1 /*
2 * Copyright (c) 2000-2004 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 #ifdef XNU_KERNEL_PRIVATE
23
24 #ifndef _PPC_SAVEAREA_H_
25 #define _PPC_SAVEAREA_H_
26
27 #ifndef ASSEMBLER
28
29 #include <sys/appleapiopts.h>
30
31 #ifdef __APPLE_API_PRIVATE
32
33 #ifdef MACH_KERNEL_PRIVATE
34 #include <stdint.h>
35 #include <mach/vm_types.h>
36
37 #pragma pack(4) /* Make sure the structure stays as we defined it */
38 typedef struct savearea_comm {
39
40 /*
41 * The following fields are common to all saveareas and are used to manage individual
42 * contexts.
43 *
44 * Fields that start with "save" are part of the individual saveareas. Those that
45 * start with "sac" pertain to the free pool stuff and are valid only on the first slot
46 * in the page.
47 */
48
49
50 /* Keep the save_prev, sac_next, and sac_prev in these positions, some assembler code depends upon it to
51 * match up with fields in saveanchor.
52 */
53 /* offset 0x000 */
54 addr64_t save_prev; /* The address of the previous (or next) savearea */
55 addr64_t sac_next; /* Points to next savearea page that has a free slot - real */
56 addr64_t sac_prev; /* Points to previous savearea page that has a free slot - real */
57 unsigned int save_level; /* Context ID */
58 unsigned int save_01C;
59
60 /* 0x20 */
61 unsigned int save_time[2]; /* Context save time - for debugging or performance */
62 struct thread *save_act; /* Associated thread */
63 unsigned int save_02c;
64 uint64_t sac_vrswap; /* XOR mask to swap V to R or vice versa */
65 unsigned int save_flags; /* Various flags */
66 unsigned int sac_flags; /* Various flags */
67
68 /* offset 0x040 */
69 uint64_t save_misc0; /* Various stuff */
70 uint64_t save_misc1; /* Various stuff - snapshot chain during hibernation */
71 unsigned int sac_alloc; /* Bitmap of allocated slots */
72 unsigned int save_054;
73 unsigned int save_misc2;
74 unsigned int save_misc3;
75
76 /* offset 0x0060 */
77 } savearea_comm;
78 #pragma pack()
79 #endif
80
81 #ifdef BSD_KERNEL_PRIVATE
82 typedef struct savearea_comm {
83 unsigned int save_000[24];
84 } savearea_comm;
85 #endif
86
87 #if defined(MACH_KERNEL_PRIVATE) || defined(BSD_KERNEL_PRIVATE)
88 /*
89 * This type of savearea contains all of the general context.
90 */
91
92 #pragma pack(4) /* Make sure the structure stays as we defined it */
93 typedef struct savearea {
94
95 savearea_comm save_hdr; /* Stuff common to all saveareas */
96
97 uint64_t save_xdat0; /* Exception data 0 */
98 uint64_t save_xdat1; /* Exception data 1 */
99 uint64_t save_xdat2; /* Exception data 2 */
100 uint64_t save_xdat3; /* Exception data 3 */
101 /* offset 0x0080 */
102 uint64_t save_r0;
103 uint64_t save_r1;
104 uint64_t save_r2;
105 uint64_t save_r3;
106 /* offset 0x0A0 */
107 uint64_t save_r4;
108 uint64_t save_r5;
109 uint64_t save_r6;
110 uint64_t save_r7;
111 /* offset 0x0C0 */
112 uint64_t save_r8;
113 uint64_t save_r9;
114 uint64_t save_r10;
115 uint64_t save_r11;
116 /* offset 0x0E0 */
117 uint64_t save_r12;
118 uint64_t save_r13;
119 uint64_t save_r14;
120 uint64_t save_r15;
121 /* offset 0x100 */
122 uint64_t save_r16;
123 uint64_t save_r17;
124 uint64_t save_r18;
125 uint64_t save_r19;
126 /* offset 0x120 */
127 uint64_t save_r20;
128 uint64_t save_r21;
129 uint64_t save_r22;
130 uint64_t save_r23;
131 /* offset 0x140 */
132 uint64_t save_r24;
133 uint64_t save_r25;
134 uint64_t save_r26;
135 uint64_t save_r27;
136 /* offset 0x160 */
137 uint64_t save_r28;
138 uint64_t save_r29;
139 uint64_t save_r30;
140 uint64_t save_r31;
141 /* offset 0x180 */
142 uint64_t save_srr0;
143 uint64_t save_srr1;
144 uint64_t save_xer;
145 uint64_t save_lr;
146 /* offset 0x1A0 */
147 uint64_t save_ctr;
148 uint64_t save_dar;
149 unsigned int save_cr;
150 unsigned int save_dsisr;
151 unsigned int save_exception;
152 unsigned int save_vrsave;
153 /* offset 0x1C0 */
154 unsigned int save_vscr[4];
155 unsigned int save_fpscrpad;
156 unsigned int save_fpscr;
157 unsigned int save_1d8[2];
158 /* offset 0x1E0 */
159 unsigned int save_1E0[8];
160 /* offset 0x200 - keep on 128 byte bndry */
161 uint32_t save_pmc[8];
162 uint64_t save_mmcr0; /* offset 0x220 */
163 uint64_t save_mmcr1;
164 uint64_t save_mmcr2;
165
166 unsigned int save_238[2];
167 /* offset 0x240 */
168 unsigned int save_instr[16]; /* Instrumentation */
169 /* offset 0x280 */
170 } savearea;
171 #pragma pack()
172
173
174 /*
175 * This type of savearea contains all of the floating point context.
176 */
177
178 #pragma pack(4) /* Make sure the structure stays as we defined it */
179 typedef struct savearea_fpu {
180
181 savearea_comm save_hdr; /* Stuff common to all saveareas */
182
183 unsigned int save_060[8]; /* Fill 32 bytes */
184 /* offset 0x0080 */
185 double save_fp0;
186 double save_fp1;
187 double save_fp2;
188 double save_fp3;
189
190 double save_fp4;
191 double save_fp5;
192 double save_fp6;
193 double save_fp7;
194
195 double save_fp8;
196 double save_fp9;
197 double save_fp10;
198 double save_fp11;
199
200 double save_fp12;
201 double save_fp13;
202 double save_fp14;
203 double save_fp15;
204
205 double save_fp16;
206 double save_fp17;
207 double save_fp18;
208 double save_fp19;
209
210 double save_fp20;
211 double save_fp21;
212 double save_fp22;
213 double save_fp23;
214
215 double save_fp24;
216 double save_fp25;
217 double save_fp26;
218 double save_fp27;
219
220 double save_fp28;
221 double save_fp29;
222 double save_fp30;
223 double save_fp31;
224 /* offset 0x180 */
225 unsigned int save_180[8];
226 unsigned int save_1A0[8];
227 unsigned int save_1C0[8];
228 unsigned int save_1E0[8];
229 unsigned int save_200[8];
230 unsigned int save_220[8];
231 unsigned int save_240[8];
232 unsigned int save_260[8];
233
234 /* offset 0x280 */
235 } savearea_fpu;
236 #pragma pack()
237
238
239
240 /*
241 * This type of savearea contains all of the vector context.
242 */
243
244 #pragma pack(4) /* Make sure the structure stays as we defined it */
245 typedef struct savearea_vec {
246
247 savearea_comm save_hdr; /* Stuff common to all saveareas */
248
249 unsigned int save_060[7]; /* Fill 32 bytes */
250 unsigned int save_vrvalid; /* Valid registers in saved context */
251
252 /* offset 0x0080 */
253 unsigned int save_vr0[4];
254 unsigned int save_vr1[4];
255 unsigned int save_vr2[4];
256 unsigned int save_vr3[4];
257 unsigned int save_vr4[4];
258 unsigned int save_vr5[4];
259 unsigned int save_vr6[4];
260 unsigned int save_vr7[4];
261 unsigned int save_vr8[4];
262 unsigned int save_vr9[4];
263 unsigned int save_vr10[4];
264 unsigned int save_vr11[4];
265 unsigned int save_vr12[4];
266 unsigned int save_vr13[4];
267 unsigned int save_vr14[4];
268 unsigned int save_vr15[4];
269 unsigned int save_vr16[4];
270 unsigned int save_vr17[4];
271 unsigned int save_vr18[4];
272 unsigned int save_vr19[4];
273 unsigned int save_vr20[4];
274 unsigned int save_vr21[4];
275 unsigned int save_vr22[4];
276 unsigned int save_vr23[4];
277 unsigned int save_vr24[4];
278 unsigned int save_vr25[4];
279 unsigned int save_vr26[4];
280 unsigned int save_vr27[4];
281 unsigned int save_vr28[4];
282 unsigned int save_vr29[4];
283 unsigned int save_vr30[4];
284 unsigned int save_vr31[4];
285
286 /* offset 0x280 */
287 } savearea_vec;
288 #pragma pack()
289 #endif /* MACH_KERNEL_PRIVATE || BSD_KERNEL_PRIVATE */
290
291 #ifdef MACH_KERNEL_PRIVATE
292
293 #pragma pack(4) /* Make sure the structure stays as we defined it */
294 struct Saveanchor {
295
296 /*
297 * Note that this force aligned in aligned_data.s and must be in V=R storage.
298 * Also, all addresses in chains are physical. This structure can only be
299 * updated with translation and interrupts disabled. This is because it is
300 * locked during exception processing and if we were to take a PTE miss while the
301 * lock were held, well, that would be very bad now wouldn't it?
302 * Note that the first 24 bytes must be the same format as a savearea header.
303 */
304
305 unsigned int savelock; /* 000 Lock word for savearea free list manipulation */
306 int saveRSVD4; /* 004 reserved */
307 addr64_t savepoolfwd; /* 008 Forward anchor for the free pool */
308 addr64_t savepoolbwd; /* 010 Backward anchor for the free pool */
309 volatile addr64_t savefree; /* 018 Anchor for the global free list */
310 volatile unsigned int savefreecnt; /* 020 Number of saveareas on global free list */
311 volatile int saveadjust; /* 024 If 0 number of saveareas is ok, otherwise # to change (pos means grow, neg means shrink */
312 volatile int saveinuse; /* 028 Number of areas in use counting those on the local free list */
313 unsigned int savetarget; /* 02C Number of saveareas needed */
314 int savemaxcount; /* 030 Maximum saveareas ever allocated */
315 unsigned int saveinusesnapshot; /* 034 snapshot inuse count */
316 volatile addr64_t savefreesnapshot; /* 038 snapshot global free list header */
317 /* 040 */
318 };
319 #pragma pack()
320
321 extern struct Saveanchor saveanchor; /* Aliged savearea anchor */
322
323 #define sac_cnt (4096 / sizeof(savearea)) /* Number of saveareas per page */
324 #define sac_empty (0xFFFFFFFF << (32 - sac_cnt)) /* Mask with all entries empty */
325 #define sac_perm 0x40000000 /* Page permanently assigned */
326 #define sac_permb 1 /* Page permanently assigned - bit position */
327
328 #define LocalSaveTarget (((8 + sac_cnt - 1) / sac_cnt) * sac_cnt) /* Target for size of local savearea free list */
329 #define LocalSaveMin (LocalSaveTarget / 2) /* Min size of local savearea free list before we grow */
330 #define LocalSaveMax (LocalSaveTarget * 2) /* Max size of local savearea free list before we trim */
331
332 #define FreeListMin (2 * LocalSaveTarget) /* Always make sure there are enough to fill local list twice per processor */
333 #define SaveLowHysteresis LocalSaveTarget /* The number off from target before we adjust upwards */
334 #define SaveHighHysteresis (2 * FreeListMin) /* The number off from target before we adjust downwards */
335 #define InitialSaveAreas (2 * FreeListMin) /* The number of saveareas to make at boot time */
336 #define InitialSaveTarget FreeListMin /* The number of saveareas for an initial target. This should be the minimum ever needed. */
337 #define InitialSaveBloks (InitialSaveAreas + sac_cnt - 1) / sac_cnt /* The number of savearea blocks to allocate at boot */
338 #define BackPocketSaveBloks 8 /* Number of pages of back pocket saveareas */
339
340 void save_queue(ppnum_t); /* Add a new savearea block to the free list */
341 addr64_t save_get_init(void); /* special savearea-get for cpu initialization (returns physical address) */
342 struct savearea *save_get(void); /* Obtains a savearea from the free list (returns virtual address) */
343 reg64_t save_get_phys_32(void); /* Obtains a savearea from the free list (returns phys addr in r3) */
344 reg64_t save_get_phys_64(void); /* Obtains a savearea from the free list (returns phys addr in r3) */
345 struct savearea *save_alloc(void); /* Obtains a savearea and allocates blocks if needed */
346 struct savearea *save_cpv(addr64_t); /* Converts a physical savearea address to virtual */
347 void save_ret(struct savearea *); /* Returns a savearea to the free list by virtual address */
348 void save_ret_wMSR(struct savearea *, reg64_t); /* returns a savearea and restores an MSR */
349 void save_ret_phys(reg64_t); /* Returns a savearea to the free list by physical address */
350 void save_adjust(void); /* Adjust size of the global free list */
351 struct savearea_comm *save_trim_free(void); /* Remove free pages from savearea pool */
352 int save_recover(void); /* returns nonzero if we can recover enough from the free pool */
353 void savearea_init(vm_offset_t addr); /* Boot-time savearea initialization */
354
355 void save_fake_zone_info( /* report savearea usage statistics as fake zone info */
356 int *count,
357 vm_size_t *cur_size,
358 vm_size_t *max_size,
359 vm_size_t *elem_size,
360 vm_size_t *alloc_size,
361 int *collectable,
362 int *exhaustable);
363
364 void save_snapshot(void);
365 void save_snapshot_restore(void);
366
367 #endif /* MACH_KERNEL_PRIVATE */
368 #endif /* __APPLE_API_PRIVATE */
369
370 #endif /* ndef ASSEMBLER */
371
372 #define SAVattach 0x80000000 /* Savearea has valid context */
373 #define SAVrststk 0x00010000 /* Indicates that the current stack should be reset to empty */
374 #define SAVsyscall 0x00020000 /* Indicates that the savearea is associated with a syscall */
375 #define SAVredrive 0x00040000 /* Indicates that the low-level fault handler associated */
376 #define SAVredriveb 13 /* Indicates that the low-level fault handler associated */
377 #define SAVinstrument 0x00080000 /* Indicates that we should return instrumentation data */
378 #define SAVinstrumentb 12 /* Indicates that we should return instrumentation data */
379 #define SAVeat 0x00100000 /* Indicates that interruption should be ignored */
380 #define SAVeatb 11 /* Indicates that interruption should be ignored */
381 #define SAVtype 0x0000FF00 /* Shows type of savearea */
382 #define SAVtypeshft 8 /* Shift to position type */
383 #define SAVempty 0x86 /* Savearea is on free list */
384 #define SAVgeneral 0x01 /* Savearea contains general context */
385 #define SAVfloat 0x02 /* Savearea contains floating point context */
386 #define SAVvector 0x03 /* Savearea contains vector context */
387
388
389
390 #endif /* _PPC_SAVEAREA_H_ */
391
392 #endif /* XNU_KERNEL_PRIVATE */
Cache object: 7ddd66da1d54566dada142e1c254fc46
|