1 #ifndef __ALPHA_SYSTEM_H 2 #define __ALPHA_SYSTEM_H 3 4 #include <asm/pal.h> 5 #include <asm/page.h> 6 #include <asm/barrier.h> 7 8 /* 9 * System defines.. Note that this is included both from .c and .S 10 * files, so it does only defines, not any C code. 11 */ 12 13 /* 14 * We leave one page for the initial stack page, and one page for 15 * the initial process structure. Also, the console eats 3 MB for 16 * the initial bootloader (one of which we can reclaim later). 17 */ 18 #define BOOT_PCB 0x20000000 19 #define BOOT_ADDR 0x20000000 20 /* Remove when official MILO sources have ELF support: */ 21 #define BOOT_SIZE (16*1024) 22 23 #ifdef CONFIG_ALPHA_LEGACY_START_ADDRESS 24 #define KERNEL_START_PHYS 0x300000 /* Old bootloaders hardcoded this. */ 25 #else 26 #define KERNEL_START_PHYS 0x1000000 /* required: Wildfire/Titan/Marvel */ 27 #endif 28 29 #define KERNEL_START (PAGE_OFFSET+KERNEL_START_PHYS) 30 #define SWAPPER_PGD KERNEL_START 31 #define INIT_STACK (PAGE_OFFSET+KERNEL_START_PHYS+0x02000) 32 #define EMPTY_PGT (PAGE_OFFSET+KERNEL_START_PHYS+0x04000) 33 #define EMPTY_PGE (PAGE_OFFSET+KERNEL_START_PHYS+0x08000) 34 #define ZERO_PGE (PAGE_OFFSET+KERNEL_START_PHYS+0x0A000) 35 36 #define START_ADDR (PAGE_OFFSET+KERNEL_START_PHYS+0x10000) 37 38 /* 39 * This is setup by the secondary bootstrap loader. Because 40 * the zero page is zeroed out as soon as the vm system is 41 * initialized, we need to copy things out into a more permanent 42 * place. 43 */ 44 #define PARAM ZERO_PGE 45 #define COMMAND_LINE ((char*)(PARAM + 0x0000)) 46 #define INITRD_START (*(unsigned long *) (PARAM+0x100)) 47 #define INITRD_SIZE (*(unsigned long *) (PARAM+0x108)) 48 49 #ifndef __ASSEMBLY__ 50 #include <linux/kernel.h> 51 #define AT_VECTOR_SIZE_ARCH 4 /* entries in ARCH_DLINFO */ 52 53 /* 54 * This is the logout header that should be common to all platforms 55 * (assuming they are running OSF/1 PALcode, I guess). 56 */ 57 struct el_common { 58 unsigned int size; /* size in bytes of logout area */ 59 unsigned int sbz1 : 30; /* should be zero */ 60 unsigned int err2 : 1; /* second error */ 61 unsigned int retry : 1; /* retry flag */ 62 unsigned int proc_offset; /* processor-specific offset */ 63 unsigned int sys_offset; /* system-specific offset */ 64 unsigned int code; /* machine check code */ 65 unsigned int frame_rev; /* frame revision */ 66 }; 67 68 /* Machine Check Frame for uncorrectable errors (Large format) 69 * --- This is used to log uncorrectable errors such as 70 * double bit ECC errors. 71 * --- These errors are detected by both processor and systems. 72 */ 73 struct el_common_EV5_uncorrectable_mcheck { 74 unsigned long shadow[8]; /* Shadow reg. 8-14, 25 */ 75 unsigned long paltemp[24]; /* PAL TEMP REGS. */ 76 unsigned long exc_addr; /* Address of excepting instruction*/ 77 unsigned long exc_sum; /* Summary of arithmetic traps. */ 78 unsigned long exc_mask; /* Exception mask (from exc_sum). */ 79 unsigned long pal_base; /* Base address for PALcode. */ 80 unsigned long isr; /* Interrupt Status Reg. */ 81 unsigned long icsr; /* CURRENT SETUP OF EV5 IBOX */ 82 unsigned long ic_perr_stat; /* I-CACHE Reg. <11> set Data parity 83 <12> set TAG parity*/ 84 unsigned long dc_perr_stat; /* D-CACHE error Reg. Bits set to 1: 85 <2> Data error in bank 0 86 <3> Data error in bank 1 87 <4> Tag error in bank 0 88 <5> Tag error in bank 1 */ 89 unsigned long va; /* Effective VA of fault or miss. */ 90 unsigned long mm_stat; /* Holds the reason for D-stream 91 fault or D-cache parity errors */ 92 unsigned long sc_addr; /* Address that was being accessed 93 when EV5 detected Secondary cache 94 failure. */ 95 unsigned long sc_stat; /* Helps determine if the error was 96 TAG/Data parity(Secondary Cache)*/ 97 unsigned long bc_tag_addr; /* Contents of EV5 BC_TAG_ADDR */ 98 unsigned long ei_addr; /* Physical address of any transfer 99 that is logged in EV5 EI_STAT */ 100 unsigned long fill_syndrome; /* For correcting ECC errors. */ 101 unsigned long ei_stat; /* Helps identify reason of any 102 processor uncorrectable error 103 at its external interface. */ 104 unsigned long ld_lock; /* Contents of EV5 LD_LOCK register*/ 105 }; 106 107 struct el_common_EV6_mcheck { 108 unsigned int FrameSize; /* Bytes, including this field */ 109 unsigned int FrameFlags; /* <31> = Retry, <30> = Second Error */ 110 unsigned int CpuOffset; /* Offset to CPU-specific info */ 111 unsigned int SystemOffset; /* Offset to system-specific info */ 112 unsigned int MCHK_Code; 113 unsigned int MCHK_Frame_Rev; 114 unsigned long I_STAT; /* EV6 Internal Processor Registers */ 115 unsigned long DC_STAT; /* (See the 21264 Spec) */ 116 unsigned long C_ADDR; 117 unsigned long DC1_SYNDROME; 118 unsigned long DC0_SYNDROME; 119 unsigned long C_STAT; 120 unsigned long C_STS; 121 unsigned long MM_STAT; 122 unsigned long EXC_ADDR; 123 unsigned long IER_CM; 124 unsigned long ISUM; 125 unsigned long RESERVED0; 126 unsigned long PAL_BASE; 127 unsigned long I_CTL; 128 unsigned long PCTX; 129 }; 130 131 extern void halt(void) __attribute__((noreturn)); 132 #define __halt() __asm__ __volatile__ ("call_pal %0 #halt" : : "i" (PAL_halt)) 133 134 #define switch_to(P,N,L) \ 135 do { \ 136 (L) = alpha_switch_to(virt_to_phys(&task_thread_info(N)->pcb), (P)); \ 137 check_mmu_context(); \ 138 } while (0) 139 140 struct task_struct; 141 extern struct task_struct *alpha_switch_to(unsigned long, struct task_struct*); 142 143 #define imb() \ 144 __asm__ __volatile__ ("call_pal %0 #imb" : : "i" (PAL_imb) : "memory") 145 146 #define draina() \ 147 __asm__ __volatile__ ("call_pal %0 #draina" : : "i" (PAL_draina) : "memory") 148 149 enum implver_enum { 150 IMPLVER_EV4, 151 IMPLVER_EV5, 152 IMPLVER_EV6 153 }; 154 155 #ifdef CONFIG_ALPHA_GENERIC 156 #define implver() \ 157 ({ unsigned long __implver; \ 158 __asm__ ("implver %0" : "=r"(__implver)); \ 159 (enum implver_enum) __implver; }) 160 #else 161 /* Try to eliminate some dead code. */ 162 #ifdef CONFIG_ALPHA_EV4 163 #define implver() IMPLVER_EV4 164 #endif 165 #ifdef CONFIG_ALPHA_EV5 166 #define implver() IMPLVER_EV5 167 #endif 168 #if defined(CONFIG_ALPHA_EV6) 169 #define implver() IMPLVER_EV6 170 #endif 171 #endif 172 173 enum amask_enum { 174 AMASK_BWX = (1UL << 0), 175 AMASK_FIX = (1UL << 1), 176 AMASK_CIX = (1UL << 2), 177 AMASK_MAX = (1UL << 8), 178 AMASK_PRECISE_TRAP = (1UL << 9), 179 }; 180 181 #define amask(mask) \ 182 ({ unsigned long __amask, __input = (mask); \ 183 __asm__ ("amask %1,%0" : "=r"(__amask) : "rI"(__input)); \ 184 __amask; }) 185 186 #define __CALL_PAL_R0(NAME, TYPE) \ 187 extern inline TYPE NAME(void) \ 188 { \ 189 register TYPE __r0 __asm__("$0"); \ 190 __asm__ __volatile__( \ 191 "call_pal %1 # " #NAME \ 192 :"=r" (__r0) \ 193 :"i" (PAL_ ## NAME) \ 194 :"$1", "$16", "$22", "$23", "$24", "$25"); \ 195 return __r0; \ 196 } 197 198 #define __CALL_PAL_W1(NAME, TYPE0) \ 199 extern inline void NAME(TYPE0 arg0) \ 200 { \ 201 register TYPE0 __r16 __asm__("$16") = arg0; \ 202 __asm__ __volatile__( \ 203 "call_pal %1 # "#NAME \ 204 : "=r"(__r16) \ 205 : "i"(PAL_ ## NAME), "0"(__r16) \ 206 : "$1", "$22", "$23", "$24", "$25"); \ 207 } 208 209 #define __CALL_PAL_W2(NAME, TYPE0, TYPE1) \ 210 extern inline void NAME(TYPE0 arg0, TYPE1 arg1) \ 211 { \ 212 register TYPE0 __r16 __asm__("$16") = arg0; \ 213 register TYPE1 __r17 __asm__("$17") = arg1; \ 214 __asm__ __volatile__( \ 215 "call_pal %2 # "#NAME \ 216 : "=r"(__r16), "=r"(__r17) \ 217 : "i"(PAL_ ## NAME), "0"(__r16), "1"(__r17) \ 218 : "$1", "$22", "$23", "$24", "$25"); \ 219 } 220 221 #define __CALL_PAL_RW1(NAME, RTYPE, TYPE0) \ 222 extern inline RTYPE NAME(TYPE0 arg0) \ 223 { \ 224 register RTYPE __r0 __asm__("$0"); \ 225 register TYPE0 __r16 __asm__("$16") = arg0; \ 226 __asm__ __volatile__( \ 227 "call_pal %2 # "#NAME \ 228 : "=r"(__r16), "=r"(__r0) \ 229 : "i"(PAL_ ## NAME), "0"(__r16) \ 230 : "$1", "$22", "$23", "$24", "$25"); \ 231 return __r0; \ 232 } 233 234 #define __CALL_PAL_RW2(NAME, RTYPE, TYPE0, TYPE1) \ 235 extern inline RTYPE NAME(TYPE0 arg0, TYPE1 arg1) \ 236 { \ 237 register RTYPE __r0 __asm__("$0"); \ 238 register TYPE0 __r16 __asm__("$16") = arg0; \ 239 register TYPE1 __r17 __asm__("$17") = arg1; \ 240 __asm__ __volatile__( \ 241 "call_pal %3 # "#NAME \ 242 : "=r"(__r16), "=r"(__r17), "=r"(__r0) \ 243 : "i"(PAL_ ## NAME), "0"(__r16), "1"(__r17) \ 244 : "$1", "$22", "$23", "$24", "$25"); \ 245 return __r0; \ 246 } 247 248 __CALL_PAL_W1(cflush, unsigned long); 249 __CALL_PAL_R0(rdmces, unsigned long); 250 __CALL_PAL_R0(rdps, unsigned long); 251 __CALL_PAL_R0(rdusp, unsigned long); 252 __CALL_PAL_RW1(swpipl, unsigned long, unsigned long); 253 __CALL_PAL_R0(whami, unsigned long); 254 __CALL_PAL_W2(wrent, void*, unsigned long); 255 __CALL_PAL_W1(wripir, unsigned long); 256 __CALL_PAL_W1(wrkgp, unsigned long); 257 __CALL_PAL_W1(wrmces, unsigned long); 258 __CALL_PAL_RW2(wrperfmon, unsigned long, unsigned long, unsigned long); 259 __CALL_PAL_W1(wrusp, unsigned long); 260 __CALL_PAL_W1(wrvptptr, unsigned long); 261 262 /* 263 * TB routines.. 264 */ 265 #define __tbi(nr,arg,arg1...) \ 266 ({ \ 267 register unsigned long __r16 __asm__("$16") = (nr); \ 268 register unsigned long __r17 __asm__("$17"); arg; \ 269 __asm__ __volatile__( \ 270 "call_pal %3 #__tbi" \ 271 :"=r" (__r16),"=r" (__r17) \ 272 :"0" (__r16),"i" (PAL_tbi) ,##arg1 \ 273 :"$0", "$1", "$22", "$23", "$24", "$25"); \ 274 }) 275 276 #define tbi(x,y) __tbi(x,__r17=(y),"1" (__r17)) 277 #define tbisi(x) __tbi(1,__r17=(x),"1" (__r17)) 278 #define tbisd(x) __tbi(2,__r17=(x),"1" (__r17)) 279 #define tbis(x) __tbi(3,__r17=(x),"1" (__r17)) 280 #define tbiap() __tbi(-1, /* no second argument */) 281 #define tbia() __tbi(-2, /* no second argument */) 282 283 /* 284 * Atomic exchange routines. 285 */ 286 287 #define __ASM__MB 288 #define ____xchg(type, args...) __xchg ## type ## _local(args) 289 #define ____cmpxchg(type, args...) __cmpxchg ## type ## _local(args) 290 #include <asm/xchg.h> 291 292 #define xchg_local(ptr,x) \ 293 ({ \ 294 __typeof__(*(ptr)) _x_ = (x); \ 295 (__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_, \ 296 sizeof(*(ptr))); \ 297 }) 298 299 #define cmpxchg_local(ptr, o, n) \ 300 ({ \ 301 __typeof__(*(ptr)) _o_ = (o); \ 302 __typeof__(*(ptr)) _n_ = (n); \ 303 (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \ 304 (unsigned long)_n_, \ 305 sizeof(*(ptr))); \ 306 }) 307 308 #define cmpxchg64_local(ptr, o, n) \ 309 ({ \ 310 BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ 311 cmpxchg_local((ptr), (o), (n)); \ 312 }) 313 314 #ifdef CONFIG_SMP 315 #undef __ASM__MB 316 #define __ASM__MB "\tmb\n" 317 #endif 318 #undef ____xchg 319 #undef ____cmpxchg 320 #define ____xchg(type, args...) __xchg ##type(args) 321 #define ____cmpxchg(type, args...) __cmpxchg ##type(args) 322 #include <asm/xchg.h> 323 324 #define xchg(ptr,x) \ 325 ({ \ 326 __typeof__(*(ptr)) _x_ = (x); \ 327 (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, \ 328 sizeof(*(ptr))); \ 329 }) 330 331 #define cmpxchg(ptr, o, n) \ 332 ({ \ 333 __typeof__(*(ptr)) _o_ = (o); \ 334 __typeof__(*(ptr)) _n_ = (n); \ 335 (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ 336 (unsigned long)_n_, sizeof(*(ptr)));\ 337 }) 338 339 #define cmpxchg64(ptr, o, n) \ 340 ({ \ 341 BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ 342 cmpxchg((ptr), (o), (n)); \ 343 }) 344 345 #undef __ASM__MB 346 #undef ____cmpxchg 347 348 #define __HAVE_ARCH_CMPXCHG 1 349 350 #endif /* __ASSEMBLY__ */ 351 352 #define arch_align_stack(x) (x) 353 354 #endif 355