2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
28 #ifdef XNU_KERNEL_PRIVATE
30 #ifndef _PPC_SAVEAREA_H_
31 #define _PPC_SAVEAREA_H_
35 #include <sys/appleapiopts.h>
37 #ifdef __APPLE_API_PRIVATE
39 #ifdef MACH_KERNEL_PRIVATE
41 #include <mach/vm_types.h>
43 #pragma pack(4) /* Make sure the structure stays as we defined it */
44 typedef struct savearea_comm
{
47 * The following fields are common to all saveareas and are used to manage individual
50 * Fields that start with "save" are part of the individual saveareas. Those that
51 * start with "sac" pertain to the free pool stuff and are valid only on the first slot
56 /* Keep the save_prev, sac_next, and sac_prev in these positions, some assembler code depends upon it to
57 * match up with fields in saveanchor.
60 addr64_t save_prev
; /* The address of the previous (or next) savearea */
61 addr64_t sac_next
; /* Points to next savearea page that has a free slot - real */
62 addr64_t sac_prev
; /* Points to previous savearea page that has a free slot - real */
63 unsigned int save_level
; /* Context ID */
64 unsigned int save_01C
;
67 unsigned int save_time
[2]; /* Context save time - for debugging or performance */
68 struct thread
*save_act
; /* Associated thread */
69 unsigned int save_02c
;
70 uint64_t sac_vrswap
; /* XOR mask to swap V to R or vice versa */
71 unsigned int save_flags
; /* Various flags */
72 unsigned int sac_flags
; /* Various flags */
75 uint64_t save_misc0
; /* Various stuff */
76 uint64_t save_misc1
; /* Various stuff - snapshot chain during hibernation */
77 unsigned int sac_alloc
; /* Bitmap of allocated slots */
78 unsigned int save_054
;
79 unsigned int save_misc2
;
80 unsigned int save_misc3
;
87 #ifdef BSD_KERNEL_PRIVATE
88 typedef struct savearea_comm
{
89 unsigned int save_000
[24];
93 #if defined(MACH_KERNEL_PRIVATE) || defined(BSD_KERNEL_PRIVATE)
95 * This type of savearea contains all of the general context.
98 #pragma pack(4) /* Make sure the structure stays as we defined it */
99 typedef struct savearea
{
101 savearea_comm save_hdr
; /* Stuff common to all saveareas */
103 uint64_t save_xdat0
; /* Exception data 0 */
104 uint64_t save_xdat1
; /* Exception data 1 */
105 uint64_t save_xdat2
; /* Exception data 2 */
106 uint64_t save_xdat3
; /* Exception data 3 */
155 unsigned int save_cr
;
156 unsigned int save_dsisr
;
157 unsigned int save_exception
;
158 unsigned int save_vrsave
;
160 unsigned int save_vscr
[4];
161 unsigned int save_fpscrpad
;
162 unsigned int save_fpscr
;
163 unsigned int save_1d8
[2];
165 unsigned int save_1E0
[8];
166 /* offset 0x200 - keep on 128 byte bndry */
167 uint32_t save_pmc
[8];
168 uint64_t save_mmcr0
; /* offset 0x220 */
172 unsigned int save_238
[2];
174 unsigned int save_instr
[16]; /* Instrumentation */
181 * This type of savearea contains all of the floating point context.
184 #pragma pack(4) /* Make sure the structure stays as we defined it */
185 typedef struct savearea_fpu
{
187 savearea_comm save_hdr
; /* Stuff common to all saveareas */
189 unsigned int save_060
[8]; /* Fill 32 bytes */
231 unsigned int save_180
[8];
232 unsigned int save_1A0
[8];
233 unsigned int save_1C0
[8];
234 unsigned int save_1E0
[8];
235 unsigned int save_200
[8];
236 unsigned int save_220
[8];
237 unsigned int save_240
[8];
238 unsigned int save_260
[8];
247 * This type of savearea contains all of the vector context.
250 #pragma pack(4) /* Make sure the structure stays as we defined it */
251 typedef struct savearea_vec
{
253 savearea_comm save_hdr
; /* Stuff common to all saveareas */
255 unsigned int save_060
[7]; /* Fill 32 bytes */
256 unsigned int save_vrvalid
; /* Valid registers in saved context */
259 unsigned int save_vr0
[4];
260 unsigned int save_vr1
[4];
261 unsigned int save_vr2
[4];
262 unsigned int save_vr3
[4];
263 unsigned int save_vr4
[4];
264 unsigned int save_vr5
[4];
265 unsigned int save_vr6
[4];
266 unsigned int save_vr7
[4];
267 unsigned int save_vr8
[4];
268 unsigned int save_vr9
[4];
269 unsigned int save_vr10
[4];
270 unsigned int save_vr11
[4];
271 unsigned int save_vr12
[4];
272 unsigned int save_vr13
[4];
273 unsigned int save_vr14
[4];
274 unsigned int save_vr15
[4];
275 unsigned int save_vr16
[4];
276 unsigned int save_vr17
[4];
277 unsigned int save_vr18
[4];
278 unsigned int save_vr19
[4];
279 unsigned int save_vr20
[4];
280 unsigned int save_vr21
[4];
281 unsigned int save_vr22
[4];
282 unsigned int save_vr23
[4];
283 unsigned int save_vr24
[4];
284 unsigned int save_vr25
[4];
285 unsigned int save_vr26
[4];
286 unsigned int save_vr27
[4];
287 unsigned int save_vr28
[4];
288 unsigned int save_vr29
[4];
289 unsigned int save_vr30
[4];
290 unsigned int save_vr31
[4];
295 #endif /* MACH_KERNEL_PRIVATE || BSD_KERNEL_PRIVATE */
297 #ifdef MACH_KERNEL_PRIVATE
299 #pragma pack(4) /* Make sure the structure stays as we defined it */
303 * Note that this force aligned in aligned_data.s and must be in V=R storage.
304 * Also, all addresses in chains are physical. This structure can only be
305 * updated with translation and interrupts disabled. This is because it is
306 * locked during exception processing and if we were to take a PTE miss while the
307 * lock were held, well, that would be very bad now wouldn't it?
308 * Note that the first 24 bytes must be the same format as a savearea header.
311 unsigned int savelock
; /* 000 Lock word for savearea free list manipulation */
312 int saveRSVD4
; /* 004 reserved */
313 addr64_t savepoolfwd
; /* 008 Forward anchor for the free pool */
314 addr64_t savepoolbwd
; /* 010 Backward anchor for the free pool */
315 volatile addr64_t savefree
; /* 018 Anchor for the global free list */
316 volatile unsigned int savefreecnt
; /* 020 Number of saveareas on global free list */
317 volatile int saveadjust
; /* 024 If 0 number of saveareas is ok, otherwise # to change (pos means grow, neg means shrink */
318 volatile int saveinuse
; /* 028 Number of areas in use counting those on the local free list */
319 unsigned int savetarget
; /* 02C Number of saveareas needed */
320 int savemaxcount
; /* 030 Maximum saveareas ever allocated */
321 unsigned int saveinusesnapshot
; /* 034 snapshot inuse count */
322 volatile addr64_t savefreesnapshot
; /* 038 snapshot global free list header */
327 extern struct Saveanchor saveanchor
; /* Aliged savearea anchor */
329 #define sac_cnt (4096 / sizeof(savearea)) /* Number of saveareas per page */
330 #define sac_empty (0xFFFFFFFF << (32 - sac_cnt)) /* Mask with all entries empty */
331 #define sac_perm 0x40000000 /* Page permanently assigned */
332 #define sac_permb 1 /* Page permanently assigned - bit position */
334 #define LocalSaveTarget (((8 + sac_cnt - 1) / sac_cnt) * sac_cnt) /* Target for size of local savearea free list */
335 #define LocalSaveMin (LocalSaveTarget / 2) /* Min size of local savearea free list before we grow */
336 #define LocalSaveMax (LocalSaveTarget * 2) /* Max size of local savearea free list before we trim */
338 #define FreeListMin (2 * LocalSaveTarget) /* Always make sure there are enough to fill local list twice per processor */
339 #define SaveLowHysteresis LocalSaveTarget /* The number off from target before we adjust upwards */
340 #define SaveHighHysteresis (2 * FreeListMin) /* The number off from target before we adjust downwards */
341 #define InitialSaveAreas (2 * FreeListMin) /* The number of saveareas to make at boot time */
342 #define InitialSaveTarget FreeListMin /* The number of saveareas for an initial target. This should be the minimum ever needed. */
343 #define InitialSaveBloks (InitialSaveAreas + sac_cnt - 1) / sac_cnt /* The number of savearea blocks to allocate at boot */
344 #define BackPocketSaveBloks 8 /* Number of pages of back pocket saveareas */
346 void save_queue(ppnum_t
); /* Add a new savearea block to the free list */
347 addr64_t
save_get_init(void); /* special savearea-get for cpu initialization (returns physical address) */
348 struct savearea
*save_get(void); /* Obtains a savearea from the free list (returns virtual address) */
349 reg64_t
save_get_phys_32(void); /* Obtains a savearea from the free list (returns phys addr in r3) */
350 reg64_t
save_get_phys_64(void); /* Obtains a savearea from the free list (returns phys addr in r3) */
351 struct savearea
*save_alloc(void); /* Obtains a savearea and allocates blocks if needed */
352 struct savearea
*save_cpv(addr64_t
); /* Converts a physical savearea address to virtual */
353 void save_ret(struct savearea
*); /* Returns a savearea to the free list by virtual address */
354 void save_ret_wMSR(struct savearea
*, reg64_t
); /* returns a savearea and restores an MSR */
355 void save_ret_phys(reg64_t
); /* Returns a savearea to the free list by physical address */
356 void save_adjust(void); /* Adjust size of the global free list */
357 struct savearea_comm
*save_trim_free(void); /* Remove free pages from savearea pool */
358 int save_recover(void); /* returns nonzero if we can recover enough from the free pool */
359 void savearea_init(vm_offset_t addr
); /* Boot-time savearea initialization */
361 void save_fake_zone_info( /* report savearea usage statistics as fake zone info */
365 vm_size_t
*elem_size
,
366 vm_size_t
*alloc_size
,
370 void save_snapshot(void);
371 void save_snapshot_restore(void);
373 #endif /* MACH_KERNEL_PRIVATE */
374 #endif /* __APPLE_API_PRIVATE */
376 #endif /* ndef ASSEMBLER */
378 #define SAVattach 0x80000000 /* Savearea has valid context */
379 #define SAVrststk 0x00010000 /* Indicates that the current stack should be reset to empty */
380 #define SAVsyscall 0x00020000 /* Indicates that the savearea is associated with a syscall */
381 #define SAVredrive 0x00040000 /* Indicates that the low-level fault handler associated */
382 #define SAVredriveb 13 /* Indicates that the low-level fault handler associated */
383 #define SAVinstrument 0x00080000 /* Indicates that we should return instrumentation data */
384 #define SAVinstrumentb 12 /* Indicates that we should return instrumentation data */
385 #define SAVeat 0x00100000 /* Indicates that interruption should be ignored */
386 #define SAVeatb 11 /* Indicates that interruption should be ignored */
387 #define SAVtype 0x0000FF00 /* Shows type of savearea */
388 #define SAVtypeshft 8 /* Shift to position type */
389 #define SAVempty 0x86 /* Savearea is on free list */
390 #define SAVgeneral 0x01 /* Savearea contains general context */
391 #define SAVfloat 0x02 /* Savearea contains floating point context */
392 #define SAVvector 0x03 /* Savearea contains vector context */
396 #endif /* _PPC_SAVEAREA_H_ */
398 #endif /* XNU_KERNEL_PRIVATE */