]> git.saurik.com Git - apple/xnu.git/blob - EXTERNAL_HEADERS/architecture/ppc/basic_regs.h
xnu-123.5.tar.gz
[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 * 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 (umeshv@apple.com)
31 Updated to match MPCFPE32B/AD 1/97 REV. 1
32 * 29-Dec-96 Umesh Vaishampayan (umeshv@NeXT.com)
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 #include <architecture/ppc/reg_help.h>
42 #include <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