]>
Commit | Line | Data |
---|---|---|
b94c3ac9 AB |
1 | /******************************************************************************\r |
2 | * arch-arm.h\r | |
3 | *\r | |
4 | * Guest OS interface to ARM Xen.\r | |
5 | *\r | |
6f21d772 | 6 | * SPDX-License-Identifier: MIT\r |
b94c3ac9 AB |
7 | *\r |
8 | * Copyright 2011 (C) Citrix Systems\r | |
9 | */\r | |
10 | \r | |
11 | #ifndef __XEN_PUBLIC_ARCH_ARM_H__\r | |
12 | #define __XEN_PUBLIC_ARCH_ARM_H__\r | |
13 | \r | |
14 | /*\r | |
15 | * `incontents 50 arm_abi Hypercall Calling Convention\r | |
16 | *\r | |
17 | * A hypercall is issued using the ARM HVC instruction.\r | |
18 | *\r | |
19 | * A hypercall can take up to 5 arguments. These are passed in\r | |
20 | * registers, the first argument in x0/r0 (for arm64/arm32 guests\r | |
21 | * respectively irrespective of whether the underlying hypervisor is\r | |
22 | * 32- or 64-bit), the second argument in x1/r1, the third in x2/r2,\r | |
23 | * the forth in x3/r3 and the fifth in x4/r4.\r | |
24 | *\r | |
25 | * The hypercall number is passed in r12 (arm) or x16 (arm64). In both\r | |
26 | * cases the relevant ARM procedure calling convention specifies this\r | |
27 | * is an inter-procedure-call scratch register (e.g. for use in linker\r | |
28 | * stubs). This use does not conflict with use during a hypercall.\r | |
29 | *\r | |
30 | * The HVC ISS must contain a Xen specific TAG: XEN_HYPERCALL_TAG.\r | |
31 | *\r | |
32 | * The return value is in x0/r0.\r | |
33 | *\r | |
34 | * The hypercall will clobber x16/r12 and the argument registers used\r | |
35 | * by that hypercall (except r0 which is the return value) i.e. in\r | |
36 | * addition to x16/r12 a 2 argument hypercall will clobber x1/r1 and a\r | |
37 | * 4 argument hypercall will clobber x1/r1, x2/r2 and x3/r3.\r | |
38 | *\r | |
39 | * Parameter structs passed to hypercalls are laid out according to\r | |
40 | * the Procedure Call Standard for the ARM Architecture (AAPCS, AKA\r | |
41 | * EABI) and Procedure Call Standard for the ARM 64-bit Architecture\r | |
42 | * (AAPCS64). Where there is a conflict the 64-bit standard should be\r | |
43 | * used regardless of guest type. Structures which are passed as\r | |
44 | * hypercall arguments are always little endian.\r | |
45 | *\r | |
46 | * All memory which is shared with other entities in the system\r | |
47 | * (including the hypervisor and other guests) must reside in memory\r | |
48 | * which is mapped as Normal Inner-cacheable. This applies to:\r | |
49 | * - hypercall arguments passed via a pointer to guest memory.\r | |
50 | * - memory shared via the grant table mechanism (including PV I/O\r | |
51 | * rings etc).\r | |
52 | * - memory shared with the hypervisor (struct shared_info, struct\r | |
53 | * vcpu_info, the grant table, etc).\r | |
54 | *\r | |
55 | * Any Inner cache allocation strategy (Write-Back, Write-Through etc)\r | |
56 | * is acceptable. There is no restriction on the Outer-cacheability.\r | |
57 | */\r | |
58 | \r | |
59 | /*\r | |
60 | * `incontents 55 arm_hcall Supported Hypercalls\r | |
61 | *\r | |
62 | * Xen on ARM makes extensive use of hardware facilities and therefore\r | |
63 | * only a subset of the potential hypercalls are required.\r | |
64 | *\r | |
65 | * Since ARM uses second stage paging any machine/physical addresses\r | |
66 | * passed to hypercalls are Guest Physical Addresses (Intermediate\r | |
67 | * Physical Addresses) unless otherwise noted.\r | |
68 | *\r | |
69 | * The following hypercalls (and sub operations) are supported on the\r | |
70 | * ARM platform. Other hypercalls should be considered\r | |
71 | * unavailable/unsupported.\r | |
72 | *\r | |
73 | * HYPERVISOR_memory_op\r | |
74 | * All generic sub-operations.\r | |
75 | *\r | |
76 | * In addition the following arch specific sub-ops:\r | |
77 | * * XENMEM_add_to_physmap\r | |
78 | * * XENMEM_add_to_physmap_batch\r | |
79 | *\r | |
80 | * HYPERVISOR_domctl\r | |
81 | * All generic sub-operations, with the exception of:\r | |
82 | * * XEN_DOMCTL_iomem_permission (not yet implemented)\r | |
83 | * * XEN_DOMCTL_irq_permission (not yet implemented)\r | |
84 | *\r | |
85 | * HYPERVISOR_sched_op\r | |
86 | * All generic sub-operations, with the exception of:\r | |
87 | * * SCHEDOP_block -- prefer wfi hardware instruction\r | |
88 | *\r | |
89 | * HYPERVISOR_console_io\r | |
90 | * All generic sub-operations\r | |
91 | *\r | |
92 | * HYPERVISOR_xen_version\r | |
93 | * All generic sub-operations\r | |
94 | *\r | |
95 | * HYPERVISOR_event_channel_op\r | |
96 | * All generic sub-operations\r | |
97 | *\r | |
98 | * HYPERVISOR_physdev_op\r | |
99 | * No sub-operations are currenty supported\r | |
100 | *\r | |
101 | * HYPERVISOR_sysctl\r | |
102 | * All generic sub-operations, with the exception of:\r | |
103 | * * XEN_SYSCTL_page_offline_op\r | |
104 | * * XEN_SYSCTL_get_pmstat\r | |
105 | * * XEN_SYSCTL_pm_op\r | |
106 | *\r | |
107 | * HYPERVISOR_hvm_op\r | |
108 | * Exactly these sub-operations are supported:\r | |
109 | * * HVMOP_set_param\r | |
110 | * * HVMOP_get_param\r | |
111 | *\r | |
112 | * HYPERVISOR_grant_table_op\r | |
113 | * All generic sub-operations\r | |
114 | *\r | |
115 | * HYPERVISOR_vcpu_op\r | |
116 | * Exactly these sub-operations are supported:\r | |
117 | * * VCPUOP_register_vcpu_info\r | |
118 | * * VCPUOP_register_runstate_memory_area\r | |
119 | *\r | |
120 | *\r | |
121 | * Other notes on the ARM ABI:\r | |
122 | *\r | |
123 | * - struct start_info is not exported to ARM guests.\r | |
124 | *\r | |
125 | * - struct shared_info is mapped by ARM guests using the\r | |
126 | * HYPERVISOR_memory_op sub-op XENMEM_add_to_physmap, passing\r | |
127 | * XENMAPSPACE_shared_info as space parameter.\r | |
128 | *\r | |
129 | * - All the per-cpu struct vcpu_info are mapped by ARM guests using the\r | |
130 | * HYPERVISOR_vcpu_op sub-op VCPUOP_register_vcpu_info, including cpu0\r | |
131 | * struct vcpu_info.\r | |
132 | *\r | |
133 | * - The grant table is mapped using the HYPERVISOR_memory_op sub-op\r | |
134 | * XENMEM_add_to_physmap, passing XENMAPSPACE_grant_table as space\r | |
135 | * parameter. The memory range specified under the Xen compatible\r | |
136 | * hypervisor node on device tree can be used as target gpfn for the\r | |
137 | * mapping.\r | |
138 | *\r | |
139 | * - Xenstore is initialized by using the two hvm_params\r | |
140 | * HVM_PARAM_STORE_PFN and HVM_PARAM_STORE_EVTCHN. They can be read\r | |
141 | * with the HYPERVISOR_hvm_op sub-op HVMOP_get_param.\r | |
142 | *\r | |
143 | * - The paravirtualized console is initialized by using the two\r | |
144 | * hvm_params HVM_PARAM_CONSOLE_PFN and HVM_PARAM_CONSOLE_EVTCHN. They\r | |
145 | * can be read with the HYPERVISOR_hvm_op sub-op HVMOP_get_param.\r | |
146 | *\r | |
147 | * - Event channel notifications are delivered using the percpu GIC\r | |
148 | * interrupt specified under the Xen compatible hypervisor node on\r | |
149 | * device tree.\r | |
150 | *\r | |
151 | * - The device tree Xen compatible node is fully described under Linux\r | |
152 | * at Documentation/devicetree/bindings/arm/xen.txt.\r | |
153 | */\r | |
154 | \r | |
bc0f20c1 | 155 | #define XEN_HYPERCALL_TAG 0xEA1\r |
b94c3ac9 AB |
156 | \r |
157 | #define uint64_aligned_t UINT64 __attribute__((aligned(8)))\r | |
158 | \r | |
159 | #ifndef __ASSEMBLY__\r | |
160 | #define ___DEFINE_XEN_GUEST_HANDLE(name, type) \\r | |
161 | typedef union { type *p; unsigned long q; } \\r | |
162 | __guest_handle_ ## name; \\r | |
163 | typedef union { type *p; uint64_aligned_t q; } \\r | |
164 | __guest_handle_64_ ## name;\r | |
165 | \r | |
166 | /*\r | |
167 | * XEN_GUEST_HANDLE represents a guest pointer, when passed as a field\r | |
168 | * in a struct in memory. On ARM is always 8 bytes sizes and 8 bytes\r | |
169 | * aligned.\r | |
170 | * XEN_GUEST_HANDLE_PARAM represent a guest pointer, when passed as an\r | |
171 | * hypercall argument. It is 4 bytes on aarch and 8 bytes on aarch64.\r | |
172 | */\r | |
173 | #define __DEFINE_XEN_GUEST_HANDLE(name, type) \\r | |
174 | ___DEFINE_XEN_GUEST_HANDLE(name, type); \\r | |
175 | ___DEFINE_XEN_GUEST_HANDLE(const_##name, const type)\r | |
176 | #define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, name)\r | |
177 | #define __XEN_GUEST_HANDLE(name) __guest_handle_64_ ## name\r | |
178 | #define XEN_GUEST_HANDLE(name) __XEN_GUEST_HANDLE(name)\r | |
179 | /* this is going to be changed on 64 bit */\r | |
180 | #define XEN_GUEST_HANDLE_PARAM(name) __guest_handle_ ## name\r | |
181 | #define set_xen_guest_handle_raw(hnd, val) \\r | |
182 | do { \\r | |
183 | typeof(&(hnd)) _sxghr_tmp = &(hnd); \\r | |
184 | _sxghr_tmp->q = 0; \\r | |
185 | _sxghr_tmp->p = val; \\r | |
186 | } while ( 0 )\r | |
187 | #ifdef __XEN_TOOLS__\r | |
188 | #define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0)\r | |
189 | #endif\r | |
190 | #define set_xen_guest_handle(hnd, val) set_xen_guest_handle_raw(hnd, val)\r | |
191 | \r | |
192 | #if defined(__GNUC__) && !defined(__STRICT_ANSI__)\r | |
193 | /* Anonymous union includes both 32- and 64-bit names (e.g., r0/x0). */\r | |
194 | # define __DECL_REG(n64, n32) union { \\r | |
195 | UINT64 n64; \\r | |
196 | UINT32 n32; \\r | |
197 | }\r | |
198 | #else\r | |
199 | /* Non-gcc sources must always use the proper 64-bit name (e.g., x0). */\r | |
200 | #define __DECL_REG(n64, n32) UINT64 n64\r | |
201 | #endif\r | |
202 | \r | |
203 | struct vcpu_guest_core_regs\r | |
204 | {\r | |
205 | /* Aarch64 Aarch32 */\r | |
206 | __DECL_REG(x0, r0_usr);\r | |
207 | __DECL_REG(x1, r1_usr);\r | |
208 | __DECL_REG(x2, r2_usr);\r | |
209 | __DECL_REG(x3, r3_usr);\r | |
210 | __DECL_REG(x4, r4_usr);\r | |
211 | __DECL_REG(x5, r5_usr);\r | |
212 | __DECL_REG(x6, r6_usr);\r | |
213 | __DECL_REG(x7, r7_usr);\r | |
214 | __DECL_REG(x8, r8_usr);\r | |
215 | __DECL_REG(x9, r9_usr);\r | |
216 | __DECL_REG(x10, r10_usr);\r | |
217 | __DECL_REG(x11, r11_usr);\r | |
218 | __DECL_REG(x12, r12_usr);\r | |
219 | \r | |
220 | __DECL_REG(x13, sp_usr);\r | |
221 | __DECL_REG(x14, lr_usr);\r | |
222 | \r | |
223 | __DECL_REG(x15, __unused_sp_hyp);\r | |
224 | \r | |
225 | __DECL_REG(x16, lr_irq);\r | |
226 | __DECL_REG(x17, sp_irq);\r | |
227 | \r | |
228 | __DECL_REG(x18, lr_svc);\r | |
229 | __DECL_REG(x19, sp_svc);\r | |
230 | \r | |
231 | __DECL_REG(x20, lr_abt);\r | |
232 | __DECL_REG(x21, sp_abt);\r | |
233 | \r | |
234 | __DECL_REG(x22, lr_und);\r | |
235 | __DECL_REG(x23, sp_und);\r | |
236 | \r | |
237 | __DECL_REG(x24, r8_fiq);\r | |
238 | __DECL_REG(x25, r9_fiq);\r | |
239 | __DECL_REG(x26, r10_fiq);\r | |
240 | __DECL_REG(x27, r11_fiq);\r | |
241 | __DECL_REG(x28, r12_fiq);\r | |
242 | \r | |
243 | __DECL_REG(x29, sp_fiq);\r | |
244 | __DECL_REG(x30, lr_fiq);\r | |
245 | \r | |
246 | /* Return address and mode */\r | |
247 | __DECL_REG(pc64, pc32); /* ELR_EL2 */\r | |
248 | UINT32 cpsr; /* SPSR_EL2 */\r | |
249 | \r | |
250 | union {\r | |
251 | UINT32 spsr_el1; /* AArch64 */\r | |
252 | UINT32 spsr_svc; /* AArch32 */\r | |
253 | };\r | |
254 | \r | |
255 | /* AArch32 guests only */\r | |
256 | UINT32 spsr_fiq, spsr_irq, spsr_und, spsr_abt;\r | |
257 | \r | |
258 | /* AArch64 guests only */\r | |
259 | UINT64 sp_el0;\r | |
260 | UINT64 sp_el1, elr_el1;\r | |
261 | };\r | |
262 | typedef struct vcpu_guest_core_regs vcpu_guest_core_regs_t;\r | |
263 | DEFINE_XEN_GUEST_HANDLE(vcpu_guest_core_regs_t);\r | |
264 | \r | |
265 | #undef __DECL_REG\r | |
266 | \r | |
267 | typedef UINT64 xen_pfn_t;\r | |
268 | #define PRI_xen_pfn PRIx64\r | |
269 | \r | |
270 | /* Maximum number of virtual CPUs in legacy multi-processor guests. */\r | |
271 | /* Only one. All other VCPUS must use VCPUOP_register_vcpu_info */\r | |
272 | #define XEN_LEGACY_MAX_VCPUS 1\r | |
273 | \r | |
274 | typedef UINT64 xen_ulong_t;\r | |
275 | #define PRI_xen_ulong PRIx64\r | |
276 | \r | |
277 | #if defined(__XEN__) || defined(__XEN_TOOLS__)\r | |
278 | struct vcpu_guest_context {\r | |
279 | #define _VGCF_online 0\r | |
280 | #define VGCF_online (1<<_VGCF_online)\r | |
281 | UINT32 flags; /* VGCF_* */\r | |
282 | \r | |
283 | struct vcpu_guest_core_regs user_regs; /* Core CPU registers */\r | |
284 | \r | |
285 | UINT32 sctlr;\r | |
286 | UINT64 ttbcr, ttbr0, ttbr1;\r | |
287 | };\r | |
288 | typedef struct vcpu_guest_context vcpu_guest_context_t;\r | |
289 | DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);\r | |
290 | #endif\r | |
291 | \r | |
292 | struct arch_vcpu_info {\r | |
293 | };\r | |
294 | typedef struct arch_vcpu_info arch_vcpu_info_t;\r | |
295 | \r | |
296 | struct arch_shared_info {\r | |
297 | };\r | |
298 | typedef struct arch_shared_info arch_shared_info_t;\r | |
299 | typedef UINT64 xen_callback_t;\r | |
300 | \r | |
301 | #endif\r | |
302 | \r | |
303 | #if defined(__XEN__) || defined(__XEN_TOOLS__)\r | |
304 | \r | |
305 | /* PSR bits (CPSR, SPSR)*/\r | |
306 | \r | |
307 | #define PSR_THUMB (1<<5) /* Thumb Mode enable */\r | |
308 | #define PSR_FIQ_MASK (1<<6) /* Fast Interrupt mask */\r | |
309 | #define PSR_IRQ_MASK (1<<7) /* Interrupt mask */\r | |
310 | #define PSR_ABT_MASK (1<<8) /* Asynchronous Abort mask */\r | |
311 | #define PSR_BIG_ENDIAN (1<<9) /* arm32: Big Endian Mode */\r | |
312 | #define PSR_DBG_MASK (1<<9) /* arm64: Debug Exception mask */\r | |
313 | #define PSR_IT_MASK (0x0600fc00) /* Thumb If-Then Mask */\r | |
314 | #define PSR_JAZELLE (1<<24) /* Jazelle Mode */\r | |
315 | \r | |
316 | /* 32 bit modes */\r | |
317 | #define PSR_MODE_USR 0x10\r | |
318 | #define PSR_MODE_FIQ 0x11\r | |
319 | #define PSR_MODE_IRQ 0x12\r | |
320 | #define PSR_MODE_SVC 0x13\r | |
321 | #define PSR_MODE_MON 0x16\r | |
322 | #define PSR_MODE_ABT 0x17\r | |
323 | #define PSR_MODE_HYP 0x1a\r | |
324 | #define PSR_MODE_UND 0x1b\r | |
325 | #define PSR_MODE_SYS 0x1f\r | |
326 | \r | |
327 | /* 64 bit modes */\r | |
328 | #define PSR_MODE_BIT 0x10 /* Set iff AArch32 */\r | |
329 | #define PSR_MODE_EL3h 0x0d\r | |
330 | #define PSR_MODE_EL3t 0x0c\r | |
331 | #define PSR_MODE_EL2h 0x09\r | |
332 | #define PSR_MODE_EL2t 0x08\r | |
333 | #define PSR_MODE_EL1h 0x05\r | |
334 | #define PSR_MODE_EL1t 0x04\r | |
335 | #define PSR_MODE_EL0t 0x00\r | |
336 | \r | |
337 | #define PSR_GUEST32_INIT (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC)\r | |
338 | #define PSR_GUEST64_INIT (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_EL1h)\r | |
339 | \r | |
340 | #define SCTLR_GUEST_INIT 0x00c50078\r | |
341 | \r | |
342 | /*\r | |
343 | * Virtual machine platform (memory layout, interrupts)\r | |
344 | *\r | |
345 | * These are defined for consistency between the tools and the\r | |
346 | * hypervisor. Guests must not rely on these hardcoded values but\r | |
347 | * should instead use the FDT.\r | |
348 | */\r | |
349 | \r | |
350 | /* Physical Address Space */\r | |
351 | \r | |
352 | /* vGIC mappings: Only one set of mapping is used by the guest.\r | |
353 | * Therefore they can overlap.\r | |
354 | */\r | |
355 | \r | |
356 | /* vGIC v2 mappings */\r | |
357 | #define GUEST_GICD_BASE 0x03001000ULL\r | |
358 | #define GUEST_GICD_SIZE 0x00001000ULL\r | |
359 | #define GUEST_GICC_BASE 0x03002000ULL\r | |
360 | #define GUEST_GICC_SIZE 0x00000100ULL\r | |
361 | \r | |
362 | /* vGIC v3 mappings */\r | |
363 | #define GUEST_GICV3_GICD_BASE 0x03001000ULL\r | |
364 | #define GUEST_GICV3_GICD_SIZE 0x00010000ULL\r | |
365 | \r | |
366 | #define GUEST_GICV3_RDIST_STRIDE 0x20000ULL\r | |
367 | #define GUEST_GICV3_RDIST_REGIONS 1\r | |
368 | \r | |
369 | #define GUEST_GICV3_GICR0_BASE 0x03020000ULL /* vCPU0 - vCPU7 */\r | |
370 | #define GUEST_GICV3_GICR0_SIZE 0x00100000ULL\r | |
371 | \r | |
372 | /* 16MB == 4096 pages reserved for guest to use as a region to map its\r | |
373 | * grant table in.\r | |
374 | */\r | |
375 | #define GUEST_GNTTAB_BASE 0x38000000ULL\r | |
376 | #define GUEST_GNTTAB_SIZE 0x01000000ULL\r | |
377 | \r | |
378 | #define GUEST_MAGIC_BASE 0x39000000ULL\r | |
379 | #define GUEST_MAGIC_SIZE 0x01000000ULL\r | |
380 | \r | |
381 | #define GUEST_RAM_BANKS 2\r | |
382 | \r | |
383 | #define GUEST_RAM0_BASE 0x40000000ULL /* 3GB of low RAM @ 1GB */\r | |
384 | #define GUEST_RAM0_SIZE 0xc0000000ULL\r | |
385 | \r | |
386 | #define GUEST_RAM1_BASE 0x0200000000ULL /* 1016GB of RAM @ 8GB */\r | |
387 | #define GUEST_RAM1_SIZE 0xfe00000000ULL\r | |
388 | \r | |
389 | #define GUEST_RAM_BASE GUEST_RAM0_BASE /* Lowest RAM address */\r | |
390 | /* Largest amount of actual RAM, not including holes */\r | |
391 | #define GUEST_RAM_MAX (GUEST_RAM0_SIZE + GUEST_RAM1_SIZE)\r | |
392 | /* Suitable for e.g. const uint64_t ramfoo[] = GUEST_RAM_BANK_FOOS; */\r | |
393 | #define GUEST_RAM_BANK_BASES { GUEST_RAM0_BASE, GUEST_RAM1_BASE }\r | |
394 | #define GUEST_RAM_BANK_SIZES { GUEST_RAM0_SIZE, GUEST_RAM1_SIZE }\r | |
395 | \r | |
396 | /* Interrupts */\r | |
397 | #define GUEST_TIMER_VIRT_PPI 27\r | |
398 | #define GUEST_TIMER_PHYS_S_PPI 29\r | |
399 | #define GUEST_TIMER_PHYS_NS_PPI 30\r | |
400 | #define GUEST_EVTCHN_PPI 31\r | |
401 | \r | |
402 | /* PSCI functions */\r | |
403 | #define PSCI_cpu_suspend 0\r | |
404 | #define PSCI_cpu_off 1\r | |
405 | #define PSCI_cpu_on 2\r | |
406 | #define PSCI_migrate 3\r | |
407 | \r | |
408 | #endif\r | |
409 | \r | |
410 | #endif /* __XEN_PUBLIC_ARCH_ARM_H__ */\r | |
411 | \r | |
412 | /*\r | |
413 | * Local variables:\r | |
414 | * mode: C\r | |
415 | * c-file-style: "BSD"\r | |
416 | * c-basic-offset: 4\r | |
417 | * tab-width: 4\r | |
418 | * indent-tabs-mode: nil\r | |
419 | * End:\r | |
420 | */\r |