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