1 /* $OpenBSD: alpha_cpu.h,v 1.14 2023/04/13 19:39:50 miod Exp $ */ 2 /* $NetBSD: alpha_cpu.h,v 1.43 2001/12/18 04:18:22 thorpej Exp $ */ 3 4 /* 5 * Copyright (c) 1996 Carnegie-Mellon University. 6 * All rights reserved. 7 * 8 * Author: Chris G. Demetriou 9 * 10 * Permission to use, copy, modify and distribute this software and 11 * its documentation is hereby granted, provided that both the copyright 12 * notice and this permission notice appear in all copies of the 13 * software, derivative works or modified versions, and any portions 14 * thereof, and that both notices appear in supporting documentation. 15 * 16 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 17 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 18 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 19 * 20 * Carnegie Mellon requests users of this software to return to 21 * 22 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 23 * School of Computer Science 24 * Carnegie Mellon University 25 * Pittsburgh PA 15213-3890 26 * 27 * any improvements or extensions that they make and grant Carnegie the 28 * rights to redistribute these changes. 29 */ 30 31 #ifndef _MACHINE_ALPHA_CPU_H_ 32 #define _MACHINE_ALPHA_CPU_H_ 33 34 /* 35 * Alpha CPU + OSF/1 PALcode definitions for use by the kernel. 36 * 37 * Definitions for: 38 * 39 * Process Control Block 40 * Interrupt/Exception/Syscall Stack Frame 41 * Processor Status Register 42 * Machine Check Error Summary Register 43 * Machine Check Logout Area 44 * Per CPU state Management of Machine Check Handling 45 * Virtual Memory Management 46 * Kernel Entry Vectors 47 * MMCSR Fault Type Codes 48 * Translation Buffer Invalidation 49 * 50 * and miscellaneous PALcode operations. 51 */ 52 53 54 /* 55 * Process Control Block definitions [OSF/1 PALcode Specific] 56 */ 57 58 struct alpha_pcb { 59 unsigned long apcb_ksp; /* kernel stack ptr */ 60 unsigned long apcb_usp; /* user stack ptr */ 61 unsigned long apcb_ptbr; /* page table base reg */ 62 unsigned int apcb_cpc; /* charged process cycles */ 63 unsigned int apcb_asn; /* address space number */ 64 unsigned long apcb_unique; /* process unique value */ 65 unsigned long apcb_flags; /* flags; see below */ 66 unsigned long apcb_decrsv0; /* DEC reserved */ 67 unsigned long apcb_decrsv1; /* DEC reserved */ 68 }; 69 70 #define ALPHA_PCB_FLAGS_FEN 0x0000000000000001 71 #define ALPHA_PCB_FLAGS_PME 0x4000000000000000 72 73 /* 74 * Interrupt/Exception/Syscall "Hardware" (really PALcode) 75 * Stack Frame definitions 76 * 77 * These are quadword offsets from the sp on kernel entry, i.e. 78 * to get to the value in question you access (sp + (offset * 8)). 79 * 80 * On syscall entry, A0-A2 aren't written to memory but space 81 * _is_ reserved for them. 82 */ 83 84 #define ALPHA_HWFRAME_PS 0 /* processor status register */ 85 #define ALPHA_HWFRAME_PC 1 /* program counter */ 86 #define ALPHA_HWFRAME_GP 2 /* global pointer */ 87 #define ALPHA_HWFRAME_A0 3 /* a0 */ 88 #define ALPHA_HWFRAME_A1 4 /* a1 */ 89 #define ALPHA_HWFRAME_A2 5 /* a2 */ 90 91 #define ALPHA_HWFRAME_SIZE 6 /* 6 8-byte words */ 92 93 /* 94 * Processor Status Register [OSF/1 PALcode Specific] 95 * 96 * Includes user/kernel mode bit, interrupt priority levels, etc. 97 */ 98 99 #define ALPHA_PSL_USERMODE 0x0008 /* set -> user mode */ 100 #define ALPHA_PSL_IPL_MASK 0x0007 /* interrupt level mask */ 101 102 #define ALPHA_PSL_IPL_0 0x0000 /* all interrupts enabled */ 103 #define ALPHA_PSL_IPL_SOFT 0x0001 /* software ints disabled */ 104 #define ALPHA_PSL_IPL_IO 0x0004 /* I/O dev ints disabled */ 105 #define ALPHA_PSL_IPL_CLOCK 0x0005 /* clock ints disabled */ 106 #define ALPHA_PSL_IPL_HIGH 0x0006 /* all but mchecks disabled */ 107 108 #define ALPHA_PSL_MUST_BE_ZERO 0xfffffffffffffff0UL 109 110 /* Convenience constants: what must be set/clear in user mode */ 111 #define ALPHA_PSL_USERSET ALPHA_PSL_USERMODE 112 #define ALPHA_PSL_USERCLR (ALPHA_PSL_MUST_BE_ZERO | ALPHA_PSL_IPL_MASK) 113 114 /* 115 * Interrupt Type Code Definitions [OSF/1 PALcode Specific] 116 */ 117 118 #define ALPHA_INTR_XPROC 0 /* interprocessor interrupt */ 119 #define ALPHA_INTR_CLOCK 1 /* clock interrupt */ 120 #define ALPHA_INTR_ERROR 2 /* correctable error or mcheck */ 121 #define ALPHA_INTR_DEVICE 3 /* device interrupt */ 122 #define ALPHA_INTR_PERF 4 /* performance counter */ 123 #define ALPHA_INTR_PASSIVE 5 /* passive release */ 124 125 /* 126 * Machine Check Error Summary Register definitions [OSF/1 PALcode Specific] 127 * 128 * The following bits are values as read. On write, _PCE, _SCE, and 129 * _MIP are "write 1 to clear." 130 */ 131 132 #define ALPHA_MCES_IMP \ 133 0xffffffff00000000UL /* impl. dependent */ 134 #define ALPHA_MCES_RSVD \ 135 0x00000000ffffffe0UL /* reserved */ 136 #define ALPHA_MCES_DSC \ 137 0x0000000000000010UL /* disable system correctable error reporting */ 138 #define ALPHA_MCES_DPC \ 139 0x0000000000000008UL /* disable processor correctable error reporting */ 140 #define ALPHA_MCES_PCE \ 141 0x0000000000000004UL /* processor correctable error in progress */ 142 #define ALPHA_MCES_SCE \ 143 0x0000000000000002UL /* system correctable error in progress */ 144 #define ALPHA_MCES_MIP \ 145 0x0000000000000001UL /* machine check in progress */ 146 147 /* 148 * Machine Check Error Summary Register definitions [OSF/1 PALcode Specific] 149 * 150 * Note that these are *generic* OSF/1 PALcode specific defines. There are 151 * platform variations to these entities. 152 */ 153 154 struct alpha_logout_area { 155 unsigned int la_frame_size; /* frame size */ 156 unsigned int la_flags; /* flags; see below */ 157 unsigned int la_cpu_offset; /* offset to cpu area */ 158 unsigned int la_system_offset; /* offset to system area */ 159 }; 160 161 #define ALPHA_LOGOUT_FLAGS_RETRY 0x80000000 /* OK to continue */ 162 #define ALPHA_LOGOUT_FLAGS_SE 0x40000000 /* second error */ 163 #define ALPHA_LOGOUT_FLAGS_SBZ 0x3fffffff /* should be zero */ 164 165 #define ALPHA_LOGOUT_NOT_BUILT \ 166 (struct alpha_logout_area *)0xffffffffffffffffUL) 167 168 #define ALPHA_LOGOUT_PAL_AREA(lap) \ 169 (unsigned long *)((unsigned char *)(lap) + 16) 170 #define ALPHA_LOGOUT_PAL_SIZE(lap) \ 171 ((lap)->la_cpu_offset - 16) 172 #define ALPHA_LOGOUT_CPU_AREA(lap) \ 173 (unsigned long *)((unsigned char *)(lap) + (lap)->la_cpu_offset) 174 #define ALPHA_LOGOUT_CPU_SIZE(lap) \ 175 ((lap)->la_system_offset - (lap)->la_cpu_offset) 176 #define ALPHA_LOGOUT_SYSTEM_AREA(lap) \ 177 (unsigned long *)((unsigned char *)(lap) + (lap)->la_system_offset) 178 #define ALPHA_LOGOUT_SYSTEM_SIZE(lap) \ 179 ((lap)->la_frame_size - (lap)->la_system_offset) 180 181 /* types of machine checks */ 182 #define ALPHA_SYS_ERROR 0x620 /* System correctable error */ 183 #define ALPHA_PROC_ERROR 0x630 /* Processor correctable error */ 184 #define ALPHA_SYS_MCHECK 0x660 /* System machine check */ 185 #define ALPHA_PROC_MCHECK 0x670 /* Processor machine check */ 186 #define ALPHA_ENV_MCHECK 0x680 /* Environmental machine check */ 187 188 /* 189 * Virtual Memory Management definitions [OSF/1 PALcode Specific] 190 * 191 * Includes user and kernel space addresses and information, 192 * page table entry definitions, etc. 193 */ 194 195 #define ALPHA_USEG_BASE 0 /* virtual */ 196 #define ALPHA_USEG_END 0x000003ffffffffffUL 197 198 #define ALPHA_K0SEG_BASE 0xfffffc0000000000UL /* direct-mapped */ 199 #define ALPHA_K0SEG_END 0xfffffdffffffffffUL 200 #define ALPHA_K1SEG_BASE 0xfffffe0000000000UL /* virtual */ 201 #define ALPHA_K1SEG_END 0xffffffffffffffffUL 202 203 #define ALPHA_K0SEG_TO_PHYS(x) ((x) & ~ALPHA_K0SEG_BASE) 204 #define ALPHA_PHYS_TO_K0SEG(x) ((x) | ALPHA_K0SEG_BASE) 205 206 #define ALPHA_PTE_VALID 0x0001UL 207 208 #define ALPHA_PTE_FAULT_ON_READ 0x0002UL 209 #define ALPHA_PTE_FAULT_ON_WRITE 0x0004UL 210 #define ALPHA_PTE_FAULT_ON_EXECUTE 0x0008UL 211 212 #define ALPHA_PTE_ASM 0x0010UL /* addr. space match */ 213 #define ALPHA_PTE_GRANULARITY 0x0060UL /* granularity hint */ 214 215 #define ALPHA_PTE_PROT 0xff00UL 216 #define ALPHA_PTE_KR 0x0100UL 217 #define ALPHA_PTE_UR 0x0200UL 218 #define ALPHA_PTE_KW 0x1000UL 219 #define ALPHA_PTE_UW 0x2000UL 220 221 #define ALPHA_PTE_WRITE (ALPHA_PTE_KW | ALPHA_PTE_UW) 222 223 #define ALPHA_PTE_SOFTWARE 0x00000000ffff0000UL 224 #define ALPHA_PTE_PALCODE (~ALPHA_PTE_SOFTWARE) /* shorthand */ 225 226 #define ALPHA_PTE_PFN 0xffffffff00000000UL 227 228 #define ALPHA_PTE_TO_PFN(pte) ((pte) >> 32) 229 #define ALPHA_PTE_FROM_PFN(pfn) ((pfn) << 32) 230 231 typedef unsigned long alpha_pt_entry_t; 232 233 /* 234 * Kernel Entry Vectors. [OSF/1 PALcode Specific] 235 */ 236 237 #define ALPHA_KENTRY_INT 0 238 #define ALPHA_KENTRY_ARITH 1 239 #define ALPHA_KENTRY_MM 2 240 #define ALPHA_KENTRY_IF 3 241 #define ALPHA_KENTRY_UNA 4 242 #define ALPHA_KENTRY_SYS 5 243 244 /* 245 * MMCSR Fault Type Codes. [OSF/1 PALcode Specific] 246 */ 247 248 #define ALPHA_MMCSR_INVALTRANS 0 249 #define ALPHA_MMCSR_ACCESS 1 250 #define ALPHA_MMCSR_FOR 2 251 #define ALPHA_MMCSR_FOE 3 252 #define ALPHA_MMCSR_FOW 4 253 254 /* 255 * Instruction Fault Type Codes. [OSF/1 PALcode Specific] 256 */ 257 258 #define ALPHA_IF_CODE_BPT 0 259 #define ALPHA_IF_CODE_BUGCHK 1 260 #define ALPHA_IF_CODE_GENTRAP 2 261 #define ALPHA_IF_CODE_FEN 3 262 #define ALPHA_IF_CODE_OPDEC 4 263 264 #ifdef _KERNEL 265 266 /* 267 * Translation Buffer Invalidation definitions [OSF/1 PALcode Specific] 268 */ 269 270 #define ALPHA_TBIA() alpha_pal_tbi(-2, 0) /* all TB entries */ 271 #define ALPHA_TBIAP() alpha_pal_tbi(-1, 0) /* all per-process */ 272 #define ALPHA_TBISI(va) alpha_pal_tbi(1, (va)) /* ITB entry for va */ 273 #define ALPHA_TBISD(va) alpha_pal_tbi(2, (va)) /* DTB entry for va */ 274 #define ALPHA_TBIS(va) alpha_pal_tbi(3, (va)) /* all for va */ 275 276 #endif /* _KERNEL */ 277 278 /* 279 * Bits used in the amask instruction [EV56 and later] 280 */ 281 282 #define ALPHA_AMASK_BWX 0x0001 /* byte/word extension */ 283 #define ALPHA_AMASK_FIX 0x0002 /* floating point conv. ext. */ 284 #define ALPHA_AMASK_CIX 0x0004 /* count extension */ 285 #define ALPHA_AMASK_MVI 0x0100 /* multimedia extension */ 286 #define ALPHA_AMASK_PAT 0x0200 /* precise arith. traps */ 287 288 #define ALPHA_AMASK_ALL (ALPHA_AMASK_BWX|ALPHA_AMASK_FIX| \ 289 ALPHA_AMASK_CIX|ALPHA_AMASK_MVI| \ 290 ALPHA_AMASK_PAT) 291 292 #define ALPHA_AMASK_BITS \ 293 "\20\12PAT\11MVI\3CIX\2FIX\1BWX" 294 295 /* 296 * Chip family IDs returned by implver instruction 297 */ 298 299 #define ALPHA_IMPLVER_EV4 0 /* LCA/EV4/EV45 */ 300 #define ALPHA_IMPLVER_EV5 1 /* EV5/EV56/PCA56 */ 301 #define ALPHA_IMPLVER_EV6 2 /* EV6 */ 302 303 #ifdef _KERNEL 304 305 /* 306 * Maximum processor ID we allow from `whami', and related constants. 307 * 308 * XXX This is not really processor or PALcode specific, but this is 309 * a convenient place to put these definitions. 310 * 311 * XXX This is clipped at 63 so that we can use `long's for proc bitmasks. 312 */ 313 314 #define ALPHA_WHAMI_MAXID 63 315 #define ALPHA_MAXPROCS (ALPHA_WHAMI_MAXID + 1) 316 317 /* 318 * Misc. support routines. 319 */ 320 const char *alpha_dsr_sysname(void); 321 322 /* 323 * Stubs for Alpha instructions normally inaccessible from C. 324 */ 325 unsigned long alpha_amask(unsigned long); 326 unsigned long alpha_implver(void); 327 328 #endif /* _KERNEL */ 329 330 /* XXX Expose the insn wrappers to userspace, for now. */ 331 332 static __inline unsigned long 333 alpha_rpcc(void) 334 { 335 unsigned long v0; 336 337 __asm volatile("rpcc %0" : "=r" (v0)); 338 return (v0); 339 } 340 341 #define alpha_mb() __asm volatile("mb" : : : "memory") 342 #define alpha_wmb() __asm volatile("mb" : : : "memory") /* XXX */ 343 344 #if defined(_KERNEL) || defined(_STANDALONE) 345 346 /* 347 * Stubs for OSF/1 PALcode operations. 348 */ 349 #include <machine/pal.h> 350 351 void alpha_pal_cflush(unsigned long); 352 void alpha_pal_halt(void) __attribute__((__noreturn__)); 353 unsigned long _alpha_pal_swpipl(unsigned long); /* for profiling */ 354 void alpha_pal_wrent(void *, unsigned long); 355 void alpha_pal_wrvptptr(unsigned long); 356 357 #define alpha_pal_draina() __asm volatile("call_pal %0 # PAL_draina" \ 358 : : "i" (PAL_draina) : "memory") 359 360 #define alpha_pal_imb() __asm volatile("call_pal %0 # PAL_imb" \ 361 : : "i" (PAL_imb) : "memory") 362 363 static __inline unsigned long 364 alpha_pal_rdmces(void) 365 { 366 register unsigned long v0 __asm("$0"); 367 368 __asm volatile("call_pal %1 # PAL_OSF1_rdmces" 369 : "=r" (v0) 370 : "i" (PAL_OSF1_rdmces) 371 /* clobbers t0, t8..t11 */ 372 : "$1", "$22", "$23", "$24", "$25"); 373 374 return (v0); 375 } 376 377 static __inline unsigned long 378 alpha_pal_rdps(void) 379 { 380 register unsigned long v0 __asm("$0"); 381 382 __asm volatile("call_pal %1 # PAL_OSF1_rdps" 383 : "=r" (v0) 384 : "i" (PAL_OSF1_rdps) 385 /* clobbers t0, t8..t11 */ 386 : "$1", "$22", "$23", "$24", "$25"); 387 388 return (v0); 389 } 390 391 static __inline unsigned long 392 alpha_pal_rdunique(void) 393 { 394 register unsigned long v0 __asm("$0"); 395 396 __asm volatile("call_pal %1 # PAL_rdunique" 397 : "=r" (v0) 398 : "i" (PAL_rdunique)); 399 400 return (v0); 401 } 402 403 static __inline unsigned long 404 alpha_pal_rdusp(void) 405 { 406 register unsigned long v0 __asm("$0"); 407 408 __asm volatile("call_pal %1 # PAL_OSF1_rdusp" 409 : "=r" (v0) 410 : "i" (PAL_OSF1_rdusp) 411 /* clobbers t0, t8..t11 */ 412 : "$1", "$22", "$23", "$24", "$25"); 413 414 return (v0); 415 } 416 417 static __inline unsigned long 418 alpha_pal_rdval(void) 419 { 420 register unsigned long v0 __asm("$0"); 421 422 __asm volatile("call_pal %1 # PAL_OSF1_rdval" 423 : "=r" (v0) 424 : "i" (PAL_OSF1_rdval) 425 /* clobbers t0, t8..t11 */ 426 : "$1", "$22", "$23", "$24", "$25"); 427 428 return (v0); 429 } 430 431 static __inline unsigned long 432 alpha_pal_swpctx(unsigned long ctx) 433 { 434 register unsigned long a0 __asm("$16") = ctx; 435 register unsigned long v0 __asm("$0"); 436 437 __asm volatile("call_pal %2 # PAL_OSF1_swpctx" 438 : "=r" (a0), "=r" (v0) 439 : "i" (PAL_OSF1_swpctx), "0" (a0) 440 /* clobbers t0, t8..t11, a0 (above) */ 441 : "$1", "$22", "$23", "$24", "$25", "memory"); 442 443 return (v0); 444 } 445 446 static __inline unsigned long 447 alpha_pal_swpipl(unsigned long ipl) 448 { 449 register unsigned long a0 __asm("$16") = ipl; 450 register unsigned long v0 __asm("$0"); 451 452 __asm volatile("call_pal %2 # PAL_OSF1_swpipl" 453 : "=r" (a0), "=r" (v0) 454 : "i" (PAL_OSF1_swpipl), "0" (a0) 455 /* clobbers t0, t8..t11, a0 (above) */ 456 : "$1", "$22", "$23", "$24", "$25", "memory"); 457 458 return (v0); 459 } 460 461 static __inline void 462 alpha_pal_tbi(unsigned long op, vaddr_t va) 463 { 464 register unsigned long a0 __asm("$16") = op; 465 register unsigned long a1 __asm("$17") = va; 466 467 __asm volatile("call_pal %2 # PAL_OSF1_tbi" 468 : "=r" (a0), "=r" (a1) 469 : "i" (PAL_OSF1_tbi), "0" (a0), "1" (a1) 470 /* clobbers t0, t8..t11, a0 (above), a1 (above) */ 471 : "$1", "$22", "$23", "$24", "$25"); 472 } 473 474 static __inline unsigned long 475 alpha_pal_whami(void) 476 { 477 register unsigned long v0 __asm("$0"); 478 479 __asm volatile("call_pal %1 # PAL_OSF1_whami" 480 : "=r" (v0) 481 : "i" (PAL_OSF1_whami) 482 /* clobbers t0, t8..t11 */ 483 : "$1", "$22", "$23", "$24", "$25"); 484 485 return (v0); 486 } 487 488 static __inline void 489 alpha_pal_wrfen(unsigned long onoff) 490 { 491 register unsigned long a0 __asm("$16") = onoff; 492 493 __asm volatile("call_pal %1 # PAL_OSF1_wrfen" 494 : "=r" (a0) 495 : "i" (PAL_OSF1_wrfen), "0" (a0) 496 /* clobbers t0, t8..t11, a0 (above) */ 497 : "$1", "$22", "$23", "$24", "$25"); 498 } 499 500 static __inline void 501 alpha_pal_wripir(unsigned long cpu_id) 502 { 503 register unsigned long a0 __asm("$16") = cpu_id; 504 505 __asm volatile("call_pal %1 # PAL_ipir" 506 : "=r" (a0) 507 : "i" (PAL_ipir), "0" (a0) 508 /* clobbers t0, t8..t11, a0 (above) */ 509 : "$1", "$22", "$23", "$24", "$25"); 510 } 511 512 static __inline void 513 alpha_pal_wrunique(unsigned long unique) 514 { 515 register unsigned long a0 __asm("$16") = unique; 516 517 __asm volatile("call_pal %1 # PAL_wrunique" 518 : "=r" (a0) 519 : "i" (PAL_wrunique), "0" (a0)); 520 } 521 522 static __inline void 523 alpha_pal_wrusp(unsigned long usp) 524 { 525 register unsigned long a0 __asm("$16") = usp; 526 527 __asm volatile("call_pal %1 # PAL_OSF1_wrusp" 528 : "=r" (a0) 529 : "i" (PAL_OSF1_wrusp), "0" (a0) 530 /* clobbers t0, t8..t11, a0 (above) */ 531 : "$1", "$22", "$23", "$24", "$25"); 532 } 533 534 static __inline void 535 alpha_pal_wrmces(unsigned long mces) 536 { 537 register unsigned long a0 __asm("$16") = mces; 538 539 __asm volatile("call_pal %1 # PAL_OSF1_wrmces" 540 : "=r" (a0) 541 : "i" (PAL_OSF1_wrmces), "0" (a0) 542 /* clobbers t0, t8..t11 */ 543 : "$1", "$22", "$23", "$24", "$25"); 544 } 545 546 static __inline void 547 alpha_pal_wrval(unsigned long val) 548 { 549 register unsigned long a0 __asm("$16") = val; 550 551 __asm volatile("call_pal %1 # PAL_OSF1_wrval" 552 : "=r" (a0) 553 : "i" (PAL_OSF1_wrval), "0" (a0) 554 /* clobbers t0, t8..t11, a0 (above) */ 555 : "$1", "$22", "$23", "$24", "$25"); 556 } 557 558 #endif /* _KERNEL */ 559 560 #endif /* _MACHINE_ALPHA_CPU_H_ */ 561