]>
Commit | Line | Data |
---|---|---|
1c79356b | 1 | /* |
91447636 | 2 | * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved. |
1c79356b | 3 | * |
8ad349bb | 4 | * @APPLE_LICENSE_OSREFERENCE_HEADER_START@ |
1c79356b | 5 | * |
8ad349bb A |
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 | |
10 | * License may not be used to create, or enable the creation or | |
11 | * redistribution of, unlawful or unlicensed copies of an Apple operating | |
12 | * system, or to circumvent, violate, or enable the circumvention or | |
13 | * violation of, any terms of an Apple operating system software license | |
14 | * agreement. | |
15 | * | |
16 | * Please obtain a copy of the License at | |
17 | * http://www.opensource.apple.com/apsl/ and read it before using this | |
18 | * file. | |
19 | * | |
20 | * The Original Code and all software distributed under the License are | |
21 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
22 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
23 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
24 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
25 | * Please see the License for the specific language governing rights and | |
26 | * limitations under the License. | |
27 | * | |
28 | * @APPLE_LICENSE_OSREFERENCE_HEADER_END@ | |
1c79356b A |
29 | */ |
30 | /* | |
31 | * @OSF_COPYRIGHT@ | |
32 | */ | |
33 | /* | |
34 | * Copyright (c) 1990 The University of Utah and | |
35 | * the Center for Software Science at the University of Utah (CSS). | |
36 | * All rights reserved. | |
37 | * | |
38 | * Permission to use, copy, modify and distribute this software is hereby | |
39 | * granted provided that (1) source code retains these copyright, permission, | |
40 | * and disclaimer notices, and (2) redistributions including binaries | |
41 | * reproduce the notices in supporting documentation, and (3) all advertising | |
42 | * materials mentioning features or use of this software display the following | |
43 | * acknowledgement: ``This product includes software developed by the Center | |
44 | * for Software Science at the University of Utah.'' | |
45 | * | |
46 | * THE UNIVERSITY OF UTAH AND CSS ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS | |
47 | * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSS DISCLAIM ANY LIABILITY OF | |
48 | * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. | |
49 | * | |
50 | * CSS requests users of this software to return to css-dist@cs.utah.edu any | |
51 | * improvements that they make and grant CSS redistribution rights. | |
52 | * | |
53 | * Utah $Hdr: pmap.h 1.13 91/09/25$ | |
54 | * Author: Mike Hibler, Bob Wheeler, University of Utah CSS, 9/90 | |
55 | */ | |
56 | ||
57 | #ifndef _PPC_PMAP_H_ | |
58 | #define _PPC_PMAP_H_ | |
59 | ||
60 | #include <mach/vm_types.h> | |
61 | #include <mach/machine/vm_types.h> | |
62 | #include <mach/vm_prot.h> | |
63 | #include <mach/vm_statistics.h> | |
64 | #include <kern/queue.h> | |
65 | #include <vm/pmap.h> | |
91447636 | 66 | #include <ppc/mappings.h> |
1c79356b | 67 | |
55e303ae A |
68 | #define maxPPage32 0x000FFFFF /* Maximum page number in 32-bit machines */ |
69 | ||
70 | typedef uint32_t shexlock; | |
71 | ||
72 | #pragma pack(4) /* Make sure the structure stays as we defined it */ | |
73 | ||
74 | struct sgc { | |
75 | uint64_t sgcESID; /* ESID portion of segment cache */ | |
76 | #define sgcESmsk 0xFFFFFFFFF0000000ULL /* ESID portion of segment register cache */ | |
77 | uint64_t sgcVSID; /* VSID portion of segment cache */ | |
78 | #define sgcVSmsk 0xFFFFFFFFFFFFF000ULL /* VSID mask */ | |
79 | #define sgcVSKeys 0x0000000000000C00ULL /* Protection keys */ | |
80 | #define sgcVSKeyUsr 53 /* User protection key */ | |
81 | #define sgcVSNoEx 0x0000000000000200ULL /* No execute */ | |
82 | }; | |
83 | #pragma pack() | |
84 | ||
85 | typedef struct sgc sgc; | |
86 | ||
91447636 A |
87 | #pragma pack(4) /* Make sure the structure stays as we defined it */ |
88 | struct pmap_vmm_stats { | |
89 | unsigned int vxsGpf; /* Guest faults */ | |
90 | unsigned int vxsGpfMiss; /* Faults that miss in hash table */ | |
91 | ||
92 | unsigned int vxsGrm; /* Guest mapping remove requests */ | |
93 | unsigned int vxsGrmMiss; /* Remove misses in hash table */ | |
94 | unsigned int vxsGrmActive; /* Remove hits that are active */ | |
95 | ||
96 | unsigned int vxsGra; /* Guest remove all mappings requests */ | |
97 | unsigned int vxsGraHits; /* Remove hits in hash table */ | |
98 | unsigned int vxsGraActive; /* Remove hits that are active */ | |
99 | ||
100 | unsigned int vxsGrl; /* Guest remove local mappings requests */ | |
101 | unsigned int vxsGrlActive; /* Active mappings removed */ | |
102 | ||
103 | unsigned int vxsGrs; /* Guest mapping resumes */ | |
104 | unsigned int vxsGrsHitAct; /* Resume hits active entry */ | |
105 | unsigned int vxsGrsHitSusp; /* Resume hits suspended entry */ | |
106 | unsigned int vxsGrsMissGV; /* Resume misses on guest virtual */ | |
107 | unsigned int vxsGrsHitPE; /* Resume hits on host virtual */ | |
108 | unsigned int vxsGrsMissPE; /* Resume misses on host virtual */ | |
109 | ||
110 | unsigned int vxsGad; /* Guest mapping adds */ | |
111 | unsigned int vxsGadHit; /* Add hits entry (active or dormant) */ | |
112 | unsigned int vxsGadFree; /* Add takes free entry in group */ | |
113 | unsigned int vxsGadDormant; /* Add steals dormant entry in group */ | |
114 | unsigned int vxsGadSteal; /* Add steals active entry in group */ | |
115 | ||
116 | unsigned int vxsGsu; /* Guest mapping suspends */ | |
117 | unsigned int vxsGsuHit; /* Suspend hits entry (active only) */ | |
118 | unsigned int vxsGsuMiss; /* Suspend misses entry */ | |
119 | ||
120 | unsigned int vxsGtd; /* Guest test ref&chg */ | |
121 | unsigned int vxsGtdHit; /* Test r&c hits entry (active only) */ | |
122 | unsigned int vxsGtdMiss; /* Test r&c misses entry */ | |
123 | }; | |
124 | #pragma pack() | |
125 | typedef struct pmap_vmm_stats pmap_vmm_stats; | |
126 | ||
127 | /* Not wanting to tax all of our customers for the sins of those that use virtual operating | |
128 | systems, we've built the hash table from its own primitive virtual memory. We first | |
129 | allocate a pmap_vmm_ext with sufficient space following to accomodate the hash table | |
130 | index (one 64-bit physical address per 4k-byte page of hash table). The allocation | |
131 | must not cross a 4k-byte page boundary (we'll be accessing the block with relocation | |
132 | off), so we'll try a couple of times, then just burn a whole page. We stuff the effective | |
133 | address of the cache-aligned index into hIdxBase; the physical-mode code locates the index | |
134 | by adding the size of a pmap_vmm_extension to its translated physical address, then rounding | |
135 | up to the next 32-byte boundary. Now we grab enough virtual pages to contain the hash table, | |
136 | and fill in the index with the page's physical addresses. For the final touch that's sure | |
137 | to please, we initialize the hash table. Mmmmm, golden brown perfection. | |
138 | */ | |
139 | ||
140 | #pragma pack(4) | |
141 | struct pmap_vmm_ext { | |
142 | addr64_t vmxSalt; /* This block's virt<->real conversion salt */ | |
143 | addr64_t vmxHostPmapPhys; /* Host pmap physical address */ | |
144 | struct pmap *vmxHostPmap; /* Host pmap effective address */ | |
145 | addr64_t *vmxHashPgIdx; /* Hash table physical index base address */ | |
146 | vm_offset_t *vmxHashPgList; /* List of virtual pages comprising the hash table */ | |
147 | unsigned int *vmxActiveBitmap; /* Bitmap of active mappings in hash table */ | |
148 | pmap_vmm_stats vmxStats; /* Stats for VMM assists */ | |
149 | #define VMX_HPIDX_OFFSET ((sizeof(pmap_vmm_ext) + 127) & ~127) | |
150 | /* The hash table physical index begins at the first | |
151 | 128-byte boundary after the pmap_vmm_ext struct */ | |
152 | #define VMX_HPLIST_OFFSET (VMX_HPIDX_OFFSET + (GV_HPAGES * sizeof(addr64_t))) | |
153 | #define VMX_ACTMAP_OFFSET (VMX_HPLIST_OFFSET + (GV_HPAGES * sizeof(vm_offset_t))) | |
154 | }; | |
155 | #pragma pack() | |
156 | typedef struct pmap_vmm_ext pmap_vmm_ext; | |
157 | ||
55e303ae | 158 | #pragma pack(4) /* Make sure the structure stays as we defined it */ |
1c79356b | 159 | struct pmap { |
55e303ae A |
160 | queue_head_t pmap_link; /* MUST BE FIRST */ |
161 | addr64_t pmapvr; /* Virtual to real conversion mask */ | |
162 | shexlock pmapSXlk; /* Shared/Exclusive lock for mapping changes */ | |
163 | unsigned int space; /* space for this pmap */ | |
164 | #define invalSpace 0x00000001 /* Predefined always invalid space */ | |
165 | int ref_count; /* reference count */ | |
166 | unsigned int pmapFlags; /* Flags */ | |
167 | #define pmapKeys 0x00000007 /* Keys and no execute bit to use with this pmap */ | |
168 | #define pmapKeyDef 0x00000006 /* Default keys - Sup = 1, user = 1, no ex = 0 */ | |
169 | #define pmapVMhost 0x00000010 /* pmap with Virtual Machines attached to it */ | |
91447636 | 170 | #define pmapVMgsaa 0x00000020 /* Guest shadow assist active */ |
5d5c5d0d | 171 | #define pmapNXdisabled 0x00000040 /* no-execute disabled for this pmap */ |
55e303ae A |
172 | unsigned int spaceNum; /* Space number */ |
173 | unsigned int pmapCCtl; /* Cache control */ | |
174 | #define pmapCCtlVal 0xFFFF0000 /* Valid entries */ | |
175 | #define pmapCCtlLck 0x00008000 /* Lock bit */ | |
176 | #define pmapCCtlLckb 16 /* Lock bit */ | |
177 | #define pmapCCtlGen 0x00007FFF /* Generation number */ | |
178 | ||
179 | #define pmapSegCacheCnt 16 /* Maximum number of cache entries */ | |
180 | #define pmapSegCacheUse 16 /* Number of cache entries to use */ | |
181 | ||
182 | struct pmap *freepmap; /* Free pmaps */ | |
91447636 A |
183 | pmap_vmm_ext *pmapVmmExt; /* VMM extension block, for VMM host and guest pmaps */ |
184 | addr64_t pmapVmmExtPhys; /* VMM extension block physical address */ | |
55e303ae A |
185 | /* 0x038 */ |
186 | uint64_t pmapSCSubTag; /* Segment cache sub-tags. This is a 16 entry 4 bit array */ | |
187 | /* 0x040 */ | |
188 | sgc pmapSegCache[pmapSegCacheCnt]; /* SLD values cached for quick load */ | |
189 | ||
190 | /* 0x140 */ | |
191 | /* if fanout is 4, then shift is 1, if fanout is 8 shift is 2, etc */ | |
192 | #define kSkipListFanoutShift 1 | |
193 | /* with n lists, we can handle (fanout**n) pages optimally */ | |
194 | #define kSkipListMaxLists 12 | |
195 | unsigned char pmapCurLists; /* 0x140 - max #lists any mapping in this pmap currently has */ | |
196 | unsigned char pmapRsv2[3]; | |
197 | uint32_t pmapRandNum; /* 0x144 - used by mapSetLists() as a random number generator */ | |
198 | addr64_t pmapSkipLists[kSkipListMaxLists]; /* 0x148 - the list headers */ | |
199 | /* following statistics conditionally gathered */ | |
200 | uint64_t pmapSearchVisits; /* 0x1A8 - nodes visited searching pmaps */ | |
201 | uint32_t pmapSearchCnt; /* 0x1B0 - number of calls to mapSearch or mapSearchFull */ | |
202 | ||
203 | unsigned int pmapRsv3[3]; | |
204 | ||
205 | /* 0x1C0 */ | |
206 | ||
207 | struct pmap_statistics stats; /* statistics */ | |
1c79356b A |
208 | |
209 | /* Need to pad out to a power of 2 - right now it is 512 bytes */ | |
210 | #define pmapSize 512 | |
211 | }; | |
55e303ae A |
212 | #pragma pack() |
213 | ||
214 | #pragma pack(4) | |
215 | struct pmapTransTab { | |
216 | addr64_t pmapPAddr; /* Physcial address of pmap */ | |
217 | unsigned int pmapVAddr; /* Virtual address of pmap */ | |
218 | }; | |
219 | #pragma pack() /* Make sure the structure stays as we defined it */ | |
220 | ||
221 | typedef struct pmapTransTab pmapTransTab; | |
1c79356b | 222 | |
91447636 A |
223 | /* |
224 | * Address Chunk IDentified Table | |
225 | */ | |
226 | ||
227 | struct acidTabEnt { | |
228 | unsigned int acidVAddr; /* Virtual address of pmap or pointer to next free entry */ | |
229 | unsigned int acidGas; /* reserved */ | |
230 | addr64_t acidPAddr; /* Physcial address of pmap */ | |
231 | }; | |
232 | ||
233 | typedef struct acidTabEnt acidTabEnt; | |
234 | ||
235 | extern acidTabEnt *acidTab; /* Pointer to acid table */ | |
236 | extern acidTabEnt *acidFree; /* List of free acid entries */ | |
237 | ||
1c79356b A |
238 | #define PMAP_NULL ((pmap_t) 0) |
239 | ||
1c79356b | 240 | extern pmap_t cursor_pmap; /* The pmap to start allocations with */ |
55e303ae A |
241 | extern pmap_t sharedPmap; |
242 | extern unsigned int sharedPage; | |
243 | extern int ppc_max_adrsp; /* Maximum number of concurrent address spaces allowed. */ | |
244 | extern addr64_t vm_max_address; /* Maximum effective address supported */ | |
245 | extern addr64_t vm_max_physical; /* Maximum physical address supported */ | |
246 | extern pmapTransTab *pmapTrans; /* Space to pmap translate table */ | |
1c79356b A |
247 | #define PMAP_SWITCH_USER(th, map, my_cpu) th->map = map; |
248 | ||
1c79356b A |
249 | #define PMAP_CONTEXT(pmap,th) |
250 | ||
251 | #define pmap_kernel_va(VA) \ | |
55e303ae | 252 | (((VA) >= VM_MIN_KERNEL_ADDRESS) && ((VA) <= vm_last_addr)) |
1c79356b A |
253 | |
254 | #define PPC_SID_KERNEL 0 /* Must change KERNEL_SEG_REG0_VALUE if !0 */ | |
55e303ae A |
255 | |
256 | #define maxAdrSp 16384 | |
257 | #define maxAdrSpb 14 | |
91447636 A |
258 | #define USER_MEM_WINDOW_VADDR 0x00000000E0000000ULL |
259 | #define PHYS_MEM_WINDOW_VADDR 0x0000000100000000ULL | |
260 | #define IO_MEM_WINDOW_VADDR 0x0000000080000000ULL | |
261 | #define IO_MEM_WINDOW_SIZE 0x0000000080000000ULL | |
3a60a9f5 | 262 | #define pmapSmallBlock 65536 |
1c79356b A |
263 | |
264 | #define pmap_kernel() (kernel_pmap) | |
265 | #define pmap_resident_count(pmap) ((pmap)->stats.resident_count) | |
266 | #define pmap_remove_attributes(pmap,start,end) | |
267 | #define pmap_copy(dpmap,spmap,da,len,sa) | |
268 | #define pmap_update() | |
269 | ||
9bccf70c A |
270 | #define PMAP_DEFAULT_CACHE 0 |
271 | #define PMAP_INHIBIT_CACHE 1 | |
272 | #define PMAP_GUARDED_CACHE 2 | |
273 | #define PMAP_ACTIVATE_CACHE 4 | |
274 | #define PMAP_NO_GUARD_CACHE 8 | |
275 | ||
276 | /* corresponds to cached, coherent, not writethru, not guarded */ | |
55e303ae A |
277 | #define VM_WIMG_DEFAULT (VM_MEM_COHERENT) |
278 | #define VM_WIMG_COPYBACK (VM_MEM_COHERENT) | |
279 | #define VM_WIMG_IO (VM_MEM_COHERENT | \ | |
280 | VM_MEM_NOT_CACHEABLE | VM_MEM_GUARDED) | |
281 | #define VM_WIMG_WTHRU (VM_MEM_WRITE_THROUGH | VM_MEM_COHERENT | VM_MEM_GUARDED) | |
282 | /* write combining mode, aka store gather */ | |
283 | #define VM_WIMG_WCOMB (VM_MEM_NOT_CACHEABLE | VM_MEM_COHERENT) | |
9bccf70c | 284 | |
1c79356b A |
285 | /* |
286 | * prototypes. | |
287 | */ | |
5d5c5d0d | 288 | extern addr64_t kvtophys(vm_offset_t va); /* Get physical address from kernel virtual */ |
1c79356b A |
289 | extern vm_offset_t pmap_map(vm_offset_t va, |
290 | vm_offset_t spa, | |
291 | vm_offset_t epa, | |
5d5c5d0d A |
292 | vm_prot_t prot, |
293 | unsigned int flags); | |
1c79356b A |
294 | extern kern_return_t pmap_add_physical_memory(vm_offset_t spa, |
295 | vm_offset_t epa, | |
296 | boolean_t available, | |
297 | unsigned int attr); | |
55e303ae | 298 | extern void pmap_bootstrap(uint64_t msize, |
1c79356b | 299 | vm_offset_t *first_avail, |
55e303ae | 300 | unsigned int kmapsize); |
1c79356b | 301 | |
91447636 | 302 | extern vm_offset_t pmap_boot_map(vm_size_t size); |
1c79356b | 303 | |
55e303ae A |
304 | extern void sync_cache64(addr64_t pa, unsigned length); |
305 | extern void sync_ppage(ppnum_t pa); | |
306 | extern void sync_cache_virtual(vm_offset_t va, unsigned length); | |
1c79356b | 307 | extern void flush_dcache(vm_offset_t va, unsigned length, boolean_t phys); |
55e303ae | 308 | extern void flush_dcache64(addr64_t va, unsigned length, boolean_t phys); |
1c79356b | 309 | extern void invalidate_dcache(vm_offset_t va, unsigned length, boolean_t phys); |
55e303ae | 310 | extern void invalidate_dcache64(addr64_t va, unsigned length, boolean_t phys); |
1c79356b | 311 | extern void invalidate_icache(vm_offset_t va, unsigned length, boolean_t phys); |
55e303ae | 312 | extern void invalidate_icache64(addr64_t va, unsigned length, boolean_t phys); |
91447636 A |
313 | extern void pmap_sync_page_data_phys(ppnum_t pa); |
314 | extern void pmap_sync_page_attributes_phys(ppnum_t pa); | |
3a60a9f5 A |
315 | extern void pmap_map_block(pmap_t pmap, addr64_t va, ppnum_t pa, uint32_t size, vm_prot_t prot, int attr, unsigned int flags); |
316 | extern int pmap_map_block_rc(pmap_t pmap, addr64_t va, ppnum_t pa, uint32_t size, vm_prot_t prot, int attr, unsigned int flags); | |
55e303ae A |
317 | |
318 | extern kern_return_t pmap_nest(pmap_t grand, pmap_t subord, addr64_t vstart, addr64_t nstart, uint64_t size); | |
91447636 | 319 | extern kern_return_t pmap_unnest(pmap_t grand, addr64_t vaddr); |
55e303ae | 320 | extern ppnum_t pmap_find_phys(pmap_t pmap, addr64_t va); |
91447636 A |
321 | extern void MapUserMemoryWindowInit(void); |
322 | extern addr64_t MapUserMemoryWindow(vm_map_t map, addr64_t va); | |
323 | extern boolean_t pmap_eligible_for_execute(ppnum_t pa); | |
324 | extern int pmap_list_resident_pages( | |
325 | struct pmap *pmap, | |
326 | vm_offset_t *listp, | |
327 | int space); | |
328 | extern void pmap_init_sharedpage(vm_offset_t cpg); | |
329 | extern void pmap_map_sharedpage(task_t task, pmap_t pmap); | |
330 | extern void pmap_unmap_sharedpage(pmap_t pmap); | |
5d5c5d0d A |
331 | extern void pmap_disable_NX(pmap_t pmap); |
332 | /* Not required for ppc: */ | |
333 | static inline void pmap_set_4GB_pagezero(__unused pmap_t pmap) {} | |
334 | static inline void pmap_clear_4GB_pagezero(__unused pmap_t pmap) {} | |
91447636 A |
335 | |
336 | ||
1c79356b A |
337 | |
338 | #endif /* _PPC_PMAP_H_ */ | |
339 |