[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Minios-devel] [PATCH v2 10/47] arm64: add exception support



This patch adds the exception support for arm64:
    .0) Add {arm32, arm64}/traps.h, and add new pt_regs{} for arm64.
    .1) Add save_registers/restore_registers which are based on FreeBSD code.
    .2) setup the vector table

Signed-off-by: Huang Shijie <shijie.huang@xxxxxxx>
---
 arch/arm/arm64/arm64.S    | 147 ++++++++++++++++++++++++++++++++++++++++++++++
 arch/arm/arm64/traps.c    |  16 +++++
 arch/arm/time.c           |   8 ++-
 include/arm/arm32/traps.h |  20 +++++++
 include/arm/arm64/traps.h |  27 +++++++++
 include/arm/traps.h       |  20 -------
 include/console.h         |   8 +++
 include/events.h          |   9 ++-
 include/hypervisor.h      |   7 +++
 xenbus/xenbus.c           |   8 +++
 10 files changed, 248 insertions(+), 22 deletions(-)
 create mode 100644 arch/arm/arm64/traps.c
 create mode 100644 include/arm/arm32/traps.h
 create mode 100644 include/arm/arm64/traps.h
 delete mode 100644 include/arm/traps.h

diff --git a/arch/arm/arm64/arm64.S b/arch/arm/arm64/arm64.S
index b454cc6..9eb7ea0 100644
--- a/arch/arm/arm64/arm64.S
+++ b/arch/arm/arm64/arm64.S
@@ -1,6 +1,7 @@
 #include "asm.h"
 #include <arch_limits.h>
 #include <arm64/pagetable.h>
+#include <arm64/traps.h>
 #include <xen/xen.h>
 
 /* This macro will use the x0/x1/x2/x16 */
@@ -101,6 +102,11 @@ ENTRY(_start)
     msr     ttbr0_el1, x0
     isb
 
+    /* Load the exception vectors */
+    ldr     x2, =vector_table
+    msr     vbar_el1, x2
+    isb
+
     /* Turning on MMU */
     tlbi    vmalle1
     dsb     nsh
@@ -284,3 +290,144 @@ _setup_idmap_pgtable:
     adr     x0, idmap_l0_pgtable
     dsb     sy
     ret
+
+/* The save_registers/restore_registers are based on the code in FreeBSD */
+.macro save_registers el
+       mov     x18, sp
+
+       sub     sp, sp, #(PT_REG_SIZE)
+
+       stp     x28, x29, [sp, #(PT_REG_X + 28 * 8)]
+       stp     x26, x27, [sp, #(PT_REG_X + 26 * 8)]
+       stp     x24, x25, [sp, #(PT_REG_X + 24 * 8)]
+       stp     x22, x23, [sp, #(PT_REG_X + 22 * 8)]
+       stp     x20, x21, [sp, #(PT_REG_X + 20 * 8)]
+       stp     x18, x19, [sp, #(PT_REG_X + 18 * 8)]
+       stp     x16, x17, [sp, #(PT_REG_X + 16 * 8)]
+       stp     x14, x15, [sp, #(PT_REG_X + 14 * 8)]
+       stp     x12, x13, [sp, #(PT_REG_X + 12 * 8)]
+       stp     x10, x11, [sp, #(PT_REG_X + 10 * 8)]
+       stp     x8,  x9,  [sp, #(PT_REG_X + 8  * 8)]
+       stp     x6,  x7,  [sp, #(PT_REG_X + 6  * 8)]
+       stp     x4,  x5,  [sp, #(PT_REG_X + 4  * 8)]
+       stp     x2,  x3,  [sp, #(PT_REG_X + 2  * 8)]
+       stp     x0,  x1,  [sp, #(PT_REG_X + 0  * 8)]
+
+       mrs     x10, elr_el1
+       mrs     x11, spsr_el1
+       mrs     x12, esr_el1
+.if \el == 0
+       mrs     x18, sp_el0
+.endif
+       str     x10, [sp, #(PT_REG_ELR)]
+       stp     w11, w12, [sp, #(PT_REG_SPSR)]
+       stp     x18, x30, [sp, #(PT_REG_SP)]
+.endm
+
+.macro restore_registers el
+       ldp     x18, x30, [sp, #(PT_REG_SP)]
+       ldp     x10, x11, [sp, #(PT_REG_ELR)]
+.if \el == 0
+       msr     sp_el0, x18
+.endif
+       msr     spsr_el1, x11
+       msr     elr_el1, x10
+
+       ldp     x0,  x1,  [sp, #(PT_REG_X + 0  * 8)]
+       ldp     x2,  x3,  [sp, #(PT_REG_X + 2  * 8)]
+       ldp     x4,  x5,  [sp, #(PT_REG_X + 4  * 8)]
+       ldp     x6,  x7,  [sp, #(PT_REG_X + 6  * 8)]
+       ldp     x8,  x9,  [sp, #(PT_REG_X + 8  * 8)]
+       ldp     x10, x11, [sp, #(PT_REG_X + 10 * 8)]
+       ldp     x12, x13, [sp, #(PT_REG_X + 12 * 8)]
+       ldp     x14, x15, [sp, #(PT_REG_X + 14 * 8)]
+       ldp     x16, x17, [sp, #(PT_REG_X + 16 * 8)]
+       ldp     x18, x19, [sp, #(PT_REG_X + 18 * 8)]
+       ldp     x20, x21, [sp, #(PT_REG_X + 20 * 8)]
+       ldp     x22, x23, [sp, #(PT_REG_X + 22 * 8)]
+       ldp     x24, x25, [sp, #(PT_REG_X + 24 * 8)]
+       ldp     x26, x27, [sp, #(PT_REG_X + 26 * 8)]
+       ldp     x28, x29, [sp, #(PT_REG_X + 28 * 8)]
+
+       mov     sp, x18
+        eret
+.endm
+
+    .globl IRQ_handler
+IRQ_handler:
+    .long 0x0
+
+    .align 6
+el1_sync:
+    save_registers 1
+    mov     x0, sp
+    mrs     x1, esr_el1;
+    mrs     x2, far_el1;
+    bl      do_sync
+    restore_registers 1
+
+    .align 6
+el1_irq:
+    save_registers 1
+    ldr     x0, IRQ_handler
+    blr     x0
+    restore_registers 1
+
+/* Bad Abort numbers */
+#define BAD_SYNC    0
+#define BAD_IRQ     1
+#define BAD_FIQ     2
+#define BAD_ERROR   3
+
+#define el_invalid(name, reason, el)  \
+    .align 6;                         \
+name##_invalid:                       \
+    save_registers  el;               \
+    mov     x0, sp;                   \
+    mov     x1, #(reason);            \
+    mrs     x2, esr_el1;              \
+    mrs     x3, far_el1;              \
+    b       do_bad_mode;              \
+ENDPROC(name##_invalid);              \
+
+el_invalid(el1_sync, BAD_SYNC, 1);
+el_invalid(el0_sync, BAD_SYNC, 0);
+el_invalid(el1_irq, BAD_IRQ, 1);
+el_invalid(el0_irq, BAD_IRQ, 0);
+el_invalid(el1_fiq, BAD_FIQ, 1);
+el_invalid(el0_fiq, BAD_FIQ, 0);
+el_invalid(el1_error, BAD_ERROR, 1);
+el_invalid(el0_error, BAD_ERROR, 0);
+
+    /* Exception vector entry */
+    .macro vector_entry label
+    .align  7
+    b       \label
+    .endm
+
+    .align  11
+ENTRY(vector_table)
+    /* Current Exception level with SP_EL0 */
+    vector_entry el1_sync_invalid         /* Synchronous EL1t       */
+    vector_entry el1_irq_invalid          /* IRQ EL1t               */
+    vector_entry el1_fiq_invalid          /* FIQ EL1t               */
+    vector_entry el1_error_invalid        /* Error EL1t             */
+
+    /* Current Exception level with SP_EL1 */
+    vector_entry el1_sync                 /* Synchronous EL1h       */
+    vector_entry el1_irq                  /* IRQ EL1h               */
+    vector_entry el1_fiq_invalid          /* FIQ EL1h               */
+    vector_entry el1_error_invalid        /* Error EL1h             */
+
+    /* Lower Exception level using AArch64 */
+    vector_entry el0_sync_invalid         /* Synchronous 64-bit EL0 */
+    vector_entry el0_irq_invalid          /* IRQ 64-bit EL0         */
+    vector_entry el0_fiq_invalid          /* FIQ 64-bit EL0         */
+    vector_entry el0_error_invalid        /* Error 64-bit EL0       */
+
+    /* Lower Exception level using AArch32 */
+    vector_entry el0_sync_invalid         /* Synchronous 32-bit EL0 */
+    vector_entry el0_irq_invalid          /* IRQ 32-bit EL0         */
+    vector_entry el0_fiq_invalid          /* FIQ 32-bit EL0         */
+    vector_entry el0_error_invalid        /* Error 32-bit EL0       */
+END(vector_table)
diff --git a/arch/arm/arm64/traps.c b/arch/arm/arm64/traps.c
new file mode 100644
index 0000000..62dd2e6
--- /dev/null
+++ b/arch/arm/arm64/traps.c
@@ -0,0 +1,16 @@
+#include <mini-os/os.h>
+#include <mini-os/arm64/traps.h>
+#include <console.h>
+
+void do_bad_mode(struct pt_regs *regs, int reason,
+                  unsigned long esr, unsigned long far)
+{
+    /* TO DO */
+    do_exit();
+}
+
+void do_sync(struct pt_regs *regs, unsigned long esr, unsigned long far)
+{
+    /* TO DO */
+    do_exit();
+}
diff --git a/arch/arm/time.c b/arch/arm/time.c
index a088981..84032fe 100644
--- a/arch/arm/time.c
+++ b/arch/arm/time.c
@@ -1,7 +1,13 @@
 #include <mini-os/os.h>
 #include <mini-os/hypervisor.h>
 #include <mini-os/events.h>
-#include <mini-os/traps.h>
+
+#if defined(__arm__)
+#include <mini-os/arm32/traps.h>
+#else
+#include <mini-os/arm64/traps.h>
+#endif
+
 #include <mini-os/types.h>
 #include <mini-os/time.h>
 #include <mini-os/lib.h>
diff --git a/include/arm/arm32/traps.h b/include/arm/arm32/traps.h
new file mode 100644
index 0000000..704df22
--- /dev/null
+++ b/include/arm/arm32/traps.h
@@ -0,0 +1,20 @@
+#ifndef _TRAPS_H_
+#define _TRAPS_H_
+
+struct pt_regs {
+    unsigned long r0;
+    unsigned long r1;
+    unsigned long r2;
+    unsigned long r3;
+    unsigned long r4;
+    unsigned long r5;
+    unsigned long r6;
+    unsigned long r7;
+    unsigned long r8;
+    unsigned long r9;
+    unsigned long r10;
+    unsigned long r11;
+    unsigned long r12;
+};
+
+#endif
diff --git a/include/arm/arm64/traps.h b/include/arm/arm64/traps.h
new file mode 100644
index 0000000..962f4a6
--- /dev/null
+++ b/include/arm/arm64/traps.h
@@ -0,0 +1,27 @@
+#ifndef _TRAPS_H_
+#define _TRAPS_H_
+
+#ifndef __ASSEMBLY__
+struct pt_regs {
+    uint64_t sp;
+    uint64_t pc;
+    uint64_t lr;  /* elr */
+    uint32_t pstate;
+    uint32_t esr;
+
+    /* From x0 ~ x29 */
+    uint64_t x[30];
+};
+
+#else
+
+#define PT_REG_SIZE   (272)
+
+#define PT_REG_SP     (0)
+#define PT_REG_ELR    (16)
+#define PT_REG_SPSR   (24)
+#define PT_REG_X      (32)
+
+#endif
+
+#endif
diff --git a/include/arm/traps.h b/include/arm/traps.h
deleted file mode 100644
index 704df22..0000000
--- a/include/arm/traps.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef _TRAPS_H_
-#define _TRAPS_H_
-
-struct pt_regs {
-    unsigned long r0;
-    unsigned long r1;
-    unsigned long r2;
-    unsigned long r3;
-    unsigned long r4;
-    unsigned long r5;
-    unsigned long r6;
-    unsigned long r7;
-    unsigned long r8;
-    unsigned long r9;
-    unsigned long r10;
-    unsigned long r11;
-    unsigned long r12;
-};
-
-#endif
diff --git a/include/console.h b/include/console.h
index 539cccd..eef15fb 100644
--- a/include/console.h
+++ b/include/console.h
@@ -37,7 +37,15 @@
 #define _LIB_CONSOLE_H_
 
 #include <mini-os/os.h>
+
+#if defined(__arm__)
+#include <mini-os/arm32/traps.h>
+#elif defined(__aarch64__)
+#include <mini-os/arm64/traps.h>
+#else
 #include <mini-os/traps.h>
+#endif
+
 #include <mini-os/types.h>
 #include <xen/grant_table.h>
 #include <xenbus.h>
diff --git a/include/events.h b/include/events.h
index 89b5997..2187bab 100644
--- a/include/events.h
+++ b/include/events.h
@@ -19,7 +19,14 @@
 #ifndef _EVENTS_H_
 #define _EVENTS_H_
 
-#include<mini-os/traps.h>
+#if defined(__arm__)
+#include <mini-os/arm32/traps.h>
+#elif defined(__aarch64__)
+#include <mini-os/arm64/traps.h>
+#else
+#include <mini-os/traps.h>
+#endif
+
 #include<xen/event_channel.h>
 
 typedef void (*evtchn_handler_t)(evtchn_port_t, struct pt_regs *, void *);
diff --git a/include/hypervisor.h b/include/hypervisor.h
index f3b1f3c..effdbba 100644
--- a/include/hypervisor.h
+++ b/include/hypervisor.h
@@ -24,7 +24,14 @@
 #error "Unsupported architecture"
 #endif
 #include <xen/hvm/hvm_op.h>
+
+#if defined(__arm__)
+#include <mini-os/arm32/traps.h>
+#elif defined(__aarch64__)
+#include <mini-os/arm64/traps.h>
+#else
 #include <mini-os/traps.h>
+#endif
 
 /* hypervisor.c */
 #ifdef CONFIG_PARAVIRT
diff --git a/xenbus/xenbus.c b/xenbus/xenbus.c
index 636786c..1154207 100644
--- a/xenbus/xenbus.c
+++ b/xenbus/xenbus.c
@@ -18,7 +18,15 @@
 #include <inttypes.h>
 #include <mini-os/os.h>
 #include <mini-os/mm.h>
+
+#if defined(__arm__)
+#include <mini-os/arm32/traps.h>
+#elif defined(__aarch64__)
+#include <mini-os/arm64/traps.h>
+#else
 #include <mini-os/traps.h>
+#endif
+
 #include <mini-os/lib.h>
 #include <mini-os/xenbus.h>
 #include <mini-os/events.h>
-- 
2.7.4


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.