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

Re: [Minios-devel] [PATCH 07/40] arm64: add exception support



On Fri, Nov 03, 2017 at 03:44:27PM +0000, Julien Grall wrote:
> Hi Shijie,
> 
> On 03/11/17 03:11, Huang Shijie wrote:
> > This patch adds the exception support for arm64:
> >      .0) Add the new pt_regs{} for arm64.
> >      .1) Add stack macros: trap_entry/trap_exit
> >      .2) setup the vector table
> > 
> > Change-Id: I61d86ed4516443bf8baf4ef0b13687f9cb2047fd
> > Jira: ENTOS-247
> > Signed-off-by: Huang Shijie <shijie.huang@xxxxxxx>
> > ---
> >   arch/arm/arm64/arm64.S | 154 
> > +++++++++++++++++++++++++++++++++++++++++++++++++
> >   arch/arm/arm64/traps.c |  15 +++++
> >   include/arm/traps.h    |  14 +++++
> >   3 files changed, 183 insertions(+)
> >   create mode 100644 arch/arm/arm64/traps.c
> > 
> > diff --git a/arch/arm/arm64/arm64.S b/arch/arm/arm64/arm64.S
> > index 61c14a6..1321a1d 100644
> > --- a/arch/arm/arm64/arm64.S
> > +++ b/arch/arm/arm64/arm64.S
> > @@ -105,6 +105,11 @@ ENTRY(_start)
> >       msr     ttbr0_el1, x5
> >       isb
> > +    /* Load the exception vectors */
> > +    ldr     x2, =vector_table
> > +    msr     vbar_el1, x2
> > +    isb
> > +
> >       /* Turning on MMU */
> >       tlbi    vmalle1
> >       dsb     nsh
> > @@ -305,3 +310,152 @@ ENTRY(_setup_idmap_pgtable)
> >       dsb     sy
> >       ret
> >   ENDPROC(_setup_idmap_pgtable)
> > +
> > +/* please refer to struct pt_regs{} in traps.h */
> > +#define FRAME_SIZE 272
> 
> Can you please define that in traps.h? This would at least help to prevent
> some divergence between pt_regs and FRAME_SIZE.
okay. I will move it to traps.h.

> 
> Question for the Mini-OS maintainers, do you have a way similar to
> asm-offsets.c in Mini-OS? This would avoid a lot of hardcoding value in the
> code.
> 
> > +
> > +    .macro trap_entry, el
> > +    sub   sp, sp, #FRAME_SIZE
> > +    stp   x0, x1, [sp, #16 * 0]
> > +    stp   x2, x3, [sp, #16 * 1]
> > +    stp   x4, x5, [sp, #16 * 2]
> > +    stp   x6, x7, [sp, #16 * 3]
> > +    stp   x8, x9, [sp, #16 * 4]
> > +    stp   x10, x11, [sp, #16 * 5]
> > +    stp   x12, x13, [sp, #16 * 6]
> > +    stp   x14, x15, [sp, #16 * 7]
> > +    stp   x16, x17, [sp, #16 * 8]
> > +    stp   x18, x19, [sp, #16 * 9]
> > +    stp   x20, x21, [sp, #16 * 10]
> > +    stp   x22, x23, [sp, #16 * 11]
> > +    stp   x24, x25, [sp, #16 * 12]
> > +    stp   x26, x27, [sp, #16 * 13]
> > +    stp   x28, x29, [sp, #16 * 14]
> 
> Is there any way to simplify this code? Such as using writeback version?
I do not know, I just copy it from the linux kernel.

Could you give an example about the writeback version?

> 
> > +
> > +    .if     \el == 0
> > +    mrs     x21, sp_el0
> > +    .else
> > +    add     x21, sp, #FRAME_SIZE
> > +    .endif
> 
> This code was adapted from Linux, right? At least it looks like because of
> the way to save registers and the temporary register (which could be any
> between x0 and x29) used is strangely the same as Linux.
Yes.

> 
> > +
> > +    stp     x30, x21, [sp, #16 * 15]
> > +
> > +    mrs     x22, elr_el1
> > +    mrs     x23, spsr_el1
> > +    stp     x22, x23, [sp, #16 * 16]
> > +    .endm
> > +
> > +    .macro trap_exit, el
> > +    ldp   x22, x23, [sp, #16 * 16]
> > +
> > +    /* restore the elr and spsr */
> > +    msr   elr_el1, x22
> > +    msr   spsr_el1, x23
> > +
> > +    /* restore the lr(x30) and sp_el0 */
> > +    ldp   x30, x21, [sp, #16 * 15]
> > +
> > +    .if     \el == 0
> > +    msr     sp_el0, x21
> > +    .endif
> > +
> > +    ldp   x0, x1, [sp, #16 * 0]
> > +    ldp   x2, x3, [sp, #16 * 1]
> > +    ldp   x4, x5, [sp, #16 * 2]
> > +    ldp   x6, x7, [sp, #16 * 3]
> > +    ldp   x8, x9, [sp, #16 * 4]
> > +    ldp   x10, x11, [sp, #16 * 5]
> > +    ldp   x12, x13, [sp, #16 * 6]
> > +    ldp   x14, x15, [sp, #16 * 7]
> > +    ldp   x16, x17, [sp, #16 * 8]
> > +    ldp   x18, x19, [sp, #16 * 9]
> > +    ldp   x20, x21, [sp, #16 * 10]
> > +    ldp   x22, x23, [sp, #16 * 11]
> > +    ldp   x24, x25, [sp, #16 * 12]
> > +    ldp   x26, x27, [sp, #16 * 13]
> > +    ldp   x28, x29, [sp, #16 * 14]
> > +
> > +    add     sp, sp, #FRAME_SIZE
> > +    eret
> > +    .endm
> > +
> > +    .globl IRQ_handler
> > +IRQ_handler:
> > +    .long 0x0
> > +
> > +    .align 6
> > +el1_sync:
> > +    trap_entry 1
> > +    mov     x0, sp
> > +    mrs     x1, esr_el1;
> > +    mrs     x2, far_el1;
> > +    bl      do_sync
> > +    trap_exit 1
> > +ENDPROC(el1_sync)
> > +
> > +    .align 6
> > +el1_irq:
> > +    trap_entry 1
> > +    ldr     x0, IRQ_handler
> > +    blr     x0
> > +    trap_exit 1
> > +ENDPROC(el1_irq)
> > +
> > +    /* 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 Executable level with SP_EL1 */
> 
> Executable? Do you mean Exception?
yes, I mean exception...
> > +
> > +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);
> 
> It would be more logic to define all the exception handler before creating
> the vector table.
do you mean I need to add another patch to define all the handlers?

thanks
> 
> > diff --git a/arch/arm/arm64/traps.c b/arch/arm/arm64/traps.c
> > new file mode 100644
> > index 0000000..200b0ab
> > --- /dev/null
> > +++ b/arch/arm/arm64/traps.c
> > @@ -0,0 +1,15 @@
> > +#include <mini-os/os.h>
> > +#include <mini-os/traps.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/traps.h b/include/arm/traps.h
> > index 704df22..21de0e9 100644
> > --- a/include/arm/traps.h
> > +++ b/include/arm/traps.h
> > @@ -1,6 +1,7 @@
> >   #ifndef _TRAPS_H_
> >   #define _TRAPS_H_
> > +#if defined(__arm__)
> >   struct pt_regs {
> >       unsigned long r0;
> >       unsigned long r1;
> > @@ -16,5 +17,18 @@ struct pt_regs {
> >       unsigned long r11;
> >       unsigned long r12;
> >   };
> > +#elif defined(__aarch64__)
> > +struct pt_regs {
> > +    /* From x0 ~ x29 */
> > +    uint64_t x[30];
> > +    union {
> > +        uint64_t x30;
> > +        uint64_t lr;
> > +    };
> > +    uint64_t sp;
> > +    uint64_t pc;
> > +    uint64_t pstate;
> > +};
> > +#endif
> 
> Please introduce {arm64,arm32}/traps.h
okay...

thanks
Huang Shijie

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

 


Rackspace

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