armv7: save vfp context (at least part of it)
authorAdam Turowski <adam.turowski@inf.ethz.ch>
Thu, 22 Jun 2017 14:00:21 +0000 (16:00 +0200)
committerAdam Turowski <adam.turowski@inf.ethz.ch>
Thu, 22 Jun 2017 14:00:21 +0000 (16:00 +0200)
Signed-off-by: Adam Turowski <adam.turowski@inf.ethz.ch>

hake/ARMv7.hs
include/arch/arm/barrelfish_kpi/registers_arch.h
kernel/arch/armv7/exceptions.S
lib/barrelfish/arch/arm/dispatch.c

index d88b3ae..71c6847 100644 (file)
@@ -118,6 +118,7 @@ kernelCFlags = [ Str s | s <- [ "-fno-builtin",
                                 "-marm",
                                 "-mcpu=cortex-a9",
                                 "-march=armv7-a",
+                                "-mfpu=vfpv3",
                                 "-mapcs",
                                 "-mabi=aapcs-linux",
                                 "-mfloat-abi=hard",
index 5c6a150..b464afb 100644 (file)
@@ -42,7 +42,7 @@
 #define LR_REG   15
 #define PC_REG   16
 
-#define NUM_REGS 17            /* cpsr, r0-r15 */
+#define NUM_REGS 82            /* cpsr, r0-r15 */
 #define NUM_FPU_REGS 0
 #define ARCH_NUMREGS NUM_REGS
 
@@ -72,6 +72,11 @@ union registers_arm {
         uint32_t stack;
         uint32_t link;
         uint32_t pc;
+        uint32_t _align;
+        uint64_t d0, d1, d2, d3, d4, d5, d6, d7;
+        uint64_t d8, d9, d10, d11, d12, d13, d14, d15;
+        uint64_t d16, d17, d18, d19, d20, d21, d22, d23;
+        uint64_t d24, d25, d26, d27, d28, d29, d30, d31;
     } named;
     struct registers_arm_syscall_args {
         uint32_t cpsr;
@@ -88,7 +93,7 @@ union registers_arm {
     uint32_t regs[sizeof(struct registers_arm_named) / sizeof(uint32_t)];
 };
 
-STATIC_ASSERT_SIZEOF(union registers_arm, 17 * 4);
+STATIC_ASSERT_SIZEOF(union registers_arm, (17 + 64 + 1) * 4);
 
 ///< Opaque handle for the register state
 typedef union registers_arm arch_registers_state_t;
index 7f6cede..543fc43 100644 (file)
     .endif
     str     \spsr_reg, [\context, #(CPSR_REG * 4)]
     str     lr, [\context, #(PC_REG * 4)]
-    add     \spsr_reg, \context, #(LR_REG * 4)
-    stmda   \spsr_reg, {r4-r14}^
+    add     \spsr_reg, \context, #(R4_REG * 4)
+    stmia   \spsr_reg!, {r4-r14}^
+    add     \spsr_reg, #8
+    vstmia  \spsr_reg!, {d0-d15}
+    vstmia  \spsr_reg!, {d16-d31}
     add     \spsr_reg, \context, #(R3_REG * 4)
     pop     {r4-r7}                         // Pop spilled scratch registers
     stmda   \spsr_reg!, {r4-r7}             // And Save them
@@ -450,8 +453,8 @@ do_resume:
     // LDR = read word from memory
     //        target register
     //        /   use register containing "regs" as base register
-    //       /   /           post index: only base register is used for
-    //      /   /           /   addressing and the offset added afterwards
+    //       /   /     post index: only base register is used for
+    //      /   /     /   addressing and the offset added afterwards
     ldr    lr, [r0], #4
     // set SPSR to value of lr == regs.cpsr
     // restore cpsr
@@ -468,7 +471,11 @@ do_resume:
     // Restore the user stack pointer and link register.  n.b. LR is
     // banked in SVC mode, so *our* LR isn't affected.  Also, this can't
     // write back, so we've got to add the offset ourselves.
-    ldmia  lr, {r13,r14}^
+    add lr, #5*4
+    vldmia lr!, {d0-d15}
+    vldmia lr, {d16-d31}
+    sub lr, #(5+32)*4
+    ldmia  lr, {r13, r14}^
     // Load the (banked SVC) LR with the return address (add the offset
     // that the last ldmia couldn't).
     ldr    lr, [lr, #8]
index 6195eab..555b74f 100644 (file)
@@ -42,7 +42,7 @@ void __attribute__ ((visibility ("hidden"))) disp_save_rm_kcb_epilog(void);
 //
 
 STATIC_ASSERT(CPSR_REG == 0,  "broken context assumption");
-STATIC_ASSERT(NUM_REGS == 17, "broken context assumption");
+STATIC_ASSERT(NUM_REGS == 82, "broken context assumption");
 STATIC_ASSERT(PC_REG   == 16, "broken context assumption");