|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |