]> git.saurik.com Git - apple/xnu.git/blame - osfmk/ppc/mappings.h
xnu-517.tar.gz
[apple/xnu.git] / osfmk / ppc / mappings.h
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
43866e37 6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
1c79356b 7 *
43866e37
A
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
1c79356b
A
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
43866e37
A
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.
1c79356b
A
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25/*
26 * Header files for the hardware virtual memory mapping stuff
27 */
28#ifndef _PPC_MAPPINGS_H_
29#define _PPC_MAPPINGS_H_
30
55e303ae
A
31#include <cpus.h>
32
33#include <mach/mach_types.h>
34#include <mach/vm_types.h>
35#include <mach/machine/vm_types.h>
36#include <mach/vm_prot.h>
37#include <mach/vm_statistics.h>
38#include <kern/assert.h>
39#include <kern/cpu_number.h>
40#include <kern/lock.h>
41#include <kern/queue.h>
42#include <ppc/proc_reg.h>
43
44/*
45 * Don't change these structures unless you change the assembly code
46 */
47
48/*
49 * This control block serves as anchor for all virtual mappings of the same physical
50 * page, i.e., aliases. There is a table for each bank (mem_region). All tables
51 * must reside in V=R storage and within the first 2GB of memory. Also, the
52 * mappings to which it points must be on at least a 64-byte boundary. These
53 * requirements allow a total of 2 bits for status and flags, and allow all address
54 * calculations to be 32-bit.
55 */
56
57#pragma pack(4) /* Make sure the structure stays as we defined it */
58typedef struct phys_entry {
59 addr64_t ppLink; /* Physical pointer to aliased mappings and flags */
60#define ppLock 0x8000000000000000LL /* Lock for alias chain */
61#define ppN 0x4000000000000000LL /* Not executable */
62#define ppFlags 0x000000000000003FLL /* Status and flags */
63#define ppI 0x0000000000000020LL /* Cache inhibited */
64#define ppIb 58 /* Cache inhibited */
65#define ppG 0x0000000000000010LL /* Guarded */
66#define ppGb 59 /* Guarded */
67#define ppR 0x0000000000000008LL /* Referenced */
68#define ppRb 60 /* Referenced */
69#define ppC 0x0000000000000004LL /* Changed */
70#define ppCb 61 /* Changed */
71#define ppPP 0x0000000000000003LL /* Protection */
72#define ppPPb 62 /* Protection begin */
73#define ppPPe 63 /* Protection end */
74} phys_entry;
75#pragma pack()
76
77/* Memory may be non-contiguous. This data structure contains info
78 * for mapping this non-contiguous space into the contiguous
79 * physical->virtual mapping tables. An array of this type is
80 * provided to the pmap system at bootstrap by ppc_vm_init.
81 *
82 */
83
84#pragma pack(4) /* Make sure the structure stays as we defined it */
85typedef struct mem_region {
86 phys_entry *mrPhysTab; /* Base of region table */
87 ppnum_t mrStart; /* Start of region */
88 ppnum_t mrEnd; /* Last page in region */
89 ppnum_t mrAStart; /* Next page in region to allocate */
90 ppnum_t mrAEnd; /* Last page in region to allocate */
91} mem_region_t;
92#pragma pack()
93
94#define mrSize sizeof(mem_region_t)
95#define PMAP_MEM_REGION_MAX 26
96
97extern mem_region_t pmap_mem_regions[PMAP_MEM_REGION_MAX + 1];
98extern int pmap_mem_regions_count;
99
100/* Prototypes */
101
102
103#pragma pack(4) /* Make sure the structure stays as we defined it */
1c79356b 104typedef struct PCA { /* PTEG Control Area */
1c79356b
A
105 union flgs {
106 unsigned int PCAallo; /* Allocation controls */
107 struct PCAalflgs { /* Keep these in order!!! */
108 unsigned char PCAfree; /* Indicates the slot is free */
de355530 109 unsigned char PCAsteal; /* Steal scan start position */
55e303ae
A
110 unsigned char PCAauto; /* Indicates that the PTE was autogenned */
111 unsigned char PCAmisc; /* Misc. flags */
112#define PCAlock 1 /* This locks up the associated PTEG */
113#define PCAlockb 31
1c79356b
A
114 } PCAalflgs;
115 } flgs;
1c79356b 116} PCA;
55e303ae 117#pragma pack()
1c79356b 118
55e303ae
A
119/* Mappings currently come in two sizes: 64 and 128 bytes. The only difference is the
120 * number of skiplists (ie, mpLists): 64-byte mappings have 1-4 lists and 128-byte mappings
121 * have from 5-12. Only 1 in 256 mappings is large, so an average mapping is 64.25 bytes.
122 * All mappings are 64-byte aligned.
de355530 123 *
55e303ae
A
124 * Special note on mpFIP and mpRIP:
125 * These flags are manipulated under various locks. RIP is always set under an
126 * exclusive lock while FIP is shared. The only worry is that there is a possibility that
127 * FIP could be attempted by more than 1 processor at a time. Obviously, one will win.
128 * The other(s) bail all the way to user state and may refault (or not). There are only
129 * a few things in mpFlags that are not static, mpFIP, mpRIP, mpRemovable, and mpBusy.
130 *
131 * We organize these so that mpFIP is in a byte with static data and mpRIP and mpRemovable
132 * is in another. That means that we can use a store byte to update the guys without
133 * worrying about load and reserve. Note that mpFIP must be set atomically because it is
134 * under a share lock, but it may be clear with a simple store byte. So far as mpRIP
135 * goes, it is in the same byte as mpRemovable. However, mpRemovable is set atomically
136 * but never cleared, and mpRIP will not ever be set until after mpRemovable. Note that
137 * mpRIP is never cleared either.
138 *
139 */
140#pragma pack(4) /* Make sure the structure stays as we defined it */
141typedef struct mapping {
142 unsigned int mpFlags; /* 0x000 - Various flags, lock bit. These are static except for lock */
143#define mpBusy 0xFF000000 /* Busy count */
144#define mpPIndex 0x00FF0000 /* Index into physical table (in words) */
145#define mpSpecial 0x00008000 /* Special mapping - processor specific. */
146#define mpSpecialb 16 /* Special mapping - processor specific. */
147#define mpFIP 0x00004000 /* Fault in progress */
148#define mpFIPb 17 /* Fault in progress */
149#define mpNest 0x00001000 /* Mapping describes nested pmap */
150#define mpNestb 19 /* Mapping describes nested pmap */
151#define mpPerm 0x00000800 /* Mapping is permanent */
152#define mpPermb 20 /* Mapping is permanent */
153#define mpBlock 0x00000400 /* Mapping is a block map - used for V=F or I/O */
154#define mpBlockb 21 /* Mapping is a block map - used for V=F or I/O */
155#define mpRIP 0x00000080 /* Remove in progress - DO NOT MOVE */
156#define mpRIPb 24 /* Remove in progress */
157#define mpRemovable 0x00000040 /* Mapping is removable - DO NOT MOVE */
158#define mpRemovableb 25 /* Mapping is removable */
159#define mpRSVD1 0x00002330 /* Reserved for future use */
160#define mpLists 0x0000001F /* Number of skip lists mapping is on, max of 27 */
161#define mpListsb 27 /* Number of skip lists mapping is on, max of 27 */
1c79356b 162
55e303ae
A
163 unsigned short mpSpace; /* 0x004 - Address space hash */
164 unsigned short mpBSize; /* 0x006 - Block size - 1 in pages - max block size 256MB */
165 unsigned int mpPte; /* 0x008 - Offset to PTEG in hash table. Offset to exact PTE if mpHValid set - NOTE: this MUST be 0 for block mappings */
166#define mpHValid 0x00000001 /* PTE is entered in hash table */
167#define mpHValidb 31 /* PTE is entered in hash table */
168 ppnum_t mpPAddr; /* 0x00C - Physical page number */
169 addr64_t mpVAddr; /* 0x010 - Starting virtual address */
170#define mpHWFlags 0x0000000000000FFFULL /* Reference/Change, WIMG, AC, N, protection flags from PTE */
171#define mpPP 0x0000000000000007ULL /* Protection flags */
172#define mpPPb 61
173#define mpKKN 0x0000000000000007ULL /* Segment key and no execute flag (nested pmap) */
174#define mpKKNb 61
175#define mpWIMG 0x0000000000000078ULL /* Attribute bits */
176#define mpWIMGb 57
177#define mpW 0x0000000000000040ULL
178#define mpWb 57
179#define mpI 0x0000000000000020ULL
180#define mpIb 58
181#define mpM 0x0000000000000010ULL
182#define mpMb 59
183#define mpG 0x0000000000000008ULL
184#define mpGb 60
185#define mpWIMGe 60
186#define mpC 0x0000000000000080ULL /* Change bit */
187#define mpCb 56
188#define mpR 0x0000000000000100ULL /* Reference bit */
189#define mpRb 55
190 addr64_t mpAlias; /* 0x018 - Pointer to alias mappings of physical page */
191#define mpNestReloc mpAlias /* 0x018 - Redefines mpAlias relocation value of vaddr to nested pmap value */
192#define mpBlkRemCur mpAlias /* 0x018 - Next offset in block map to remove (this is 4 bytes) */
193 addr64_t mpList0; /* 0x020 - Forward chain of mappings. This one is always used */
194 addr64_t mpList[3]; /* 0x028 - Forward chain of mappings. Next higher order */
195/* 0x040 - End of basic mapping */
196#define mpBasicSize 64
197#define mpBasicLists 4
198/* note the dependence on kSkipListMaxLists, which must be <= #lists in a 256-byte mapping (ie, <=28) */
199/* addr64_t mpList4[8]; 0x040 - First extended list entries */
200/* 0x080 - End of first extended mapping */
201/* addr64_t mpList12[8]; 0x080 - Second extended list entries */
202/* 0x0C0 - End of second extended mapping */
203/* addr64_t mpList20[8]; 0x0C0 - Third extended list entries */
204/* 0x100 - End of third extended mapping */
1c79356b 205
55e303ae
A
206} mapping;
207#pragma pack()
1c79356b
A
208
209#define MAPPING_NULL ((struct mapping *) 0)
210
0b4e3aa0
A
211#define mapDirect 0x08
212#define mapRWNA 0x00000000
213#define mapRWRO 0x00000001
214#define mapRWRW 0x00000002
215#define mapRORO 0x00000003
216
55e303ae
A
217/* All counts are in units of basic 64-byte mappings. A 128-byte mapping is
218 * just two adjacent 64-byte entries.
219 */
220#pragma pack(4) /* Make sure the structure stays as we defined it */
9bccf70c
A
221
222typedef struct mappingflush {
55e303ae
A
223 addr64_t addr; /* Start address to search mapping */
224 unsigned int spacenum; /* Last space num to search pmap */
225 unsigned int mapfgas[1]; /* Pad to 64 bytes */
9bccf70c
A
226} mappingflush;
227
1c79356b
A
228typedef struct mappingctl {
229 unsigned int mapclock; /* Mapping allocation lock */
230 unsigned int mapcrecurse; /* Mapping allocation recursion control */
231 struct mappingblok *mapcnext; /* First mapping block with free entries */
232 struct mappingblok *mapclast; /* Last mapping block with free entries */
233 struct mappingblok *mapcrel; /* List of deferred block releases */
234 unsigned int mapcfree; /* Total free entries on list */
235 unsigned int mapcinuse; /* Total entries in use */
236 unsigned int mapcreln; /* Total blocks on pending release list */
237 int mapcholdoff; /* Hold off clearing release list */
238 unsigned int mapcfreec; /* Total calls to mapping free */
239 unsigned int mapcallocc; /* Total calls to mapping alloc */
55e303ae
A
240 unsigned int mapcbig; /* Count times a big mapping was requested of mapping_alloc */
241 unsigned int mapcbigfails; /* Times caller asked for a big one but we gave 'em a small one */
1c79356b
A
242 unsigned int mapcmin; /* Minimum free mappings to keep */
243 unsigned int mapcmaxalloc; /* Maximum number of mappings allocated at one time */
de355530 244 unsigned int mapcgas[1]; /* Pad to 64 bytes */
55e303ae 245 struct mappingflush mapcflush;
1c79356b 246} mappingctl;
55e303ae 247#pragma pack()
1c79356b 248
55e303ae
A
249/* MAPPERBLOK is the number of basic 64-byte mappings per block (ie, per page.) */
250#define MAPPERBLOK 63
1c79356b
A
251#define MAPALTHRSH (4*MAPPERBLOK)
252#define MAPFRTHRSH (2 * ((MAPALTHRSH + MAPPERBLOK - 1) / MAPPERBLOK))
253typedef struct mappingblok {
55e303ae
A
254 unsigned int mapblokfree[2]; /* Bit map of free mapping entrys */
255 addr64_t mapblokvrswap; /* Virtual address XORed with physical address */
1c79356b
A
256 unsigned int mapblokflags; /* Various flags */
257#define mbPerm 0x80000000 /* Block is permanent */
258 struct mappingblok *nextblok; /* Pointer to the next mapping block */
259} mappingblok;
260
55e303ae
A
261#define mapRemChunk 128
262
263#define mapRetCode 0xF
264#define mapRtOK 0
265#define mapRtBadLk 1
266#define mapRtPerm 2
267#define mapRtNotFnd 3
268#define mapRtBlock 4
269#define mapRtNest 5
270#define mapRtRemove 6
271#define mapRtMapDup 7
272
1c79356b
A
273extern mappingctl mapCtl; /* Mapping allocation control */
274
55e303ae
A
275extern addr64_t mapping_remove(pmap_t pmap, addr64_t va); /* Remove a single mapping for this VADDR */
276extern mapping *mapping_find(pmap_t pmap, addr64_t va, addr64_t *nextva, int full); /* Finds a mapping */
1c79356b
A
277extern void mapping_free_init(vm_offset_t mbl, int perm, boolean_t locked); /* Sets start and end of a block of mappings */
278extern void mapping_adjust(void); /* Adjust free mapping count */
279extern void mapping_free_prime(void); /* Primes the mapping block release list */
280extern void mapping_prealloc(unsigned int); /* Preallocate mappings for large use */
281extern void mapping_relpre(void); /* Releases preallocate request */
282extern void mapping_init(void); /* Do initial stuff */
55e303ae 283extern mapping *mapping_alloc(int lists); /* Obtain a mapping */
1c79356b 284extern void mapping_free(struct mapping *mp); /* Release a mapping */
55e303ae
A
285extern boolean_t mapping_tst_ref(ppnum_t pa); /* Tests the reference bit of a physical page */
286extern boolean_t mapping_tst_mod(ppnum_t pa); /* Tests the change bit of a physical page */
287extern void mapping_set_ref(ppnum_t pa); /* Sets the reference bit of a physical page */
288extern void mapping_clr_ref(ppnum_t pa); /* Clears the reference bit of a physical page */
289extern void mapping_set_mod(ppnum_t pa); /* Sets the change bit of a physical page */
290extern void mapping_clr_mod(ppnum_t pa); /* Clears the change bit of a physical page */
291extern void mapping_protect_phys(ppnum_t pa, vm_prot_t prot); /* Change protection of all mappings to page */
292extern int mapping_protect(pmap_t pmap, addr64_t va, vm_prot_t prot, addr64_t *nextva); /* Change protection of a single mapping to page */
293extern addr64_t mapping_make(pmap_t pmap, addr64_t va, ppnum_t pa, unsigned int flags, unsigned int size, vm_prot_t prot); /* Make a mapping */
294/* Flags for mapping_make */
295#define mmFlgBlock 0x80000000 /* This is a block map, use size for number of pages covered */
296#define mmFlgUseAttr 0x40000000 /* Use specified attributes */
297#define mmFlgPerm 0x20000000 /* Mapping is permanant */
298#define mmFlgCInhib 0x00000002 /* Cahching inhibited - use if mapFlgUseAttr set or block */
299#define mmFlgGuarded 0x00000001 /* Access guarded - use if mapFlgUseAttr set or block */
300extern void mapping_purge(ppnum_t pa); /* Remove all mappings for this physent */
301extern addr64_t mapping_p2v(pmap_t pmap, ppnum_t pa); /* Finds first virtual mapping of a physical page in a space */
302extern void mapping_drop_busy(struct mapping *mapping); /* Drops busy count on mapping */
303extern phys_entry *mapping_phys_lookup(ppnum_t pp, unsigned int *pindex); /* Finds the physical entry for the page */
304extern int mapalc1(struct mappingblok *mb); /* Finds and allcates a 1-bit mapping entry */
305extern int mapalc2(struct mappingblok *mb); /* Finds and allcates a 2-bit mapping entry */
1c79356b
A
306extern void ignore_zero_fault(boolean_t type); /* Sets up to ignore or honor any fault on page 0 access for the current thread */
307
308
55e303ae
A
309extern mapping *hw_rem_map(pmap_t pmap, addr64_t va, addr64_t *next); /* Remove a mapping from the system */
310extern mapping *hw_purge_map(pmap_t pmap, addr64_t va, addr64_t *next); /* Remove a regular mapping from the system */
311extern mapping *hw_purge_space(struct phys_entry *pp, pmap_t pmap); /* Remove the first mapping for a specific pmap from physentry */
312extern mapping *hw_purge_phys(struct phys_entry *pp); /* Remove the first mapping for a physentry */
313extern mapping *hw_find_map(pmap_t pmap, addr64_t va, addr64_t *nextva); /* Finds a mapping */
314extern addr64_t hw_add_map(pmap_t pmap, struct mapping *mp); /* Add a mapping to a pmap */
315extern int hw_protect(pmap_t pmap, addr64_t va, vm_prot_t prot, addr64_t *nextva); /* Change the protection of a virtual page */
316extern unsigned int hw_test_rc(pmap_t pmap, addr64_t va, boolean_t reset); /* Test and optionally reset the RC bit of specific mapping */
317
318extern unsigned int hw_phys_walk(struct phys_entry *pp, unsigned int preop, unsigned int op, /* Perform function on all mappings on a physical page */
319 unsigned int postop, unsigned int parm);
320#define hwpNoop 0 /* No operation */
321#define hwpSPrtPhy 1 /* Sets protection in physent */
322#define hwpSPrtMap 2 /* Sets protection in mapping */
323#define hwpSAtrPhy 3 /* Sets attributes in physent */
324#define hwpSAtrMap 4 /* Sets attributes in mapping */
325#define hwpCRefPhy 5 /* Clears reference in physent */
326#define hwpCRefMap 6 /* Clears reference in mapping */
327#define hwpCCngPhy 7 /* Clears change in physent */
328#define hwpCCngMap 8 /* Clears change in mapping */
329#define hwpSRefPhy 9 /* Sets reference in physent */
330#define hwpSRefMap 10 /* Sets reference in mapping */
331#define hwpSCngPhy 11 /* Sets change in physent */
332#define hwpSCngMap 12 /* Sets change in mapping */
333#define hwpTRefPhy 13 /* Tests reference in physent */
334#define hwpTRefMap 14 /* Tests reference in mapping */
335#define hwpTCngPhy 15 /* Tests change in physent */
336#define hwpTCngMap 16 /* Tests change in mapping */
1c79356b
A
337
338extern boolean_t hw_tst_mod(struct phys_entry *pp); /* Tests change bit */
339extern void hw_set_mod(struct phys_entry *pp); /* Set change bit */
340extern void hw_clr_mod(struct phys_entry *pp); /* Clear change bit */
341
342extern boolean_t hw_tst_ref(struct phys_entry *pp); /* Tests reference bit */
343extern void hw_set_ref(struct phys_entry *pp); /* Set reference bit */
344extern void hw_clr_ref(struct phys_entry *pp); /* Clear reference bit */
345
1c79356b
A
346extern void hw_set_user_space(pmap_t pmap); /* Indicate we need a space switch */
347extern void hw_set_user_space_dis(pmap_t pmap); /* Indicate we need a space switch (already disabled) */
55e303ae
A
348extern void hw_setup_trans(void); /* Setup hardware for translation */
349extern void hw_start_trans(void); /* Start translation for the first time */
350extern void hw_map_seg(pmap_t pmap, addr64_t seg, addr64_t va); /* Validate a segment */
351extern void hw_blow_seg(addr64_t seg); /* Invalidate a segment */
352extern void invalidateSegs(pmap_t pmap); /* Invalidate the segment cache */
353extern struct phys_entry *pmap_find_physentry(ppnum_t pa);
354extern void mapLog(unsigned int laddr, unsigned int type, addr64_t va);
355extern unsigned int mapSkipListVerifyC(pmap_t pmap, unsigned long long *dumpa);
356extern void fillPage(ppnum_t pa, unsigned int fill);
1c79356b
A
357
358extern unsigned int mappingdeb0; /* (TEST/DEBUG) */
359extern unsigned int incrVSID; /* VSID increment value */
360
361#endif /* _PPC_MAPPINGS_H_ */
362