aboutsummaryrefslogtreecommitdiffstats
path: root/xen/include/public
diff options
context:
space:
mode:
authorIan Campbell <ian.campbell@citrix.com>2013-02-22 08:58:03 +0000
committerIan Campbell <ian.campbell@citrix.com>2013-02-22 12:14:53 +0000
commit1c38a1e937d39d3f6079667bfb6e8ff877eddbde (patch)
tree168a0f74572069e862dae30ccce6335ed7d44b0f /xen/include/public
parenta51b368b64943196f86f444c45b1c5c61b148d1a (diff)
downloadxen-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.h115
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);