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