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