Commit | Line | Data |
---|---|---|
1c79356b A |
1 | /* |
2 | * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
de355530 A |
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. | |
1c79356b | 11 | * |
de355530 A |
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 | |
1c79356b A |
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
de355530 A |
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. | |
1c79356b A |
19 | * |
20 | * @APPLE_LICENSE_HEADER_END@ | |
21 | */ | |
22 | /*----------------------------------------------------------------------- | |
23 | ** vmachmon.h | |
24 | ** | |
25 | ** C routines that we are adding to the MacOS X kernel. | |
26 | ** | |
de355530 A |
27 | ** Wierd Apple PSL stuff goes here... |
28 | ** | |
29 | ** Until then, Copyright 2000, Connectix | |
30 | ** | |
1c79356b A |
31 | -----------------------------------------------------------------------*/ |
32 | ||
33 | #include <ppc/exception.h> | |
34 | ||
35 | #ifndef _VEMULATION_H_ | |
36 | #define _VEMULATION_H_ | |
37 | ||
38 | /************************************************************************************* | |
39 | External Emulation Types | |
40 | **************************************************************************************/ | |
41 | ||
42 | typedef union vmm_vector_register_t { | |
43 | unsigned long i[4]; | |
44 | unsigned short s[8]; | |
45 | unsigned char b[16]; | |
46 | } vmm_vector_register_t; | |
47 | ||
48 | typedef union vmm_fp_register_t { | |
49 | double d; | |
50 | unsigned long i[2]; | |
51 | unsigned short s[4]; | |
52 | unsigned char b[8]; | |
53 | } vmm_fp_register_t; | |
54 | ||
de355530 | 55 | typedef struct vmm_processor_state_t { |
9bccf70c | 56 | |
de355530 A |
57 | unsigned long ppcPC; |
58 | unsigned long ppcMSR; | |
d7e50217 | 59 | |
de355530 | 60 | unsigned long ppcGPRs[32]; |
d7e50217 | 61 | |
de355530 A |
62 | unsigned long ppcCR; |
63 | unsigned long ppcXER; | |
64 | unsigned long ppcLR; | |
65 | unsigned long ppcCTR; | |
66 | unsigned long ppcMQ; /* Obsolete */ | |
67 | unsigned long ppcVRSave; | |
d7e50217 | 68 | /* 32-byte bndry */ |
de355530 A |
69 | vmm_vector_register_t ppcVSCR; |
70 | vmm_fp_register_t ppcFPSCR; | |
71 | ||
72 | unsigned long ppcReserved1[34]; /* Future processor state can go here */ | |
1c79356b A |
73 | |
74 | /* We must be 16-byte aligned here */ | |
75 | ||
de355530 A |
76 | vmm_vector_register_t ppcVRs[32]; |
77 | vmm_vector_register_t ppcVSCRshadow; | |
1c79356b A |
78 | |
79 | /* We must be 8-byte aligned here */ | |
80 | ||
de355530 A |
81 | vmm_fp_register_t ppcFPRs[32]; |
82 | vmm_fp_register_t ppcFPSCRshadow; | |
1c79356b A |
83 | unsigned long ppcReserved2[2]; /* Pad out to multiple of 16 bytes */ |
84 | } vmm_processor_state_t; | |
85 | ||
86 | typedef unsigned long vmm_return_code_t; | |
87 | ||
88 | typedef unsigned long vmm_thread_index_t; | |
0b4e3aa0 | 89 | |
1c79356b | 90 | enum { |
0b4e3aa0 | 91 | kVmmCurMajorVersion = 0x0001, |
de355530 | 92 | kVmmCurMinorVersion = 0x0005, |
0b4e3aa0 | 93 | kVmmMinMajorVersion = 0x0001, |
1c79356b | 94 | }; |
0b4e3aa0 | 95 | #define kVmmCurrentVersion ((kVmmCurMajorVersion << 16) | kVmmCurMinorVersion) |
1c79356b A |
96 | |
97 | typedef unsigned long vmm_features_t; | |
98 | enum { | |
0b4e3aa0 A |
99 | kVmmFeature_LittleEndian = 0x00000001, |
100 | kVmmFeature_Stop = 0x00000002, | |
101 | kVmmFeature_ExtendedMapping = 0x00000004, | |
9bccf70c | 102 | kVmmFeature_ListMapping = 0x00000008, |
d7e50217 | 103 | kVmmFeature_FastAssist = 0x00000010, |
1c79356b | 104 | }; |
de355530 A |
105 | #define kVmmCurrentFeatures (kVmmFeature_LittleEndian | \ |
106 | kVmmFeature_Stop | \ | |
107 | kVmmFeature_ExtendedMapping | \ | |
108 | kVmmFeature_ListMapping | \ | |
109 | kVmmFeature_FastAssist) | |
d7e50217 | 110 | |
1c79356b A |
111 | |
112 | typedef unsigned long vmm_version_t; | |
113 | ||
de355530 | 114 | typedef struct vmm_fastassist_state_t { |
d7e50217 A |
115 | unsigned long fastassist_dispatch; |
116 | unsigned long fastassist_refcon; | |
117 | ||
118 | unsigned long fastassist_dispatch_code; | |
119 | unsigned long fastassist_parameter[5]; | |
120 | ||
121 | unsigned long guest_register[8]; | |
122 | ||
123 | unsigned long guest_pc; | |
124 | unsigned long guest_msr; | |
125 | ||
126 | unsigned long fastassist_intercepts; | |
127 | unsigned long fastassist_reserved1; | |
d7e50217 | 128 | } vmm_fastassist_state_t; |
d7e50217 | 129 | |
1c79356b A |
130 | typedef struct vmm_state_page_t { |
131 | /* This structure must remain below 4Kb (one page) in size */ | |
132 | vmm_version_t interface_version; | |
133 | vmm_thread_index_t thread_index; | |
134 | unsigned int vmmStat; /* Note: this field is identical to vmmFlags in vmmCntrlEntry */ | |
135 | unsigned int vmmCntrl; | |
136 | #define vmmFloatLoad 0x80000000 | |
137 | #define vmmFloatLoadb 0 | |
138 | #define vmmVectLoad 0x40000000 | |
139 | #define vmmVectLoadb 1 | |
140 | #define vmmVectVRall 0x20000000 | |
141 | #define vmmVectVRallb 2 | |
142 | #define vmmVectVAss 0x10000000 | |
143 | #define vmmVectVAssb 3 | |
0b4e3aa0 A |
144 | #define vmmXStart 0x08000000 |
145 | #define vmmXStartb 4 | |
146 | #define vmmKey 0x04000000 | |
147 | #define vmmKeyb 5 | |
d7e50217 A |
148 | #define vmmFamEna 0x02000000 |
149 | #define vmmFamEnab 6 | |
150 | #define vmmFamSet 0x01000000 | |
151 | #define vmmFamSetb 7 | |
152 | ||
1c79356b | 153 | vmm_return_code_t return_code; |
de355530 A |
154 | unsigned long return_params[4]; |
155 | unsigned long gas[7]; /* For alignment */ | |
1c79356b A |
156 | |
157 | /* The next portion of the structure must remain 32-byte aligned */ | |
158 | vmm_processor_state_t vmm_proc_state; | |
159 | ||
d7e50217 A |
160 | /* The next portion of the structure must remain 16-byte aligned */ |
161 | vmm_fastassist_state_t vmm_fastassist_state; | |
162 | ||
1c79356b A |
163 | } vmm_state_page_t; |
164 | ||
9bccf70c A |
165 | typedef struct vmm_comm_page_t { |
166 | union { | |
167 | vmm_state_page_t vmcpState; /* Reserve area for state */ | |
168 | unsigned int vmcpPad[768]; /* Reserve space for 3/4 page state area */ | |
169 | } vmcpfirst; | |
170 | unsigned int vmcpComm[256]; /* Define last 1024 bytes as a communications area - function specific */ | |
171 | } vmm_comm_page_t; | |
172 | ||
1c79356b A |
173 | enum { |
174 | /* Function Indices (passed in r3) */ | |
de355530 A |
175 | kVmmGetVersion = 0, |
176 | kVmmvGetFeatures, | |
177 | kVmmInitContext, | |
178 | kVmmTearDownContext, | |
179 | kVmmTearDownAll, | |
180 | kVmmMapPage, | |
181 | kVmmGetPageMapping, | |
182 | kVmmUnmapPage, | |
183 | kVmmUnmapAllPages, | |
184 | kVmmGetPageDirtyFlag, | |
185 | kVmmGetFloatState, | |
186 | kVmmGetVectorState, | |
187 | kVmmSetTimer, | |
188 | kVmmGetTimer, | |
189 | kVmmExecuteVM, | |
190 | kVmmProtectPage, | |
191 | kVmmMapExecute, | |
192 | kVmmProtectExecute, | |
193 | kVmmMapList, | |
194 | kVmmUnmapList, | |
d7e50217 A |
195 | kvmmExitToHost, |
196 | kvmmResumeGuest, | |
197 | kvmmGetGuestRegister, | |
198 | kvmmSetGuestRegister, | |
1c79356b A |
199 | }; |
200 | ||
201 | #define kVmmReturnNull 0 | |
202 | #define kVmmBogusContext 1 | |
0b4e3aa0 | 203 | #define kVmmStopped 2 |
1c79356b A |
204 | #define kVmmReturnDataPageFault 3 |
205 | #define kVmmReturnInstrPageFault 4 | |
206 | #define kVmmReturnAlignmentFault 6 | |
207 | #define kVmmReturnProgramException 7 | |
208 | #define kVmmReturnSystemCall 12 | |
209 | #define kVmmReturnTraceException 13 | |
210 | #define kVmmAltivecAssist 22 | |
de355530 | 211 | #define kVmmInvalidAddress 4096 |
1c79356b | 212 | |
0b4e3aa0 A |
213 | /* |
214 | * Storage Extended Protection modes | |
215 | * Notes: | |
216 | * To keep compatibility, vmmKey and the PPC key have reversed meanings, | |
217 | * i.e., vmmKey 0 is PPC key 1 and vice versa. | |
218 | * | |
219 | * vmmKey Notes | |
220 | * Mode 0 1 | |
221 | * | |
222 | * kVmmProtNARW not accessible read/write VM_PROT_NONE (not settable via VM calls) | |
223 | * kVmmProtRORW read only read/write | |
224 | * kVmmProtRWRW read/write read/write VM_PROT_WRITE or (VM_PROT_WRITE | VM_PROT_READ) | |
225 | * kVmmProtRORO read only read only VM_PROT_READ | |
226 | ||
227 | */ | |
228 | ||
229 | #define kVmmProtXtnd 0x00000008 | |
230 | #define kVmmProtNARW (kVmmProtXtnd | 0x00000000) | |
231 | #define kVmmProtRORW (kVmmProtXtnd | 0x00000001) | |
232 | #define kVmmProtRWRW (kVmmProtXtnd | 0x00000002) | |
233 | #define kVmmProtRORO (kVmmProtXtnd | 0x00000003) | |
1c79356b | 234 | |
9bccf70c | 235 | /* |
de355530 | 236 | * Map list format |
9bccf70c A |
237 | */ |
238 | ||
de355530 A |
239 | typedef struct vmmMapList { |
240 | unsigned int vmlva; /* Virtual address in emulator address space */ | |
241 | unsigned int vmlava; /* Virtual address in alternate address space */ | |
242 | #define vmlFlgs 0x00000FFF /* Flags passed in in vmlava low order 12 bits */ | |
243 | #define vmlProt 0x00000003 /* Protection flags for the page */ | |
244 | } vmmMapList; | |
9bccf70c A |
245 | |
246 | ||
1c79356b A |
247 | /************************************************************************************* |
248 | Internal Emulation Types | |
249 | **************************************************************************************/ | |
250 | ||
de355530 | 251 | #define kVmmMaxContextsPerThread 32 |
9bccf70c A |
252 | #define kVmmMaxUnmapPages 64 |
253 | #define kVmmMaxMapPages 64 | |
1c79356b | 254 | |
1c79356b A |
255 | typedef struct vmmCntrlEntry { /* Virtual Machine Monitor control table entry */ |
256 | unsigned int vmmFlags; /* Assorted control flags */ | |
257 | #define vmmInUse 0x80000000 | |
258 | #define vmmInUseb 0 | |
259 | #define vmmFloatCngd 0x40000000 | |
260 | #define vmmFloatCngdb 1 | |
261 | #define vmmVectCngd 0x20000000 | |
262 | #define vmmVectCngdb 2 | |
263 | #define vmmTimerPop 0x10000000 | |
264 | #define vmmTimerPopb 3 | |
de355530 A |
265 | #define vmmMapDone 0x08000000 |
266 | #define vmmMapDoneb 4 | |
d7e50217 A |
267 | #define vmmFAMmode 0x04000000 |
268 | #define vmmFAMmodeb 5 | |
0b4e3aa0 A |
269 | #define vmmXStop 0x00800000 |
270 | #define vmmXStopb 8 | |
1c79356b A |
271 | #define vmmSpfSave 0x000000FF |
272 | #define vmmSpfSaveb 24 | |
de355530 | 273 | pmap_t vmmPmap; /* pmap for alternate context's view of task memory */ |
1c79356b | 274 | vmm_state_page_t *vmmContextKern; /* Kernel address of context communications area */ |
de355530 | 275 | vmm_state_page_t *vmmContextPhys; /* Physical address of context communications area */ |
1c79356b | 276 | vmm_state_page_t *vmmContextUser; /* User address of context communications area */ |
9bccf70c | 277 | facility_context vmmFacCtx; /* Header for vector and floating point contexts */ |
0b4e3aa0 | 278 | uint64_t vmmTimer; /* Last set timer value. Zero means unset */ |
de355530 | 279 | vm_offset_t vmmLastMap; /* Last vaddr mapping into virtual machine */ |
d7e50217 | 280 | unsigned int vmmFAMintercept; /* FAM intercepted exceptions */ |
1c79356b A |
281 | } vmmCntrlEntry; |
282 | ||
283 | typedef struct vmmCntrlTable { /* Virtual Machine Monitor Control table */ | |
de355530 | 284 | vmmCntrlEntry vmmc[kVmmMaxContextsPerThread]; /* One entry for each possible Virtual Machine Monitor context */ |
1c79356b A |
285 | } vmmCntrlTable; |
286 | ||
287 | /* function decls for kernel level routines... */ | |
0b4e3aa0 | 288 | extern void vmm_execute_vm(thread_act_t act, vmm_thread_index_t index); |
1c79356b A |
289 | extern vmmCntrlEntry *vmm_get_entry(thread_act_t act, vmm_thread_index_t index); |
290 | extern kern_return_t vmm_tear_down_context(thread_act_t act, vmm_thread_index_t index); | |
291 | extern kern_return_t vmm_get_float_state(thread_act_t act, vmm_thread_index_t index); | |
292 | extern kern_return_t vmm_get_vector_state(thread_act_t act, vmm_thread_index_t index); | |
293 | extern kern_return_t vmm_set_timer(thread_act_t act, vmm_thread_index_t index, unsigned int timerhi, unsigned int timerlo); | |
294 | extern kern_return_t vmm_get_timer(thread_act_t act, vmm_thread_index_t index); | |
295 | extern void vmm_tear_down_all(thread_act_t act); | |
de355530 A |
296 | extern kern_return_t vmm_map_page(thread_act_t act, vmm_thread_index_t hindex, vm_offset_t cva, |
297 | vm_offset_t ava, vm_prot_t prot); | |
298 | extern vmm_return_code_t vmm_map_execute(thread_act_t act, vmm_thread_index_t hindex, vm_offset_t cva, | |
299 | vm_offset_t ava, vm_prot_t prot); | |
300 | extern kern_return_t vmm_protect_page(thread_act_t act, vmm_thread_index_t hindex, vm_offset_t va, | |
0b4e3aa0 | 301 | vm_prot_t prot); |
de355530 | 302 | extern vmm_return_code_t vmm_protect_execute(thread_act_t act, vmm_thread_index_t hindex, vm_offset_t va, |
0b4e3aa0 | 303 | vm_prot_t prot); |
de355530 A |
304 | extern vm_offset_t vmm_get_page_mapping(thread_act_t act, vmm_thread_index_t index, |
305 | vm_offset_t va); | |
306 | extern kern_return_t vmm_unmap_page(thread_act_t act, vmm_thread_index_t index, vm_offset_t va); | |
1c79356b A |
307 | extern void vmm_unmap_all_pages(thread_act_t act, vmm_thread_index_t index); |
308 | extern boolean_t vmm_get_page_dirty_flag(thread_act_t act, vmm_thread_index_t index, | |
de355530 | 309 | vm_offset_t va, unsigned int reset); |
1c79356b A |
310 | extern int vmm_get_features(struct savearea *); |
311 | extern int vmm_get_version(struct savearea *); | |
312 | extern int vmm_init_context(struct savearea *); | |
313 | extern int vmm_dispatch(struct savearea *); | |
314 | extern int vmm_exit(thread_act_t act, struct savearea *); | |
315 | extern void vmm_force_exit(thread_act_t act, struct savearea *); | |
0b4e3aa0 A |
316 | extern int vmm_stop_vm(struct savearea *save); |
317 | extern void vmm_timer_pop(thread_act_t act); | |
318 | extern void vmm_interrupt(ReturnHandler *rh, thread_act_t act); | |
de355530 A |
319 | extern kern_return_t vmm_map_list(thread_act_t act, vmm_thread_index_t index, unsigned int cnt); |
320 | extern kern_return_t vmm_unmap_list(thread_act_t act, vmm_thread_index_t index, unsigned int cnt); | |
d7e50217 A |
321 | extern vmm_return_code_t vmm_resume_guest(vmm_thread_index_t index, unsigned long pc, |
322 | unsigned long vmmCntrl, unsigned long vmmCntrMaskl); | |
323 | extern vmm_return_code_t vmm_exit_to_host(vmm_thread_index_t index); | |
324 | extern unsigned long vmm_get_guest_register(vmm_thread_index_t index, unsigned long reg_index); | |
325 | extern vmm_return_code_t vmm_set_guest_register(vmm_thread_index_t index, unsigned long reg_index, unsigned long reg_value); | |
1c79356b A |
326 | |
327 | #endif | |
328 |