|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: #ifndef _PPC_PROC_REG_H_ ! 26: #define _PPC_PROC_REG_H_ ! 27: ! 28: #include <mach/boolean.h> ! 29: ! 30: /* Define some useful masks that convert from bit numbers */ ! 31: ! 32: #if __BIG_ENDIAN__ ! 33: #define ENDIAN_MASK(val,size) (1 << (size-1 - val)) ! 34: #else ! 35: #error code not ported to little endian targets yet ! 36: #endif /* __BIG_ENDIAN__ */ ! 37: ! 38: #define MASK32(PART) ENDIAN_MASK(PART ## _BIT, 32) ! 39: #define MASK16(PART) ENDIAN_MASK(PART ## _BIT, 16) ! 40: #define MASK8(PART) ENDIAN_MASK(PART ## _BIT, 8) ! 41: ! 42: #undef MASK ! 43: #define MASK(PART) MASK32(PART) ! 44: ! 45: #define BITS_PER_WORD 32 ! 46: #define BITS_PER_WORD_POW2 5 ! 47: ! 48: /* Determines whether it is OK to use floating point support in ! 49: kernel code. ! 50: */ ! 51: #define USE_FLOATING_POINT_IN_KERNEL 1 ! 52: ! 53: /* Defines for decoding the MSR bits */ ! 54: ! 55: #define MSR_SF_BIT 0 ! 56: #define MSR_RES1_BIT 1 ! 57: #define MSR_RES2_BIT 2 ! 58: #define MSR_RES3_BIT 3 ! 59: #define MSR_RES4_BIT 4 ! 60: #define MSR_RES5_BIT 5 ! 61: #define MSR_RES6_BIT 6 ! 62: #define MSR_RES7_BIT 7 ! 63: #define MSR_RES8_BIT 8 ! 64: #define MSR_RES9_BIT 9 ! 65: #define MSR_RES10_BIT 10 ! 66: #define MSR_RES11_BIT 11 ! 67: #define MSR_KEY_BIT 12 /* Key bit on 603e (not on 603) */ ! 68: #define MSR_POW_BIT 13 ! 69: #define MSR_TGPR_BIT 14 /* Temporary GPR mappings on 603/603e */ ! 70: #define MSR_ILE_BIT 15 ! 71: #define MSR_EE_BIT 16 ! 72: #define MSR_PR_BIT 17 ! 73: #define MSR_FP_BIT 18 ! 74: #define MSR_ME_BIT 19 ! 75: #define MSR_FE0_BIT 20 ! 76: #define MSR_SE_BIT 21 ! 77: #define MSR_BE_BIT 22 ! 78: #define MSR_FE1_BIT 23 ! 79: #define MSR_RES24_BIT 24 /* AL bit in power architectures */ ! 80: #define MSR_IP_BIT 25 ! 81: #define MSR_IR_BIT 26 ! 82: #define MSR_DR_BIT 27 ! 83: #define MSR_RES28_BIT 28 ! 84: #define MSR_RES29_BIT 29 ! 85: #define MSR_RI_BIT 30 ! 86: #define MSR_LE_BIT 31 ! 87: ! 88: /* MSR for kernel mode, interrupts disabled, running in virtual mode */ ! 89: #define MSR_SUPERVISOR_INT_OFF (MASK(MSR_ME) | MASK(MSR_IR) | MASK(MSR_DR)) ! 90: ! 91: /* MSR for above but with interrupts enabled */ ! 92: #define MSR_SUPERVISOR_INT_ON (MSR_SUPERVISOR_INT_OFF | MASK(MSR_EE)) ! 93: ! 94: /* MSR for physical mode code */ ! 95: #define MSR_VM_OFF (MASK(MSR_ME)) ! 96: ! 97: /* MSR mask for user-exported bits - identify bits that must be set/reset */ ! 98: ! 99: /* SET - external exceptions, machine check, vm on, user-level privs */ ! 100: #define MSR_EXPORT_MASK_SET (MASK(MSR_EE)| MASK(MSR_ME)| \ ! 101: MASK(MSR_IR)|MASK(MSR_DR)|MASK(MSR_PR)) ! 102: ! 103: /* only the following bits may be changed by a task */ ! 104: #define MSR_IMPORT_BITS (MASK(MSR_FE0)|MASK(MSR_SE)|MASK(MSR_BE)| \ ! 105: MASK(MSR_FE1)|MASK(MSR_LE)) ! 106: ! 107: #define MSR_PREPARE_FOR_IMPORT(origmsr, newmsr) \ ! 108: ((origmsr & ~MSR_IMPORT_BITS) | (newmsr & MSR_IMPORT_BITS)) ! 109: ! 110: #define USER_MODE(msr) (msr & MASK(MSR_PR) ? TRUE : FALSE) ! 111: ! 112: /* SYSCALL structures are marked by setting a reserved bit in the MSR, ! 113: * this bit should never leak into executing code, it'll be masked off ! 114: * beforehand. We don't use bit 0, since it leads to sign problems. ! 115: */ ! 116: ! 117: #define MSR_SYSCALL_MASK MASK(MSR_RES1) ! 118: #define MSR_MARK_SYSCALL(msr) (msr | (MSR_SYSCALL_MASK)) ! 119: #define MSR_WAS_SYSCALL(msr) (msr & MSR_SYSCALL_MASK) ! 120: #define MSR_REMOVE_SYSCALL_MARK(msr) (msr & ~(MSR_SYSCALL_MASK)) ! 121: ! 122: /* seg reg values must be simple expressions so that assembler can cope */ ! 123: #define SEG_REG_INVALID 0x0000 ! 124: #define KERNEL_SEG_REG0_VALUE 0x20000000 /* T=0,Ks=0,Ku=1 PPC_SID_KERNEL=0*/ ! 125: #define KERNEL_SEG_REG1_VALUE 0x20000001 /* T=0,Ks=0,Ku=1 PPC_SID_KERNEL=0*/ ! 126: ! 127: /* the following segment register values are only used prior to the probe, ! 128: * they map the various device areas 1-1 on 601 machines ! 129: */ ! 130: #define KERNEL_SEG_REG5_VALUE 0xa7F00005 /* T=1,Ks=0,Ku=1,BUID=0x7F,SR=5 */ ! 131: #define KERNEL_SEG_REG8_VALUE 0xa7F00008 /* T=1,Ks=0,Ku=1,BUID=0x7F,SR=8 */ ! 132: #define KERNEL_SEG_REG9_VALUE 0xa7F00009 /* T=1,Ks=0,Ku=1,BUID=0x7F,SR=9 */ ! 133: #define KERNEL_SEG_REG10_VALUE 0xa7F0000a /* T=1,Ks=0,Ku=1,BUID=0x7F,SR=a */ ! 134: #define KERNEL_SEG_REG11_VALUE 0xa7F0000b /* T=1,Ks=0,Ku=1,BUID=0x7F,SR=b */ ! 135: #define KERNEL_SEG_REG12_VALUE 0xa7F0000c /* T=1,Ks=0,Ku=1,BUID=0x7F,SR=c */ ! 136: #define KERNEL_SEG_REG13_VALUE 0xa7F0000d /* T=1,Ks=0,Ku=1,BUID=0x7F,SR=d */ ! 137: #define KERNEL_SEG_REG14_VALUE 0xa7F0000e /* T=1,Ks=0,Ku=1,BUID=0x7F,SR=e */ ! 138: #define KERNEL_SEG_REG15_VALUE 0xa7F0000f /* T=1,Ks=0,Ku=1,BUID=0x7F,SR=f */ ! 139: ! 140: /* For SEG_REG_PROT we have T=0, Ks=0, Ku=1 */ ! 141: #define SEG_REG_PROT 0x20000000 /* seg regs should have these bits set */ ! 142: ! 143: /* This segment register is used for copyin/copyout+remapping and must be ! 144: * saved and restored in the thread context. ! 145: */ ! 146: ! 147: #define SR_COPYIN 14 ! 148: #define SR_COPYIN_NAME sr14 ! 149: ! 150: /* Don't do it this way.... so pex can be happy */ ! 151: //#define SR_COPYIN 12 ! 152: //#define SR_COPYIN_NAME sr12 ! 153: ! 154: /* This segment register is unused by the kernel, and thus contains ! 155: * the space ID of the currently interrupted user task immediately ! 156: * after an exception and before interrupts are reenabled. It's used ! 157: * purely for an assert. ! 158: */ ! 159: #define SR_UNUSED_BY_KERN 13 ! 160: ! 161: /* used for asserts... */ ! 162: #define SR_KERNEL 0 ! 163: ! 164: /* DSISR bits on data access exceptions */ ! 165: ! 166: #define DSISR_IO_BIT 0 /* NOT USED on 601 */ ! 167: #define DSISR_HASH_BIT 1 ! 168: #define DSISR_PROT_BIT 4 ! 169: #define DSISR_IO_SPC_BIT 5 ! 170: #define DSISR_WRITE_BIT 6 ! 171: #define DSISR_WATCH_BIT 9 ! 172: #define DSISR_EIO_BIT 11 ! 173: ! 174: /* SRR1 bits on data/instruction translation exceptions */ ! 175: ! 176: #define SRR1_TRANS_HASH_BIT 1 ! 177: #define SRR1_TRANS_IO_BIT 3 ! 178: #define SRR1_TRANS_PROT_BIT 4 ! 179: #define SRR1_TRANS_NO_PTE_BIT 10 ! 180: ! 181: /* SRR1 bits on program exceptions */ ! 182: ! 183: #define SRR1_PRG_FE_BIT 11 ! 184: #define SRR1_PRG_ILL_INS_BIT 12 ! 185: #define SRR1_PRG_PRV_INS_BIT 13 ! 186: #define SRR1_PRG_TRAP_BIT 14 ! 187: ! 188: /* BAT information */ ! 189: ! 190: /* Constants used when setting mask values */ ! 191: ! 192: #define BAT_INVALID 0 ! 193: ! 194: /* ! 195: * Virtual to physical mapping macros/structures. ! 196: * IMPORTANT NOTE: there is one mapping per HW page, not per MACH page. ! 197: */ ! 198: ! 199: #define CACHE_LINE_SIZE 32 ! 200: #define CACHE_LINE_POW2 5 ! 201: #define cache_align(x) (((x) + CACHE_LINE_SIZE-1) & ~(CACHE_LINE_SIZE - 1)) ! 202: ! 203: #define PTE1_WIMG_GUARD_BIT 28 /* Needed for assembler */ ! 204: #define PTE1_REFERENCED_BIT 23 /* ditto */ ! 205: #define PTE1_CHANGED_BIT 24 ! 206: #define PTE0_HASH_ID_BIT 25 ! 207: ! 208: #define PPC_HASHSIZE 2048 /* size of hash table */ ! 209: #define PPC_HASHSIZE_LOG2 11 ! 210: #define PPC_MIN_MPP 2 /* min # of mappings per phys page */ ! 211: ! 212: #ifndef __ASSEMBLER__ ! 213: #ifdef __GNUC__ ! 214: ! 215: #if !defined(__BIG_ENDIAN__) ! 216: #error - bitfield structures are not checked for bit ordering in words ! 217: #endif /* !__BIG_ENDIAN__ */ ! 218: ! 219: /* Structures and types for machine registers */ ! 220: ! 221: typedef union { ! 222: unsigned int word; ! 223: struct { ! 224: unsigned int htaborg : 16; ! 225: unsigned int reserved : 7; ! 226: unsigned int htabmask : 9; ! 227: } bits; ! 228: } sdr1_t; ! 229: ! 230: /* BAT register structures. ! 231: * Not used for standard mappings, but may be used ! 232: * for mapping devices. Note that the 601 has a ! 233: * different BAT layout than the other PowerPC processors ! 234: */ ! 235: ! 236: typedef union { ! 237: unsigned int word; ! 238: struct { ! 239: unsigned int blpi : 15; ! 240: unsigned int reserved : 10; ! 241: unsigned int wim : 3; ! 242: unsigned int ks : 1; ! 243: unsigned int ku : 1; ! 244: unsigned int pp : 2; ! 245: } bits; ! 246: } bat601u_t; ! 247: ! 248: typedef union { ! 249: unsigned int word; ! 250: struct { ! 251: unsigned int pbn : 15; ! 252: unsigned int reserved : 10; ! 253: unsigned int valid : 1; ! 254: unsigned int bsm : 6; ! 255: } bits; ! 256: } bat601l_t; ! 257: ! 258: typedef struct bat601_t { ! 259: bat601u_t upper; ! 260: bat601l_t lower; ! 261: } bat601_t; ! 262: ! 263: typedef union { ! 264: unsigned int word; ! 265: struct { ! 266: unsigned int bepi : 15; ! 267: unsigned int reserved : 4; ! 268: unsigned int bl : 11; ! 269: unsigned int vs : 1; ! 270: unsigned int vp : 1; ! 271: } bits; ! 272: } batu_t; ! 273: ! 274: typedef union { ! 275: unsigned int word; ! 276: struct { ! 277: unsigned int brpn : 15; ! 278: unsigned int reserved : 10; ! 279: unsigned int wimg : 4; ! 280: unsigned int reserved2 : 1; ! 281: unsigned int pp : 2; ! 282: } bits; ! 283: } batl_t; ! 284: ! 285: typedef struct bat_t { ! 286: batu_t upper; ! 287: batl_t lower; ! 288: } bat_t; ! 289: ! 290: /* PTE entries ! 291: * Used extensively for standard mappings ! 292: */ ! 293: ! 294: typedef union { ! 295: unsigned int word; ! 296: struct { ! 297: unsigned int valid : 1; ! 298: unsigned int segment_id : 24; ! 299: unsigned int hash_id : 1; ! 300: unsigned int page_index : 6; /* Abbreviated */ ! 301: } bits; ! 302: struct { ! 303: unsigned int valid : 1; ! 304: unsigned int not_used : 5; ! 305: unsigned int segment_id : 19; /* Least Sig 19 bits */ ! 306: unsigned int hash_id : 1; ! 307: unsigned int page_index : 6; ! 308: } hash_bits; ! 309: } pte0_t; ! 310: ! 311: typedef union { ! 312: unsigned int word; ! 313: struct { ! 314: unsigned int phys_page : 20; ! 315: unsigned int reserved3 : 3; ! 316: unsigned int referenced : 1; ! 317: unsigned int changed : 1; ! 318: unsigned int wimg : 4; ! 319: unsigned int reserved1 : 1; ! 320: unsigned int protection : 2; ! 321: } bits; ! 322: } pte1_t; ! 323: ! 324: typedef struct pte_t { ! 325: pte0_t pte0; ! 326: pte1_t pte1; ! 327: } pte_t; ! 328: ! 329: #define PTE_NULL ((pte_t*) NULL) /* No pte found/associated with this */ ! 330: #define PTE_EMPTY 0x7fffffbf /* Value in the pte0.word of a free pte */ ! 331: ! 332: #define PTE_WIMG_CB_CACHED 0 /* cached, writeback */ ! 333: #define PTE_WIMG_CB_CACHED_GUARDED 1 /* cached, writeback, guarded */ ! 334: #define PTE_WIMG_CB_CACHED_COHERENT 2 /* cached, writeback, coherent (default) */ ! 335: #define PTE_WIMG_CB_CACHED_COHERENT_GUARDED 3 /* cached, writeback, coherent, guarded */ ! 336: #define PTE_WIMG_UNCACHED 4 /* uncached */ ! 337: #define PTE_WIMG_UNCACHED_GUARDED 5 /* uncached, guarded */ ! 338: #define PTE_WIMG_UNCACHED_COHERENT 6 /* uncached, coherentt */ ! 339: #define PTE_WIMG_UNCACHED_COHERENT_GUARDED 7 /* uncached, coherent, guarded */ ! 340: #define PTE_WIMG_WT_CACHED 8 /* cached, writethru */ ! 341: #define PTE_WIMG_WT_CACHED_GUARDED 9 /* cached, writethru, guarded */ ! 342: #define PTE_WIMG_WT_CACHED_COHERENT 10 /* cached, writethru, coherent */ ! 343: #define PTE_WIMG_WT_CACHED_COHERENT_GUARDED 11 /* cached, writethru, coherent, guarded */ ! 344: ! 345: #define PTE_WIMG_DEFAULT PTE_WIMG_CB_CACHED_COHERENT ! 346: #define PTE_WIMG_IO PTE_WIMG_UNCACHED_COHERENT_GUARDED ! 347: ! 348: /* ! 349: * A virtual address is decoded into various parts when looking for its PTE ! 350: */ ! 351: ! 352: typedef struct va_full_t { ! 353: unsigned int seg_num : 4; ! 354: unsigned int page_index : 16; ! 355: unsigned int byte_ofs : 12; ! 356: } va_full_t; ! 357: ! 358: typedef struct va_abbrev_t { /* use bits.abbrev for abbreviated page index */ ! 359: unsigned int seg_num : 4; ! 360: unsigned int page_index : 6; ! 361: unsigned int junk : 10; ! 362: unsigned int byte_ofs : 12; ! 363: } va_abbrev_t; ! 364: ! 365: typedef union { ! 366: unsigned int word; ! 367: va_full_t full; ! 368: va_abbrev_t abbrev; ! 369: } virtual_addr_t; ! 370: ! 371: /* A physical address can be split up into page and offset */ ! 372: ! 373: typedef struct pa_t { ! 374: unsigned int page_no : 20; ! 375: unsigned int offset : 12; ! 376: } pa_t; ! 377: ! 378: typedef union { ! 379: unsigned int word; ! 380: pa_t bits; ! 381: } physical_addr_t; ! 382: ! 383: ! 384: extern long long read_processor_clock(void); ! 385: ! 386: /* ! 387: * C-helper inline functions for accessing machine registers follow. ! 388: */ ! 389: ! 390: ! 391: /* Return the current GOT pointer */ ! 392: ! 393: extern unsigned int get_got(void); ! 394: ! 395: extern __inline__ unsigned int get_got(void) ! 396: { ! 397: unsigned int result; ! 398: __asm__ volatile("mr %0, r2" : "=r" (result)); ! 399: return result; ! 400: } ! 401: ! 402: /* ! 403: * Various memory/IO synchronisation instructions ! 404: */ ! 405: ! 406: /* Use eieio as a memmory barrier to order stores. ! 407: Useful for device control and PTE maintenance. ! 408: */ ! 409: ! 410: #define eieio() \ ! 411: __asm__ volatile("eieio") ! 412: ! 413: /* Use sync to ensure previous stores have completed. ! 414: This is required when manipulating locks and/or ! 415: maintaining PTEs or other shared structures on SMP ! 416: machines. ! 417: */ ! 418: ! 419: #define sync() \ ! 420: __asm__ volatile("sync") ! 421: ! 422: /* Use isync to sychronize context; that is, the ensure ! 423: no prefetching of instructions happen before the ! 424: instruction. ! 425: */ ! 426: ! 427: #define isync() \ ! 428: __asm__ volatile("isync") ! 429: ! 430: ! 431: /* Invalidate TLB entry. Caution, requires context synchronization. ! 432: */ ! 433: extern void tlbsync(); ! 434: ! 435: extern __inline__ void tlbsync() ! 436: { ! 437: __asm__ volatile("tlbsync"); ! 438: return; ! 439: } ! 440: ! 441: ! 442: extern void tlbie(unsigned int val); ! 443: ! 444: extern __inline__ void tlbie(unsigned int val) ! 445: { ! 446: __asm__ volatile("tlbie %0" : : "r" (val)); ! 447: return; ! 448: } ! 449: ! 450: ! 451: ! 452: /* ! 453: * Access to various system registers ! 454: */ ! 455: ! 456: extern unsigned int mflr(void); ! 457: ! 458: extern __inline__ unsigned int mflr(void) ! 459: { ! 460: unsigned int result; ! 461: __asm__ volatile("mflr %0" : "=r" (result)); ! 462: return result; ! 463: } ! 464: ! 465: extern unsigned int mfpvr(void); ! 466: ! 467: extern __inline__ unsigned int mfpvr(void) ! 468: { ! 469: unsigned int result; ! 470: __asm__ ("mfpvr %0" : "=r" (result)); ! 471: return result; ! 472: } ! 473: ! 474: /* macros to help decide processor type */ ! 475: #define PROCESSOR_VERSION (mfpvr() >> 16) ! 476: #define PROCESSOR_VERSION_601 1 ! 477: #define PROCESSOR_VERSION_603 3 ! 478: #define PROCESSOR_VERSION_604 4 ! 479: #define PROCESSOR_VERSION_602 5 ! 480: #define PROCESSOR_VERSION_603e 6 ! 481: #define PROCESSOR_VERSION_603ev 7 ! 482: #define PROCESSOR_VERSION_750 8 ! 483: #define PROCESSOR_VERSION_604e 9 ! 484: #define PROCESSOR_VERSION_604ev 10 /* MachV */ ! 485: ! 486: extern void mtmsr(unsigned int val); ! 487: ! 488: extern __inline__ void mtmsr(unsigned int val) ! 489: { ! 490: __asm__ volatile("mtmsr %0" : : "r" (val)); ! 491: __asm__ volatile("isync"); ! 492: return; ! 493: } ! 494: ! 495: extern unsigned int mfmsr(void); ! 496: ! 497: extern __inline__ unsigned int mfmsr(void) ! 498: { ! 499: unsigned int result; ! 500: __asm__ volatile("mfmsr %0" : "=r" (result)); ! 501: return result; ! 502: } ! 503: ! 504: /* mtsr and mfsr must be macros since SR must be hardcoded */ ! 505: ! 506: #define mtsr(SR, REG) \ ! 507: __asm__ volatile("mtsr sr%0, %1" : : "i" (SR), "r" (REG)); ! 508: ! 509: #define mfsr(REG, SR) \ ! 510: __asm__ volatile("mfsr %0, sr%1" : "=r" (REG) : "i" (SR)); ! 511: ! 512: extern void mtsrin(unsigned int val, unsigned int reg); ! 513: ! 514: extern __inline__ void mtsrin(unsigned int val, unsigned int reg) ! 515: { ! 516: __asm__ volatile("mtsrin %0, %1" : : "r" (val), "r" (reg)); ! 517: return; ! 518: } ! 519: ! 520: extern unsigned int mfsrin(unsigned int reg); ! 521: ! 522: extern __inline__ unsigned int mfsrin(unsigned int reg) ! 523: { ! 524: unsigned int result; ! 525: __asm__ volatile("mfsrin %0, %1" : "=r" (result) : "r" (reg)); ! 526: return result; ! 527: } ! 528: ! 529: extern void mtsdr1(unsigned int val); ! 530: ! 531: extern __inline__ void mtsdr1(unsigned int val) ! 532: { ! 533: __asm__ volatile("mtsdr1 %0" : : "r" (val)); ! 534: return; ! 535: } ! 536: ! 537: extern void mtdar(unsigned int val); ! 538: ! 539: extern __inline__ void mtdar(unsigned int val) ! 540: { ! 541: __asm__ volatile("mtdar %0" : : "r" (val)); ! 542: return; ! 543: } ! 544: ! 545: extern unsigned int mfdar(void); ! 546: ! 547: extern __inline__ unsigned int mfdar(void) ! 548: { ! 549: unsigned int result; ! 550: __asm__ volatile("mfdar %0" : "=r" (result)); ! 551: return result; ! 552: } ! 553: ! 554: extern void mtdec(unsigned int val); ! 555: ! 556: extern __inline__ void mtdec(unsigned int val) ! 557: { ! 558: __asm__ volatile("mtdec %0" : : "r" (val)); ! 559: return; ! 560: } ! 561: ! 562: extern unsigned int mfdec(void); ! 563: ! 564: extern __inline__ unsigned int mfdec(void) ! 565: { ! 566: unsigned int result; ! 567: __asm__ volatile("mfdec %0" : "=r" (result)); ! 568: return result; ! 569: } ! 570: ! 571: /* Read and write the value from the real-time clock ! 572: * or time base registers. Note that you have to ! 573: * use the right ones depending upon being on ! 574: * 601 or 603/604. Care about carries between ! 575: * the words and using the right registers must be ! 576: * done by the calling function. ! 577: */ ! 578: ! 579: extern void mttb(unsigned int val); ! 580: ! 581: extern __inline__ void mttb(unsigned int val) ! 582: { ! 583: __asm__ volatile("mttb %0" : : "r" (val)); ! 584: return; ! 585: } ! 586: ! 587: extern unsigned int mftb(void); ! 588: ! 589: extern __inline__ unsigned int mftb(void) ! 590: { ! 591: unsigned int result; ! 592: __asm__ volatile("mftb %0" : "=r" (result)); ! 593: return result; ! 594: } ! 595: ! 596: extern void mttbu(unsigned int val); ! 597: ! 598: extern __inline__ void mttbu(unsigned int val) ! 599: { ! 600: __asm__ volatile("mttbu %0" : : "r" (val)); ! 601: return; ! 602: } ! 603: ! 604: extern unsigned int mftbu(void); ! 605: ! 606: extern __inline__ unsigned int mftbu(void) ! 607: { ! 608: unsigned int result; ! 609: __asm__ volatile("mftbu %0" : "=r" (result)); ! 610: return result; ! 611: } ! 612: ! 613: extern void mtrtcl(unsigned int val); ! 614: ! 615: extern __inline__ void mtrtcl(unsigned int val) ! 616: { ! 617: __asm__ volatile("mtspr 21,%0" : : "r" (val)); ! 618: return; ! 619: } ! 620: ! 621: extern unsigned int mfrtcl(void); ! 622: ! 623: extern __inline__ unsigned int mfrtcl(void) ! 624: { ! 625: unsigned int result; ! 626: __asm__ volatile("mfspr %0,5" : "=r" (result)); ! 627: return result; ! 628: } ! 629: ! 630: extern void mtrtcu(unsigned int val); ! 631: ! 632: extern __inline__ void mtrtcu(unsigned int val) ! 633: { ! 634: __asm__ volatile("mtspr 20,%0" : : "r" (val)); ! 635: return; ! 636: } ! 637: ! 638: extern unsigned int mfrtcu(void); ! 639: ! 640: extern __inline__ unsigned int mfrtcu(void) ! 641: { ! 642: unsigned int result; ! 643: __asm__ volatile("mfspr %0,4" : "=r" (result)); ! 644: return result; ! 645: } ! 646: ! 647: extern void mtl2cr(unsigned int val); ! 648: ! 649: extern __inline__ void mtl2cr(unsigned int val) ! 650: { ! 651: __asm__ volatile("mtspr 1017,%0" : : "r" (val)); ! 652: return; ! 653: } ! 654: ! 655: extern unsigned int mfl2cr(void); ! 656: ! 657: extern __inline__ unsigned int mfl2cr(void) ! 658: { ! 659: unsigned int result; ! 660: __asm__ volatile("mfspr %0,1017" : "=r" (result)); ! 661: return result; ! 662: } ! 663: ! 664: extern unsigned int cntlzw(unsigned int num); ! 665: ! 666: extern __inline__ unsigned int cntlzw(unsigned int num) ! 667: { ! 668: unsigned int result; ! 669: __asm__ volatile("cntlzw %0, %1" : "=r" (result) : "r" (num)); ! 670: return result; ! 671: } ! 672: ! 673: ! 674: extern void dcbf(unsigned int addr); ! 675: ! 676: extern __inline__ void dcbf(unsigned int addr) ! 677: { ! 678: __asm__ volatile("dcbf 0, %0" : : "r" (addr)); ! 679: return; ! 680: } ! 681: ! 682: ! 683: /* functions for doing byte reversed loads and stores */ ! 684: ! 685: extern unsigned int lwbrx(unsigned int addr); ! 686: ! 687: extern __inline__ unsigned int lwbrx(unsigned int addr) ! 688: { ! 689: unsigned int result; ! 690: __asm__ volatile("lwbrx %0, 0, %1" : "=r" (result) : "r" (addr)); ! 691: return result; ! 692: } ! 693: ! 694: extern void stwbrx(unsigned int data, unsigned int addr); ! 695: ! 696: extern __inline__ void stwbrx(unsigned int data, unsigned int addr) ! 697: { ! 698: __asm__ volatile("stwbrx %0, 0, %1" : : "r" (data), "r" (addr)); ! 699: } ! 700: ! 701: /* macros since the argument n is a hard-coded constant */ ! 702: ! 703: #define mtibatu(n, reg) __asm__ volatile("mtibatu " # n ", %0" : : "r" (reg)) ! 704: #define mtibatl(n, reg) __asm__ volatile("mtibatl " # n ", %0" : : "r" (reg)) ! 705: ! 706: #define mtdbatu(n, reg) __asm__ volatile("mtdbatu " # n ", %0" : : "r" (reg)) ! 707: #define mtdbatl(n, reg) __asm__ volatile("mtdbatl " # n ", %0" : : "r" (reg)) ! 708: ! 709: #define mfibatu(reg, n) __asm__ volatile("mfibatu %0, " # n : "=r" (reg)) ! 710: #define mfibatl(reg, n) __asm__ volatile("mfibatl %0, " # n : "=r" (reg)) ! 711: ! 712: #define mfdbatu(reg, n) __asm__ volatile("mfdbatu %0, " # n : "=r" (reg)) ! 713: #define mfdbatl(reg, n) __asm__ volatile("mfdbatl %0, " # n : "=r" (reg)) ! 714: ! 715: #define mtsprg(n, reg) __asm__ volatile("mtsprg " # n ", %0" : : "r" (reg)) ! 716: #define mfsprg(reg, n) __asm__ volatile("mfsprg %0, " # n : "=r" (reg)) ! 717: ! 718: #define mtspr(spr, val) __asm__ volatile("mtspr " # spr ", %0" : : "r" (val)) ! 719: #define mfspr(reg, spr) __asm__ volatile("mfspr %0, " # spr : "=r" (reg)) ! 720: ! 721: #endif /* __GNUC__ */ ! 722: #endif /* !__ASSEMBLER__ */ ! 723: ! 724: #endif /* _PPC_PROC_REG_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.