[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 |