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