|
|
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.