diff options
author | Ian Campbell <ian.campbell@citrix.com> | 2013-02-22 08:58:03 +0000 |
---|---|---|
committer | Ian Campbell <ian.campbell@citrix.com> | 2013-02-22 12:14:53 +0000 |
commit | 1c38a1e937d39d3f6079667bfb6e8ff877eddbde (patch) | |
tree | 168a0f74572069e862dae30ccce6335ed7d44b0f /xen/include/public | |
parent | a51b368b64943196f86f444c45b1c5c61b148d1a (diff) | |
download | xen-1c38a1e937d39d3f6079667bfb6e8ff877eddbde.tar.gz xen-1c38a1e937d39d3f6079667bfb6e8ff877eddbde.tar.bz2 xen-1c38a1e937d39d3f6079667bfb6e8ff877eddbde.zip |
xen: arm: separate guest user regs from internal guest state.
struct cpu_user_regs is currently used as both internal state
(specifically at the base of the stack) and a guest/toolstack
visible API (via struct vcpu_guest_context used by
XEN_DOMCTL_{g,s}etvcpucontext and VCPUOP_initialise).
This causes problems when we want to make the API 64-bit clean since
we don't really want to change the size of the on-stack struct.
So split into vcpu_guest_core_regs which is the API facing struct
and keep cpu_user_regs purely internal, translate between the two.
In the user API arrange for both 64- and 32-bit registers to be
included in a layout which does not differ depending on toolstack
architecture. Also switch to using the more formal banked register
names (e.g. with the _usr suffix) for clarity.
This is an ABI change. Note that the kernel doesn't currently use
this data structure so it affects the tools interface only.
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Tim Deegan <tim@xen.org>
Diffstat (limited to 'xen/include/public')
-rw-r--r-- | xen/include/public/arch-arm.h | 115 |
1 files changed, 70 insertions, 45 deletions
diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h index 5306f7989f..3333399622 100644 --- a/xen/include/public/arch-arm.h +++ b/xen/include/public/arch-arm.h @@ -86,55 +86,80 @@ #endif #define set_xen_guest_handle(hnd, val) set_xen_guest_handle_raw(hnd, val) -struct cpu_user_regs -{ - uint32_t r0; - uint32_t r1; - uint32_t r2; - uint32_t r3; - uint32_t r4; - uint32_t r5; - uint32_t r6; - uint32_t r7; - uint32_t r8; - uint32_t r9; - uint32_t r10; - union { - uint32_t r11; - uint32_t fp; - }; - uint32_t r12; +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +/* Anonymous union includes both 32- and 64-bit names (e.g., r0/x0). */ +# define __DECL_REG(n64, n32) union { \ + uint64_t n64; \ + uint32_t n32; \ + } +#else +/* Non-gcc sources must always use the proper 64-bit name (e.g., x0). */ +#define __DECL_REG(n64, n32) uint64_t n64 +#endif - uint32_t sp; /* r13 - SP: Valid for Hyp. frames only, o/w banked (see below) */ +struct vcpu_guest_core_regs +{ + /* Aarch64 Aarch32 */ + __DECL_REG(x0, r0_usr); + __DECL_REG(x1, r1_usr); + __DECL_REG(x2, r2_usr); + __DECL_REG(x3, r3_usr); + __DECL_REG(x4, r4_usr); + __DECL_REG(x5, r5_usr); + __DECL_REG(x6, r6_usr); + __DECL_REG(x7, r7_usr); + __DECL_REG(x8, r8_usr); + __DECL_REG(x9, r9_usr); + __DECL_REG(x10, r10_usr); + __DECL_REG(x11, r11_usr); + __DECL_REG(x12, r12_usr); + + __DECL_REG(x13, sp_usr); + __DECL_REG(x14, lr_usr); + + __DECL_REG(x15, __unused_sp_hyp); + + __DECL_REG(x16, lr_irq); + __DECL_REG(x17, sp_irq); + + __DECL_REG(x18, lr_svc); + __DECL_REG(x19, sp_svc); + + __DECL_REG(x20, lr_abt); + __DECL_REG(x21, sp_abt); + + __DECL_REG(x22, lr_und); + __DECL_REG(x23, sp_und); + + __DECL_REG(x24, r8_fiq); + __DECL_REG(x25, r9_fiq); + __DECL_REG(x26, r10_fiq); + __DECL_REG(x27, r11_fiq); + __DECL_REG(x28, r12_fiq); + + __DECL_REG(x29, sp_fiq); + __DECL_REG(x30, lr_fiq); + + /* Return address and mode */ + __DECL_REG(pc64, pc32); /* ELR_EL2 */ + uint32_t cpsr; /* SPSR_EL2 */ - /* r14 - LR: is the same physical register as LR_usr */ union { - uint32_t lr; /* r14 - LR: Valid for Hyp. Same physical register as lr_usr. */ - uint32_t lr_usr; + uint32_t spsr_el1; /* AArch64 */ + uint32_t spsr_svc; /* AArch32 */ }; - uint32_t pc; /* Return IP */ - uint32_t cpsr; /* Return mode */ - uint32_t pad0; /* Doubleword-align the kernel half of the frame */ - - /* Outer guest frame only from here on... */ + /* AArch32 guests only */ + uint32_t spsr_fiq, spsr_irq, spsr_und, spsr_abt; - uint32_t sp_usr; /* LR_usr is the same register as LR, see above */ - - uint32_t sp_irq, lr_irq; - uint32_t sp_svc, lr_svc; - uint32_t sp_abt, lr_abt; - uint32_t sp_und, lr_und; - - uint32_t r8_fiq, r9_fiq, r10_fiq, r11_fiq, r12_fiq; - uint32_t sp_fiq, lr_fiq; - - uint32_t spsr_svc, spsr_abt, spsr_und, spsr_irq, spsr_fiq; - - uint32_t pad1; /* Doubleword-align the user half of the frame */ + /* AArch64 guests only */ + uint64_t sp_el0; + uint64_t sp_el1, elr_el1; }; -typedef struct cpu_user_regs cpu_user_regs_t; -DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t); +typedef struct vcpu_guest_core_regs vcpu_guest_core_regs_t; +DEFINE_XEN_GUEST_HANDLE(vcpu_guest_core_regs_t); + +#undef __DECL_REG typedef uint64_t xen_pfn_t; #define PRI_xen_pfn PRIx64 @@ -151,10 +176,10 @@ struct vcpu_guest_context { #define VGCF_online (1<<_VGCF_online) uint32_t flags; /* VGCF_* */ - struct cpu_user_regs user_regs; /* User-level CPU registers */ + struct vcpu_guest_core_regs user_regs; /* Core CPU registers */ - uint32_t sctlr; - uint32_t ttbr0, ttbr1, ttbcr; + uint32_t sctlr, ttbcr; + uint64_t ttbr0, ttbr1; }; typedef struct vcpu_guest_context vcpu_guest_context_t; DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t); |