|
|
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: /* Copyright (c) 1996 NeXT Software, Inc. All rights reserved. ! 23: * ! 24: * File: architecture/ppc/basic_regs.h ! 25: * Author: Doug Mitchell, NeXT Software, Inc. ! 26: * ! 27: * Basic ppc registers. ! 28: * ! 29: * HISTORY ! 30: * 22-May-97 Umesh Vaishampayan ([email protected]) ! 31: Updated to match MPCFPE32B/AD 1/97 REV. 1 ! 32: * 29-Dec-96 Umesh Vaishampayan ([email protected]) ! 33: * Ported from m98k. ! 34: * 05-Nov-92 Doug Mitchell at NeXT ! 35: * Created. ! 36: */ ! 37: ! 38: #ifndef _ARCH_PPC_BASIC_REGS_H_ ! 39: #define _ARCH_PPC_BASIC_REGS_H_ ! 40: ! 41: #import <architecture/ppc/reg_help.h> ! 42: #import <architecture/ppc/macro_help.h> ! 43: ! 44: #if !defined(__ASSEMBLER__) ! 45: ! 46: /* ! 47: * Number of General Purpose registers. ! 48: */ ! 49: #define PPC_NGP_REGS 32 ! 50: ! 51: /* ! 52: * Common half-word used in Machine State Register and in ! 53: * various exception frames. Defined as a macro because the compiler ! 54: * will align a struct to a word boundary when used inside another struct. ! 55: */ ! 56: #define MSR_BITS \ ! 57: unsigned ee:BIT_WIDTH(15), /* external intr enable */ \ ! 58: pr:BIT_WIDTH(14), /* problem state */ \ ! 59: fp:BIT_WIDTH(13), /* floating point avail */ \ ! 60: me:BIT_WIDTH(12), /* machine check enable */ \ ! 61: fe0:BIT_WIDTH(11), /* fp exception mode 0 */ \ ! 62: se:BIT_WIDTH(10), /* single step enable */ \ ! 63: be:BIT_WIDTH(9), /* branch trace enable */ \ ! 64: fe1:BIT_WIDTH(8), /* fp exception mode 0 */ \ ! 65: rsvd1:BIT_WIDTH(7), /* reserved */ \ ! 66: ip:BIT_WIDTH(6), /* interrupt prefix */ \ ! 67: ir:BIT_WIDTH(5), /* instruction relocate */ \ ! 68: dr:BIT_WIDTH(4), /* data relocate */ \ ! 69: rsvd2:BITS_WIDTH(3,2), /* reserved */ \ ! 70: ri:BIT_WIDTH(1), /* recoverable exception */ \ ! 71: le:BIT_WIDTH(0) /* Little-endian mode */ ! 72: ! 73: /* ! 74: * Machine state register. ! 75: * Read and written via get_msr() and set_msr() inlines, below. ! 76: */ ! 77: typedef struct { ! 78: unsigned rsvd3:BITS_WIDTH(31,19), // reserved ! 79: pow:BIT_WIDTH(18), // Power management enable ! 80: rsvd0: BIT_WIDTH(17), // reserved ! 81: ile: BIT_WIDTH(16); // exception little endian ! 82: ! 83: MSR_BITS; // see above ! 84: } msr_t; ! 85: ! 86: /* ! 87: * Data Storage Interrupt Status Register (DSISR) ! 88: */ ! 89: typedef struct { ! 90: unsigned dse:BIT_WIDTH(31); // direct-store error ! 91: unsigned tnf:BIT_WIDTH(30); // translation not found ! 92: unsigned :BITS_WIDTH(29,28); ! 93: unsigned pe:BIT_WIDTH(27); // protection error ! 94: unsigned dsr:BIT_WIDTH(26); // lwarx/stwcx to direct-store ! 95: unsigned rw:BIT_WIDTH(25); // 1 => store, 0 => load ! 96: unsigned :BITS_WIDTH(24,23); ! 97: unsigned dab:BIT_WIDTH(22); // data address bkpt (601) ! 98: unsigned ssf:BIT_WIDTH(21); // seg table search failed ! 99: unsigned :BITS_WIDTH(20,0); ! 100: } dsisr_t; ! 101: ! 102: /* ! 103: * Instruction Storage Interrupt Status Register (really SRR1) ! 104: */ ! 105: typedef struct { ! 106: unsigned :BIT_WIDTH(31); ! 107: unsigned tnf:BIT_WIDTH(30); // translation not found ! 108: unsigned :BIT_WIDTH(29); ! 109: unsigned dse:BIT_WIDTH(28); // direct-store fetch error ! 110: unsigned pe:BIT_WIDTH(27); // protection error ! 111: unsigned :BITS_WIDTH(26,22); ! 112: unsigned ssf:BIT_WIDTH(21); // seg table search failed ! 113: unsigned :BITS_WIDTH(20,16); ! 114: MSR_BITS; ! 115: } isisr_t; ! 116: ! 117: /* ! 118: * Alignment Interrupt Status Register (really DSISR) ! 119: * NOTE: bit numbers in field *names* are in IBM'ese (0 is MSB). ! 120: * FIXME: Yuck!!! Double Yuck!!! ! 121: */ ! 122: typedef struct { ! 123: unsigned :BITS_WIDTH(31,20); ! 124: unsigned ds3031:BITS_WIDTH(19,18);// bits 30:31 if DS form ! 125: unsigned :BIT_WIDTH(17); ! 126: unsigned x2930:BITS_WIDTH(16,15); // bits 29:30 if X form ! 127: unsigned x25:BIT_WIDTH(14); // bit 25 if X form or ! 128: // bit 5 if D or DS form ! 129: unsigned x2124:BITS_WIDTH(13,10); // bits 21:24 if X form or ! 130: // bits 1:4 if D or DS form ! 131: unsigned all615:BITS_WIDTH(9,0); // bits 6:15 of instr ! 132: MSR_BITS; ! 133: } aisr_t; ! 134: ! 135: /* ! 136: * Program Interrupt Status Register (really SRR1) ! 137: */ ! 138: typedef struct { ! 139: unsigned :BITS_WIDTH(31,21); ! 140: unsigned fpee:BIT_WIDTH(20); // floating pt enable exception ! 141: unsigned ill:BIT_WIDTH(19); // illegal instruction ! 142: unsigned priv:BIT_WIDTH(18); // privileged instruction ! 143: unsigned trap:BIT_WIDTH(17); // trap program interrupt ! 144: unsigned subseq:BIT_WIDTH(16); // 1 => SRR0 points to ! 145: // subsequent instruction ! 146: MSR_BITS; ! 147: } pisr_t; ! 148: ! 149: /* ! 150: * Condition register. May not be useful in C, let's see... ! 151: */ ! 152: typedef struct { ! 153: unsigned lt:BIT_WIDTH(31), // negative ! 154: gt:BIT_WIDTH(30), // positive ! 155: eq:BIT_WIDTH(29), // equal to zero ! 156: so:BIT_WIDTH(28), // summary overflow ! 157: fx:BIT_WIDTH(27), // floating point exception ! 158: fex:BIT_WIDTH(26), // fp enabled exception ! 159: vx:BIT_WIDTH(25), // fp invalid operation ! 160: // exception ! 161: ox:BIT_WIDTH(24), // fp overflow exception ! 162: rsvd:BITS_WIDTH(23,0); // reserved ! 163: } cr_t; ! 164: ! 165: /* ! 166: * Abstract values representing fe0:fe1. ! 167: * See get_fp_exc_mode(), below. ! 168: */ ! 169: typedef enum { ! 170: FEM_IGNORE_EXCEP, // ignore exceptions ! 171: FEM_IMPR_NONREC, // imprecise nonrecoverable ! 172: FEM_IMPR_RECOV, // imprecise recoverable ! 173: FEM_PRECISE ! 174: } fp_exc_mode_t; ! 175: ! 176: ! 177: /* ! 178: * Special purpose registers. ! 179: */ ! 180: ! 181: /* ! 182: * Processor version register (special purpose register pvr). ! 183: */ ! 184: typedef struct { ! 185: unsigned version:BITS_WIDTH(31,16), ! 186: revision:BITS_WIDTH(15,0); ! 187: } pvr_t; ! 188: ! 189: /* ! 190: * Fixed point exception register (special purpose register xer) ! 191: */ ! 192: typedef struct { ! 193: unsigned so:BIT_WIDTH(31), // summary overflow ! 194: ov:BIT_WIDTH(30), // overflow ! 195: ca:BIT_WIDTH(29), // carry ! 196: rsvd1:BITS_WIDTH(28,7), // reserved ! 197: byte_count:BITS_WIDTH(6,0); ! 198: } xer_t; ! 199: ! 200: /* ! 201: * Inlines and macros to manipulate the above registers. ! 202: */ ! 203: ! 204: /* ! 205: * Get/set machine state register. ! 206: */ ! 207: static __inline__ msr_t ! 208: get_msr() ! 209: { ! 210: msr_t __msr_tmp; ! 211: __asm__ volatile ("mfmsr %0 /* mfmsr */" : "=r" (__msr_tmp)); ! 212: return __msr_tmp; ! 213: } ! 214: ! 215: static __inline__ void ! 216: set_msr(msr_t msr) ! 217: { ! 218: __asm__ volatile ("mtmsr %0 /* mtmsr */ " : : "r" (msr)); ! 219: } ! 220: ! 221: /* ! 222: * Determine current fp_exc_mode_t given prog_mode. ! 223: */ ! 224: static __inline__ fp_exc_mode_t ! 225: get_fp_exc_mode(pmr_t pmr) ! 226: { ! 227: if(pmr.fe0) ! 228: return pmr.fe1 ? FEM_PRECISE : FEM_IMPR_RECOV; ! 229: else ! 230: return pmr.fe1 ? FEM_IMPR_NONREC : FEM_IGNORE_EXCEP; ! 231: } ! 232: ! 233: /* ! 234: * Software definitions for special purpose registers. ! 235: * The same register is used as per_cpu data pointer and ! 236: * vector base register. This requires that the vector ! 237: * table be the first item in the per_cpu table. ! 238: */ ! 239: #define SR_EXCEPTION_TMP_LR sprg0 ! 240: #define SR_EXCEPTION_TMP_CR sprg1 ! 241: #define SR_EXCEPTION_TMP_AT sprg2 ! 242: #define SR_PER_CPU_DATA sprg3 ! 243: #define SR_VBR sprg3 ! 244: ! 245: /* ! 246: * Get/set special purpose registers. ! 247: * ! 248: * GET_SPR - get SPR by name. ! 249: * ! 250: * Example usage: ! 251: * ! 252: * { ! 253: * xer_t some_xer; ! 254: * ! 255: * some_xer = GET_SPR(xer_t, xer); ! 256: * ... ! 257: * } ! 258: * ! 259: * This is a strange one. We're creating a list of C expressions within ! 260: * a set of curlies; the last expression ("__spr_tmp;") is the return value ! 261: * of the statement created by the curlies. ! 262: * ! 263: */ ! 264: ! 265: #define GET_SPR(type, spr) \ ! 266: ({ \ ! 267: unsigned __spr_tmp; \ ! 268: __asm__ volatile ("mfspr %0, " STRINGIFY(spr) : "=r" (__spr_tmp)); \ ! 269: *(type *)&__spr_tmp; \ ! 270: }) ! 271: ! 272: /* ! 273: * Example usage of SET_SPR: ! 274: * ! 275: * { ! 276: * xer_t some_xer; ! 277: * ! 278: * ...set up some_xer... ! 279: * SET_SPR(xer, some_xer); ! 280: * } ! 281: */ ! 282: #define SET_SPR(spr, val) \ ! 283: MACRO_BEGIN \ ! 284: __typeof__ (val) __spr_tmp = (val); \ ! 285: __asm__ volatile ("mtspr "STRINGIFY(spr) ", %0" : : "r" (__spr_tmp)); \ ! 286: MACRO_END ! 287: ! 288: /* ! 289: * Fully synchronize instruction stream. ! 290: */ ! 291: static __inline__ void ! 292: ppc_sync() ! 293: { ! 294: __asm__ volatile ("sync /* sync */" : : ); ! 295: } ! 296: ! 297: #endif /* ! __ASSEMBLER__ */ ! 298: ! 299: #endif /* _ARCH_PPC_BASIC_REGS_H_ */ ! 300:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.