|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [PATCH v3 10/43] arm64: add exception support
On Wed, Apr 18, 2018 at 06:48:24PM +0100, Julien Grall wrote:
> Hi Shijie,
>
> On 16/04/18 07:31, Huang Shijie wrote:
> >This patch adds the exception support for arm64:
> > .0) Add arm64/traps.h, and add new pt_regs{} for arm64.
> > .1) Add save_registers/restore_registers which are based on FreeBSD
> > code.
>
> Please give a pointer to the code.
okay.
>
> > .2) setup the vector table
> > .3) remove the code for arm32.
>
> This does not make sense in a patch that is adding arm64 support. The code
> removed look fairly independent, so can you move that in #2.
okay.
>
> >
> >Signed-off-by: Huang Shijie <shijie.huang@xxxxxxx>
> >---
> > arch/arm/arm64/arm64.S | 147
> > ++++++++++++++++++++++++++++++++++++++++++++++
> > arch/arm/arm64/traps.c | 16 +++++
> > include/arm/arm64/traps.h | 27 +++++++++
> > include/arm/traps.h | 21 +------
> > 4 files changed, 191 insertions(+), 20 deletions(-)
> > create mode 100644 arch/arm/arm64/traps.c
> > create mode 100644 include/arm/arm64/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
>
> I don't think the isb is necessary here. You can rely on the one below (when
> setting up the SCTLR).
>
> This would be fine because the vector table contains virtual address so it
> is unusable before turning on the MMU.
>
okay, I will think about it.
> >+
> > /* 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 */
>
> Missing full stop.
>
> >+.macro save_registers el
>
> All the code below is using hard tab, however the rest of the file is using
> soft tab. Please replace all hard tab with soft tab.
I will change it to soft tab.
>
> >+ mov x18, sp
>
> Something is wrong here. You seem to overwrite x18 without saving it. Did I
> miss anything?
I copied from the freebsd code. The original code uses x18 here.
It is really not proper to overwrite x18.
I will change it later.
>
> >+
> >+ sub sp, sp, #(PT_REG_SIZE)
> >+
> >+ stp x28, x29, [sp, #(PT_REG_X + 28 * 8)]
>
> I might be nice to make PT_REG_X a macro take the registers in parameters.
> This would ease the reading of the code.
okay, no problem.
>
> >+ 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
>
> AFAICT you will never go in EL0. So is there any reason to handle EL0?
there is invalid case for EL0, such as el0_irq.
So keep it here for them.
>
> >+ mrs x18, sp_el0
> >+.endif
>
> Hmm I think you want the "mov x18, sp" but you also need to add the
> PT_REG_SIZE to get the correct sp.
The sp is correct here.
We have sub the PT_REG_SIZE at the beginning of the @save_registers.
>
> >+ 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
>
> Will you ever reach this macro with interrupt enabled? If so, don't you want
> to disable them. So you don't get interrupt in the middle of the restore?
The interrupt is disabled here.
>
> >+ 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
>
> So x18 will not contain the sp here. But I think adding PT_REG_SIZE to sp
> should be enough here.
the x18 stores the previous sp maybe is different with current sp,
So add PT_REG_SIZE to sp is wrong.
>
> >+ eret
> >+.endm
> >+
> >+ .globl IRQ_handler
> >+IRQ_handler:
> >+ .long 0x0
>
> I am not sure to understand the purpose of IRQ_handler. Can't you just
> directly call the handler?
We have already have the el1_irq to handle the IRQ.
and we need to save the context before call IRQ_handler.
>
> >+
> >+ .align 6
> >+el1_sync:
> >+ save_registers 1
> >+ mov x0, sp
> >+ mrs x1, esr_el1;
> >+ mrs x2, far_el1;
>
> Do you expect the mini-OS to always run with interrupt disabled in EL1? If
> not, you may want to re-enable interrupt here.
okay, I will check it.
>
> >+ 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 */
>
> It looks like you don't implement EL0. I would try to simplify the EL0
> handling in that case and also add a comment in the code.
okay,
>
> >+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/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)
>
> I honestly don't like hardcoding offset of the structure. This is a real
> call to mess up in the future (or even now). The lack of comments don't help
> either.
>
> But I am pretty sure I asked it before. Can't they be generated
> automatically?
I do not know how to generated it automatically :(
thanks
Huang Shijie
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |