]> git.saurik.com Git - apple/xnu.git/blob - osfmk/ppc/vmachmon.h
0fe82d921767efa7a5443efa2db181215747bc02
[apple/xnu.git] / osfmk / ppc / vmachmon.h
1 /*
2 * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_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. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 /*-----------------------------------------------------------------------
24 ** vmachmon.h
25 **
26 ** C routines that we are adding to the MacOS X kernel.
27 **
28 -----------------------------------------------------------------------*/
29
30 #include <ppc/exception.h>
31
32 #ifndef _VEMULATION_H_
33 #define _VEMULATION_H_
34
35 /*************************************************************************************
36 External Emulation Types
37 **************************************************************************************/
38
39 typedef union vmm_vector_register_t {
40 unsigned long i[4];
41 unsigned short s[8];
42 unsigned char b[16];
43 } vmm_vector_register_t;
44
45 typedef union vmm_fp_register_t {
46 double d;
47 unsigned long i[2];
48 unsigned short s[4];
49 unsigned char b[8];
50 } vmm_fp_register_t;
51
52
53 typedef struct vmm_regs32_t {
54
55 unsigned long ppcPC; /* 000 */
56 unsigned long ppcMSR; /* 004 */
57
58 unsigned long ppcGPRs[32]; /* 008 */
59
60 unsigned long ppcCR; /* 088 */
61 unsigned long ppcXER; /* 08C */
62 unsigned long ppcLR; /* 090 */
63 unsigned long ppcCTR; /* 094 */
64 unsigned long ppcMQ; /* 098 - Obsolete */
65 unsigned long ppcVRSave; /* 09C */
66 unsigned long ppcRsrvd0A0[40]; /* 0A0 */
67 /* 140 */
68 } vmm_regs32_t;
69
70 #pragma pack(4) /* Make sure the structure stays as we defined it */
71 typedef struct vmm_regs64_t {
72
73 unsigned long long ppcPC; /* 000 */
74 unsigned long long ppcMSR; /* 008 */
75
76 unsigned long long ppcGPRs[32]; /* 010 */
77
78 unsigned long long ppcXER; /* 110 */
79 unsigned long long ppcLR; /* 118 */
80 unsigned long long ppcCTR; /* 120 */
81 unsigned long ppcCR; /* 128 */
82 unsigned long ppcVRSave; /* 12C */
83 unsigned long ppcRsvd130[4]; /* 130 */
84 /* 140 */
85 } vmm_regs64_t;
86 #pragma pack()
87
88
89 #pragma pack(4) /* Make sure the structure stays as we defined it */
90 typedef union vmm_regs_t {
91 vmm_regs32_t ppcRegs32;
92 vmm_regs64_t ppcRegs64;
93 } vmm_regs_t;
94 #pragma pack()
95
96 #pragma pack(4) /* Make sure the structure stays as we defined it */
97 typedef struct vmm_processor_state_t {
98 /* 32-byte bndry */
99 vmm_regs_t ppcRegs; /* Define registers areas */
100
101 /* We must be 16-byte aligned here */
102
103 vmm_vector_register_t ppcVRs[32]; /* These are only valid after a kVmmGetVectorState */
104 vmm_vector_register_t ppcVSCR; /* This is always loaded/saved at host/guest transition */
105
106 /* We must be 8-byte aligned here */
107
108 vmm_fp_register_t ppcFPRs[32]; /* These are only valid after a kVmmGetFloatState */
109 vmm_fp_register_t ppcFPSCR; /* This is always loaded/saved at host/guest transition */
110 unsigned long ppcReserved2[2]; /* Pad out to multiple of 16 bytes */
111 } vmm_processor_state_t;
112 #pragma pack()
113
114 typedef unsigned long vmm_return_code_t;
115
116 typedef unsigned long vmm_thread_index_t;
117 #define vmmTInum 0x000000FF
118 #define vmmTIadsp 0x0000FF00
119 typedef unsigned long vmm_adsp_id_t;
120
121 enum {
122 kVmmCurMajorVersion = 0x0001,
123 kVmmCurMinorVersion = 0x0007,
124 kVmmMinMajorVersion = 0x0001,
125 };
126 #define kVmmCurrentVersion ((kVmmCurMajorVersion << 16) | kVmmCurMinorVersion)
127
128 typedef unsigned long vmm_features_t;
129 enum {
130 kVmmFeature_LittleEndian = 0x00000001,
131 kVmmFeature_Stop = 0x00000002,
132 kVmmFeature_ExtendedMapping = 0x00000004,
133 kVmmFeature_ListMapping = 0x00000008,
134 kVmmFeature_FastAssist = 0x00000010,
135 kVmmFeature_XA = 0x00000020,
136 kVmmFeature_SixtyFourBit = 0x00000040,
137 kVmmFeature_MultAddrSpace = 0x00000080,
138 kVmmFeature_GuestShadowAssist = 0x00000100, /* Guest->physical shadow hash table */
139 kVmmFeature_GlobalMappingAssist = 0x00000200, /* Global shadow mapping support */
140 kVmmFeature_HostShadowAssist = 0x00000400, /* Linear shadow mapping of an area of
141 host virtual as guest physical */
142 kVmmFeature_MultAddrSpaceAssist = 0x00000800, /* Expanded pool of guest virtual
143 address spaces */
144 };
145 #define kVmmCurrentFeatures (kVmmFeature_LittleEndian | kVmmFeature_Stop | kVmmFeature_ExtendedMapping \
146 | kVmmFeature_ListMapping | kVmmFeature_FastAssist | kVmmFeature_XA \
147 | kVmmFeature_GuestShadowAssist)
148
149 enum {
150 vmm64Bit = 0x80000000, /* Make guest 64-bit */
151 vmmGSA = 0x40000000, /* Enable guest shadow assist (GSA) */
152 vmmGMA = 0x20000000, /* Enable global shadow mapping assist (GMA) */
153 };
154
155 #define kVmmSupportedSetXA (vmm64Bit | vmmGSA | vmmGMA)
156
157 typedef unsigned long vmm_version_t;
158
159 typedef struct vmm_ret_parms32_t {
160 unsigned long return_params[4];
161 } vmm_ret_parms32_t;
162
163 typedef struct vmm_ret_parms64_t {
164 unsigned long long return_params[4];
165 } vmm_ret_parms64_t;
166
167 #pragma pack(4) /* Make sure the structure stays as we defined it */
168 typedef union vmm_ret_parms_t {
169 vmm_ret_parms64_t vmmrp64; /* 64-bit flavor */
170 vmm_ret_parms32_t vmmrp32; /* 32-bit flavor */
171 unsigned int retgas[11]; /* Force this to be 11 words long */
172 } vmm_ret_parms_t;
173 #pragma pack()
174
175 #pragma pack(4) /* Make sure the structure stays as we defined it */
176 typedef struct vmm_fastassist_state32_t {
177 unsigned long fastassist_dispatch;
178 unsigned long fastassist_refcon;
179
180 unsigned long fastassist_dispatch_code;
181 unsigned long fastassist_parameter[5];
182
183 unsigned long guest_register[8];
184
185 unsigned long guest_pc;
186 unsigned long guest_msr;
187
188 unsigned long fastassist_intercepts;
189 unsigned long fastassist_reserved1;
190 } vmm_fastassist_state32_t;
191
192 typedef struct vmm_fastassist_state64_t {
193 unsigned long long fastassist_dispatch;
194 unsigned long long fastassist_refcon;
195
196 unsigned long long fastassist_dispatch_code;
197 unsigned long long fastassist_parameter[5];
198
199 unsigned long long guest_register[8];
200
201 unsigned long long guest_pc;
202 unsigned long long guest_msr;
203
204 unsigned long fastassist_intercepts;
205 unsigned long fastassist_reserved1;
206 } vmm_fastassist_state64_t;
207
208 typedef union vmm_fastassist_state_t {
209 vmm_fastassist_state64_t vmmfs64; /* 64-bit flavor */
210 vmm_fastassist_state32_t vmmfs32; /* 32-bit flavor */
211 } vmm_fastassist_state_t;
212 #pragma pack()
213
214 #pragma pack(4) /* Make sure the structure stays as we defined it */
215 typedef struct vmm_state_page_t {
216 /* This structure must remain below 4Kb (one page) in size */
217 vmm_version_t interface_version;
218 vmm_thread_index_t thread_index;
219 unsigned int vmmStat; /* Note: this field is identical to vmmFlags in vmmCntrlEntry */
220 unsigned int vmmCntrl;
221 #define vmmFloatLoad 0x80000000
222 #define vmmFloatLoadb 0
223 #define vmmVectLoad 0x40000000
224 #define vmmVectLoadb 1
225 #define vmmVectVRall 0x20000000
226 #define vmmVectVRallb 2
227 #define vmmVectVAss 0x10000000
228 #define vmmVectVAssb 3
229 #define vmmXStart 0x08000000
230 #define vmmXStartb 4
231 #define vmmKey 0x04000000
232 #define vmmKeyb 5
233 #define vmmFamEna 0x02000000
234 #define vmmFamEnab 6
235 #define vmmFamSet 0x01000000
236 #define vmmFamSetb 7
237
238 vmm_return_code_t return_code;
239 vmm_ret_parms_t vmmRet;
240
241 /* The next portion of the structure must remain 32-byte aligned */
242 vmm_processor_state_t vmm_proc_state;
243
244 /* The next portion of the structure must remain 16-byte aligned */
245 vmm_fastassist_state_t vmm_fastassist_state;
246
247 } vmm_state_page_t;
248 #pragma pack()
249
250 #pragma pack(4) /* Make sure the structure stays as we defined it */
251 typedef struct vmm_comm_page_t {
252 union {
253 vmm_state_page_t vmcpState; /* Reserve area for state */
254 unsigned int vmcpPad[768]; /* Reserve space for 3/4 page state area */
255 } vmcpfirst;
256 unsigned int vmcpComm[256]; /* Define last 1024 bytes as a communications area - function specific */
257 } vmm_comm_page_t;
258 #pragma pack()
259
260 enum {
261 /* Function Indices (passed in r3) */
262 kVmmGetVersion = 0, /* Get VMM system version */
263 kVmmvGetFeatures, /* Get VMM supported features */
264 kVmmInitContext, /* Initialize a context */
265 kVmmTearDownContext, /* Destroy a context */
266 kVmmTearDownAll, /* Destory all contexts */
267 kVmmMapPage, /* Map a host to guest address space */
268 kVmmGetPageMapping, /* Get host address of a guest page */
269 kVmmUnmapPage, /* Unmap a guest page */
270 kVmmUnmapAllPages, /* Unmap all pages in a guest address space */
271 kVmmGetPageDirtyFlag, /* Check if guest page modified */
272 kVmmGetFloatState, /* Retrieve guest floating point context */
273 kVmmGetVectorState, /* Retrieve guest vector context */
274 kVmmSetTimer, /* Set a guest timer */
275 kVmmGetTimer, /* Get a guest timer */
276 kVmmExecuteVM, /* Launch a guest */
277 kVmmProtectPage, /* Set protection attributes for a guest page */
278 kVmmMapExecute, /* Map guest page and launch */
279 kVmmProtectExecute, /* Set prot attributes and launch */
280 kVmmMapList, /* Map a list of pages into guest address spaces */
281 kVmmUnmapList, /* Unmap a list of pages from guest address spaces */
282 kvmmExitToHost, /* Exit from FAM to host -- fast-path syscall */
283 kvmmResumeGuest, /* Resume guest from FAM -- fast-path syscall */
284 kvmmGetGuestRegister, /* Get guest register from FAM -- fast-path syscall */
285 kvmmSetGuestRegister, /* Set guest register from FAM -- fast-path syscall */
286
287 kVmmActivateXA, /* Activate extended architecture features for a VM */
288 kVmmDeactivateXA, /* Deactivate extended architecture features for a VM */
289 kVmmGetXA, /* Get extended architecture features from a VM */
290
291 kVmmMapPage64, /* Map a host to guest address space - supports 64-bit */
292 kVmmGetPageMapping64, /* Get host address of a guest page - supports 64-bit */
293 kVmmUnmapPage64, /* Unmap a guest page - supports 64-bit */
294 kVmmGetPageDirtyFlag64, /* Check if guest page modified - supports 64-bit */
295 kVmmProtectPage64, /* Set protection attributes for a guest page - supports 64-bit */
296 kVmmMapExecute64, /* Map guest page and launch - supports 64-bit */
297 kVmmProtectExecute64, /* Set prot attributes and launch - supports 64-bit */
298 kVmmMapList64, /* Map a list of pages into guest address spaces - supports 64-bit */
299 kVmmUnmapList64, /* Unmap a list of pages from guest address spaces - supports 64-bit */
300 kVmmMaxAddr, /* Returns the maximum virtual address that is mappable */
301
302 kVmmSetGuestMemory, /* Sets base and extent of guest physical memory in host address space */
303 kVmmPurgeLocal, /* Purges all non-global mappings for a given guest address space */
304 };
305
306 #define kVmmReturnNull 0
307 #define kVmmBogusContext 1
308 #define kVmmStopped 2
309 #define kVmmReturnDataPageFault 3
310 #define kVmmReturnInstrPageFault 4
311 #define kVmmReturnAlignmentFault 6
312 #define kVmmReturnProgramException 7
313 #define kVmmReturnSystemCall 12
314 #define kVmmReturnTraceException 13
315 #define kVmmAltivecAssist 22
316 #define kVmmInvalidAddress 0x1000
317 #define kVmmInvalidAdSpace 0x1001
318
319 /*
320 * Notes on guest address spaces.
321 *
322 * Address spaces are loosely coupled to virtual machines. The default is for
323 * a guest with an index of 1 to use address space 1, 2 to use 2, etc. However,
324 * any guest may be launched using any address space and any address space may be the
325 * target for a map or unmap function. Note that the (un)map list functions may pass in
326 * an address space ID on a page-by-page basis.
327 *
328 * An address space is instantiated either explicitly by mapping something into it, or
329 * implicitly by launching a guest with it.
330 *
331 * An address space is destroyed explicitly by kVmmTearDownAll or kVmmUnmapAllPages. It is
332 * destroyed implicitly by kVmmTearDownContext. The latter is done in order to remain
333 * backwards compatible with the previous implementation, which does not have decoupled
334 * guests and address spaces.
335 *
336 * An address space supports the maximum virtual address supported by the processor.
337 * The 64-bit variant of the mapping functions can be used on non-64-bit machines. If an
338 * unmappable address (e.g., an address larger than 4GB-1 on a 32-bit machine) is requested,
339 * the operation fails with a kVmmInvalidAddress return code.
340 *
341 * Note that for 64-bit calls, both host and guest are specified at 64-bit values.
342 *
343 */
344
345
346
347
348 /*
349 * Storage Extended Protection modes
350 * Notes:
351 * To keep compatibility, vmmKey and the PPC key have reversed meanings,
352 * i.e., vmmKey 0 is PPC key 1 and vice versa.
353 *
354 * vmmKey Notes
355 * Mode 0 1
356 *
357 * kVmmProtNARW not accessible read/write VM_PROT_NONE (not settable via VM calls)
358 * kVmmProtRORW read only read/write
359 * kVmmProtRWRW read/write read/write VM_PROT_WRITE or (VM_PROT_WRITE | VM_PROT_READ)
360 * kVmmProtRORO read only read only VM_PROT_READ
361
362 */
363
364 #define kVmmProtXtnd 0x00000008
365 #define kVmmProtNARW (kVmmProtXtnd | 0x00000000)
366 #define kVmmProtRORW (kVmmProtXtnd | 0x00000001)
367 #define kVmmProtRWRW (kVmmProtXtnd | 0x00000002)
368 #define kVmmProtRORO (kVmmProtXtnd | 0x00000003)
369
370 /*
371 * Map list formats
372 * The last 12 bits in the guest virtual address is used as flags as follows:
373 * 0x007 - for the map calls, this is the key to set
374 * 0x3F0 - for both map and unmap, this is the address space ID upon which to operate.
375 * Note that if 0, the address space ID from the function call is used instead.
376 */
377
378 typedef struct vmmMList {
379 unsigned int vmlva; /* Virtual address in host address space */
380 unsigned int vmlava; /* Virtual address in guest address space */
381 } vmmMList;
382
383 typedef struct vmmMList64 {
384 unsigned long long vmlva; /* Virtual address in host address space */
385 unsigned long long vmlava; /* Virtual address in guest address space */
386 } vmmMList64;
387
388 typedef struct vmmUMList {
389 unsigned int vmlava; /* Virtual address in guest address space */
390 } vmmUMList;
391
392 typedef struct vmmUMList64 {
393 unsigned long long vmlava; /* Virtual address in guest address space */
394 } vmmUMList64;
395
396 #define vmmlFlgs 0x00000FFF /* Flags passed in in vmlava low order 12 bits */
397 #define vmmlProt 0x00000007 /* Protection flags for the page */
398 #define vmmlAdID 0x000003F0 /* Guest address space ID - used only if non-zero */
399 #define vmmlGlob 0x00000400 /* Mapping is global */
400 #define vmmlRsvd 0x00000800 /* Reserved for future */
401
402 /*************************************************************************************
403 Internal Emulation Types
404 **************************************************************************************/
405
406 #define kVmmMaxContexts 32
407 #define kVmmMaxUnmapPages 64
408 #define kVmmMaxMapPages 64
409
410 #pragma pack(4) /* Make sure the structure stays as we defined it */
411 typedef struct vmmCntrlEntry { /* Virtual Machine Monitor control table entry */
412 unsigned int vmmFlags; /* Assorted control flags */
413 #define vmmInUse 0x80000000
414 #define vmmInUseb 0
415 #define vmmFloatCngd 0x40000000
416 #define vmmFloatCngdb 1
417 #define vmmVectCngd 0x20000000
418 #define vmmVectCngdb 2
419 #define vmmTimerPop 0x10000000
420 #define vmmTimerPopb 3
421 #define vmmFAMmode 0x04000000
422 #define vmmFAMmodeb 5
423 #define vmmXStop 0x00800000
424 #define vmmXStopb 8
425 #define vmmSpfSave 0x000000FF
426 #define vmmSpfSaveb 24
427 unsigned int vmmXAFlgs; /* Extended Architecture flags */
428 vmm_state_page_t *vmmContextKern; /* Kernel address of context communications area */
429 ppnum_t vmmContextPhys; /* Physical address of context communications area */
430 vmm_state_page_t *vmmContextUser; /* User address of context communications area */
431 facility_context vmmFacCtx; /* Header for vector and floating point contexts */
432 pmap_t vmmPmap; /* Last dispatched pmap */
433 uint64_t vmmTimer; /* Last set timer value. Zero means unset */
434 unsigned int vmmFAMintercept; /* FAM intercepted exceptions */
435 } vmmCntrlEntry;
436 #pragma pack()
437
438 #pragma pack(4) /* Make sure the structure stays as we defined it */
439 typedef struct vmmCntrlTable { /* Virtual Machine Monitor Control table */
440 unsigned int vmmGFlags; /* Global flags */
441 #define vmmLastAdSp 0xFF /* Remember the address space that was mapped last */
442 addr64_t vmmLastMap; /* Last vaddr mapping made */
443 vmmCntrlEntry vmmc[kVmmMaxContexts]; /* One entry for each possible Virtual Machine Monitor context */
444 pmap_t vmmAdsp[kVmmMaxContexts]; /* Guest address space pmaps */
445 } vmmCntrlTable;
446 #pragma pack()
447
448 /* function decls for kernel level routines... */
449 extern void vmm_execute_vm(thread_t act, vmm_thread_index_t index);
450 extern kern_return_t vmm_tear_down_context(thread_t act, vmm_thread_index_t index);
451 extern kern_return_t vmm_get_float_state(thread_t act, vmm_thread_index_t index);
452 extern kern_return_t vmm_get_vector_state(thread_t act, vmm_thread_index_t index);
453 extern kern_return_t vmm_set_timer(thread_t act, vmm_thread_index_t index, unsigned int timerhi, unsigned int timerlo);
454 extern kern_return_t vmm_get_timer(thread_t act, vmm_thread_index_t index);
455 extern void vmm_tear_down_all(thread_t act);
456 extern kern_return_t vmm_map_page(thread_t act, vmm_thread_index_t hindex, addr64_t cva,
457 addr64_t ava, vm_prot_t prot);
458 extern vmm_return_code_t vmm_map_execute(thread_t act, vmm_thread_index_t hindex, addr64_t cva,
459 addr64_t ava, vm_prot_t prot);
460 extern kern_return_t vmm_protect_page(thread_t act, vmm_thread_index_t hindex, addr64_t va,
461 vm_prot_t prot);
462 extern vmm_return_code_t vmm_protect_execute(thread_t act, vmm_thread_index_t hindex, addr64_t va,
463 vm_prot_t prot);
464 extern addr64_t vmm_get_page_mapping(thread_t act, vmm_thread_index_t index,
465 addr64_t va);
466 extern kern_return_t vmm_unmap_page(thread_t act, vmm_thread_index_t index, addr64_t va);
467 extern void vmm_unmap_all_pages(thread_t act, vmm_thread_index_t index);
468 extern boolean_t vmm_get_page_dirty_flag(thread_t act, vmm_thread_index_t index,
469 addr64_t va, unsigned int reset);
470 extern kern_return_t vmm_activate_XA(thread_t act, vmm_thread_index_t index, unsigned int xaflags);
471 extern kern_return_t vmm_deactivate_XA(thread_t act, vmm_thread_index_t index, unsigned int xaflags);
472 extern unsigned int vmm_get_XA(thread_t act, vmm_thread_index_t index);
473 extern int vmm_get_features(struct savearea *);
474 extern int vmm_get_version(struct savearea *);
475 extern int vmm_init_context(struct savearea *);
476 extern int vmm_dispatch(struct savearea *);
477 extern int vmm_exit(thread_t act, struct savearea *);
478 extern void vmm_force_exit(thread_t act, struct savearea *);
479 extern int vmm_stop_vm(struct savearea *save);
480 extern void vmm_timer_pop(thread_t act);
481 extern void vmm_interrupt(ReturnHandler *rh, thread_t act);
482 extern kern_return_t vmm_map_list(thread_t act, vmm_thread_index_t index, unsigned int cnt, unsigned int flavor);
483 extern kern_return_t vmm_unmap_list(thread_t act, vmm_thread_index_t index, unsigned int cnt, unsigned int flavor);
484 extern vmm_return_code_t vmm_resume_guest(vmm_thread_index_t index, unsigned long pc,
485 unsigned long vmmCntrl, unsigned long vmmCntrMaskl);
486 extern vmm_return_code_t vmm_exit_to_host(vmm_thread_index_t index);
487 extern unsigned long vmm_get_guest_register(vmm_thread_index_t index, unsigned long reg_index);
488 extern vmm_return_code_t vmm_set_guest_register(vmm_thread_index_t index, unsigned long reg_index, unsigned long reg_value);
489 extern addr64_t vmm_max_addr(thread_t act);
490 extern kern_return_t vmm_set_guest_memory(thread_t act, vmm_thread_index_t index, addr64_t base, addr64_t extent);
491 extern kern_return_t vmm_purge_local(thread_t act, vmm_thread_index_t index);
492
493 #endif