diff mbox series

[v3,08/14] xen/riscv: introduce exception handlers implementation

Message ID c614e69342eea7a5ce27f7a0e550ab3147afa592.1675779308.git.oleksii.kurochko@gmail.com (mailing list archive)
State Superseded
Headers show
Series RISCV basic exception handling implementation | expand

Commit Message

Oleksii Feb. 7, 2023, 2:46 p.m. UTC
The patch introduces an implementation of basic exception handlers:
- to save/restore context
- to handle an exception itself. The handler calls wait_for_interrupt
  now, nothing more.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
  - Nothing changed
---
Changes in V2:
  - Refactor entry.S to start using of defines introduced in asm_offsets.C
  - Rename {__,}handle_exception to handle_trap() and do_trap() to be more
    consistent with RISC-V spec.
  - Wrap handle_trap() to ENTRY().
---
 xen/arch/riscv/Makefile            |  2 +
 xen/arch/riscv/entry.S             | 94 ++++++++++++++++++++++++++++++
 xen/arch/riscv/include/asm/traps.h | 13 +++++
 xen/arch/riscv/traps.c             | 13 +++++
 4 files changed, 122 insertions(+)
 create mode 100644 xen/arch/riscv/entry.S
 create mode 100644 xen/arch/riscv/include/asm/traps.h
 create mode 100644 xen/arch/riscv/traps.c

Comments

Alistair Francis Feb. 10, 2023, 1:46 a.m. UTC | #1
On Wed, Feb 8, 2023 at 12:47 AM Oleksii Kurochko
<oleksii.kurochko@gmail.com> wrote:
>
> The patch introduces an implementation of basic exception handlers:
> - to save/restore context
> - to handle an exception itself. The handler calls wait_for_interrupt
>   now, nothing more.
>
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
> Changes in V3:
>   - Nothing changed
> ---
> Changes in V2:
>   - Refactor entry.S to start using of defines introduced in asm_offsets.C
>   - Rename {__,}handle_exception to handle_trap() and do_trap() to be more
>     consistent with RISC-V spec.
>   - Wrap handle_trap() to ENTRY().
> ---
>  xen/arch/riscv/Makefile            |  2 +
>  xen/arch/riscv/entry.S             | 94 ++++++++++++++++++++++++++++++
>  xen/arch/riscv/include/asm/traps.h | 13 +++++
>  xen/arch/riscv/traps.c             | 13 +++++
>  4 files changed, 122 insertions(+)
>  create mode 100644 xen/arch/riscv/entry.S
>  create mode 100644 xen/arch/riscv/include/asm/traps.h
>  create mode 100644 xen/arch/riscv/traps.c
>
> diff --git a/xen/arch/riscv/Makefile b/xen/arch/riscv/Makefile
> index 1a4f1a6015..443f6bf15f 100644
> --- a/xen/arch/riscv/Makefile
> +++ b/xen/arch/riscv/Makefile
> @@ -1,7 +1,9 @@
>  obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
> +obj-y += entry.o
>  obj-$(CONFIG_RISCV_64) += riscv64/
>  obj-y += sbi.o
>  obj-y += setup.o
> +obj-y += traps.o
>
>  $(TARGET): $(TARGET)-syms
>         $(OBJCOPY) -O binary -S $< $@
> diff --git a/xen/arch/riscv/entry.S b/xen/arch/riscv/entry.S
> new file mode 100644
> index 0000000000..0be543f8e0
> --- /dev/null
> +++ b/xen/arch/riscv/entry.S
> @@ -0,0 +1,94 @@
> +#include <asm/asm.h>
> +#include <asm/asm-offsets.h>
> +#include <asm/processor.h>
> +#include <asm/riscv_encoding.h>
> +#include <asm/traps.h>
> +
> +/* WIP: only works while interrupting Xen context */
> +ENTRY(handle_trap)
> +
> +    /* Exceptions from xen */
> +save_to_stack:
> +        /* Save context to stack */
> +        REG_S   sp, (CPU_USER_REGS_SP - CPU_USER_REGS_SIZE) (sp)
> +        addi    sp, sp, -CPU_USER_REGS_SIZE
> +        REG_S   t0, CPU_USER_REGS_T0(sp)
> +
> +        /* Save registers */
> +        REG_S   ra, CPU_USER_REGS_RA(sp)
> +        REG_S   gp, CPU_USER_REGS_GP(sp)
> +        REG_S   t1, CPU_USER_REGS_T1(sp)
> +        REG_S   t2, CPU_USER_REGS_T2(sp)
> +        REG_S   s0, CPU_USER_REGS_S0(sp)
> +        REG_S   s1, CPU_USER_REGS_S1(sp)
> +        REG_S   a0, CPU_USER_REGS_A0(sp)
> +        REG_S   a1, CPU_USER_REGS_A1(sp)
> +        REG_S   a2, CPU_USER_REGS_A2(sp)
> +        REG_S   a3, CPU_USER_REGS_A3(sp)
> +        REG_S   a4, CPU_USER_REGS_A4(sp)
> +        REG_S   a5, CPU_USER_REGS_A5(sp)
> +        REG_S   a6, CPU_USER_REGS_A6(sp)
> +        REG_S   a7, CPU_USER_REGS_A7(sp)
> +        REG_S   s2, CPU_USER_REGS_S2(sp)
> +        REG_S   s3, CPU_USER_REGS_S3(sp)
> +        REG_S   s4, CPU_USER_REGS_S4(sp)
> +        REG_S   s5, CPU_USER_REGS_S5(sp)
> +        REG_S   s6, CPU_USER_REGS_S6(sp)
> +        REG_S   s7, CPU_USER_REGS_S7(sp)
> +        REG_S   s8, CPU_USER_REGS_S8(sp)
> +        REG_S   s9, CPU_USER_REGS_S9(sp)
> +        REG_S   s10,CPU_USER_REGS_S10(sp)
> +        REG_S   s11,CPU_USER_REGS_S11(sp)
> +        REG_S   t3, CPU_USER_REGS_T3(sp)
> +        REG_S   t4, CPU_USER_REGS_T4(sp)
> +        REG_S   t5, CPU_USER_REGS_T5(sp)
> +        REG_S   t6, CPU_USER_REGS_T6(sp)
> +        csrr    t0, CSR_SEPC
> +        REG_S   t0, CPU_USER_REGS_SEPC(sp)
> +        csrr    t0, CSR_SSTATUS
> +        REG_S   t0, CPU_USER_REGS_SSTATUS(sp)
> +
> +        mv      a0, sp
> +        jal     do_trap
> +
> +restore_registers:
> +        /* Restore stack_cpu_regs */
> +        REG_L   t0, CPU_USER_REGS_SEPC(sp)
> +        csrw    CSR_SEPC, t0
> +        REG_L   t0, CPU_USER_REGS_SSTATUS(sp)
> +        csrw    CSR_SSTATUS, t0
> +
> +        REG_L   ra, CPU_USER_REGS_RA(sp)
> +        REG_L   gp, CPU_USER_REGS_GP(sp)
> +        REG_L   t0, CPU_USER_REGS_T0(sp)
> +        REG_L   t1, CPU_USER_REGS_T1(sp)
> +        REG_L   t2, CPU_USER_REGS_T2(sp)
> +        REG_L   s0, CPU_USER_REGS_S0(sp)
> +        REG_L   s1, CPU_USER_REGS_S1(sp)
> +        REG_L   a0, CPU_USER_REGS_A0(sp)
> +        REG_L   a1, CPU_USER_REGS_A1(sp)
> +        REG_L   a2, CPU_USER_REGS_A2(sp)
> +        REG_L   a3, CPU_USER_REGS_A3(sp)
> +        REG_L   a4, CPU_USER_REGS_A4(sp)
> +        REG_L   a5, CPU_USER_REGS_A5(sp)
> +        REG_L   a6, CPU_USER_REGS_A6(sp)
> +        REG_L   a7, CPU_USER_REGS_A7(sp)
> +        REG_L   s2, CPU_USER_REGS_S2(sp)
> +        REG_L   s3, CPU_USER_REGS_S3(sp)
> +        REG_L   s4, CPU_USER_REGS_S4(sp)
> +        REG_L   s5, CPU_USER_REGS_S5(sp)
> +        REG_L   s6, CPU_USER_REGS_S6(sp)
> +        REG_L   s7, CPU_USER_REGS_S7(sp)
> +        REG_L   s8, CPU_USER_REGS_S8(sp)
> +        REG_L   s9, CPU_USER_REGS_S9(sp)
> +        REG_L   s10, CPU_USER_REGS_S10(sp)
> +        REG_L   s11, CPU_USER_REGS_S11(sp)
> +        REG_L   t3, CPU_USER_REGS_T3(sp)
> +        REG_L   t4, CPU_USER_REGS_T4(sp)
> +        REG_L   t5, CPU_USER_REGS_T5(sp)
> +        REG_L   t6, CPU_USER_REGS_T6(sp)
> +
> +        /* Restore sp */
> +        REG_L   sp, CPU_USER_REGS_SP(sp)
> +
> +        sret
> diff --git a/xen/arch/riscv/include/asm/traps.h b/xen/arch/riscv/include/asm/traps.h
> new file mode 100644
> index 0000000000..f3fb6b25d1
> --- /dev/null
> +++ b/xen/arch/riscv/include/asm/traps.h
> @@ -0,0 +1,13 @@
> +#ifndef __ASM_TRAPS_H__
> +#define __ASM_TRAPS_H__
> +
> +#include <asm/processor.h>
> +
> +#ifndef __ASSEMBLY__
> +
> +void do_trap(struct cpu_user_regs *cpu_regs);
> +void handle_trap(void);
> +
> +#endif /* __ASSEMBLY__ */
> +
> +#endif /* __ASM_TRAPS_H__ */
> diff --git a/xen/arch/riscv/traps.c b/xen/arch/riscv/traps.c
> new file mode 100644
> index 0000000000..ccd3593f5a
> --- /dev/null
> +++ b/xen/arch/riscv/traps.c
> @@ -0,0 +1,13 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright (C) 2023 Vates
> + *
> + * RISC-V Trap handlers
> + */
> +#include <asm/processor.h>
> +#include <asm/traps.h>
> +
> +void do_trap(struct cpu_user_regs *cpu_regs)
> +{
> +    die();
> +}
> --
> 2.39.0
>
>
diff mbox series

Patch

diff --git a/xen/arch/riscv/Makefile b/xen/arch/riscv/Makefile
index 1a4f1a6015..443f6bf15f 100644
--- a/xen/arch/riscv/Makefile
+++ b/xen/arch/riscv/Makefile
@@ -1,7 +1,9 @@ 
 obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+obj-y += entry.o
 obj-$(CONFIG_RISCV_64) += riscv64/
 obj-y += sbi.o
 obj-y += setup.o
+obj-y += traps.o
 
 $(TARGET): $(TARGET)-syms
 	$(OBJCOPY) -O binary -S $< $@
diff --git a/xen/arch/riscv/entry.S b/xen/arch/riscv/entry.S
new file mode 100644
index 0000000000..0be543f8e0
--- /dev/null
+++ b/xen/arch/riscv/entry.S
@@ -0,0 +1,94 @@ 
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/processor.h>
+#include <asm/riscv_encoding.h>
+#include <asm/traps.h>
+
+/* WIP: only works while interrupting Xen context */
+ENTRY(handle_trap)
+
+    /* Exceptions from xen */
+save_to_stack:
+        /* Save context to stack */
+        REG_S   sp, (CPU_USER_REGS_SP - CPU_USER_REGS_SIZE) (sp)
+        addi    sp, sp, -CPU_USER_REGS_SIZE
+        REG_S   t0, CPU_USER_REGS_T0(sp)
+
+        /* Save registers */
+        REG_S   ra, CPU_USER_REGS_RA(sp)
+        REG_S   gp, CPU_USER_REGS_GP(sp)
+        REG_S   t1, CPU_USER_REGS_T1(sp)
+        REG_S   t2, CPU_USER_REGS_T2(sp)
+        REG_S   s0, CPU_USER_REGS_S0(sp)
+        REG_S   s1, CPU_USER_REGS_S1(sp)
+        REG_S   a0, CPU_USER_REGS_A0(sp)
+        REG_S   a1, CPU_USER_REGS_A1(sp)
+        REG_S   a2, CPU_USER_REGS_A2(sp)
+        REG_S   a3, CPU_USER_REGS_A3(sp)
+        REG_S   a4, CPU_USER_REGS_A4(sp)
+        REG_S   a5, CPU_USER_REGS_A5(sp)
+        REG_S   a6, CPU_USER_REGS_A6(sp)
+        REG_S   a7, CPU_USER_REGS_A7(sp)
+        REG_S   s2, CPU_USER_REGS_S2(sp)
+        REG_S   s3, CPU_USER_REGS_S3(sp)
+        REG_S   s4, CPU_USER_REGS_S4(sp)
+        REG_S   s5, CPU_USER_REGS_S5(sp)
+        REG_S   s6, CPU_USER_REGS_S6(sp)
+        REG_S   s7, CPU_USER_REGS_S7(sp)
+        REG_S   s8, CPU_USER_REGS_S8(sp)
+        REG_S   s9, CPU_USER_REGS_S9(sp)
+        REG_S   s10,CPU_USER_REGS_S10(sp)
+        REG_S   s11,CPU_USER_REGS_S11(sp)
+        REG_S   t3, CPU_USER_REGS_T3(sp)
+        REG_S   t4, CPU_USER_REGS_T4(sp)
+        REG_S   t5, CPU_USER_REGS_T5(sp)
+        REG_S   t6, CPU_USER_REGS_T6(sp)
+        csrr    t0, CSR_SEPC
+        REG_S   t0, CPU_USER_REGS_SEPC(sp)
+        csrr    t0, CSR_SSTATUS
+        REG_S   t0, CPU_USER_REGS_SSTATUS(sp)
+
+        mv      a0, sp
+        jal     do_trap
+
+restore_registers:
+        /* Restore stack_cpu_regs */
+        REG_L   t0, CPU_USER_REGS_SEPC(sp)
+        csrw    CSR_SEPC, t0
+        REG_L   t0, CPU_USER_REGS_SSTATUS(sp)
+        csrw    CSR_SSTATUS, t0
+
+        REG_L   ra, CPU_USER_REGS_RA(sp)
+        REG_L   gp, CPU_USER_REGS_GP(sp)
+        REG_L   t0, CPU_USER_REGS_T0(sp)
+        REG_L   t1, CPU_USER_REGS_T1(sp)
+        REG_L   t2, CPU_USER_REGS_T2(sp)
+        REG_L   s0, CPU_USER_REGS_S0(sp)
+        REG_L   s1, CPU_USER_REGS_S1(sp)
+        REG_L   a0, CPU_USER_REGS_A0(sp)
+        REG_L   a1, CPU_USER_REGS_A1(sp)
+        REG_L   a2, CPU_USER_REGS_A2(sp)
+        REG_L   a3, CPU_USER_REGS_A3(sp)
+        REG_L   a4, CPU_USER_REGS_A4(sp)
+        REG_L   a5, CPU_USER_REGS_A5(sp)
+        REG_L   a6, CPU_USER_REGS_A6(sp)
+        REG_L   a7, CPU_USER_REGS_A7(sp)
+        REG_L   s2, CPU_USER_REGS_S2(sp)
+        REG_L   s3, CPU_USER_REGS_S3(sp)
+        REG_L   s4, CPU_USER_REGS_S4(sp)
+        REG_L   s5, CPU_USER_REGS_S5(sp)
+        REG_L   s6, CPU_USER_REGS_S6(sp)
+        REG_L   s7, CPU_USER_REGS_S7(sp)
+        REG_L   s8, CPU_USER_REGS_S8(sp)
+        REG_L   s9, CPU_USER_REGS_S9(sp)
+        REG_L   s10, CPU_USER_REGS_S10(sp)
+        REG_L   s11, CPU_USER_REGS_S11(sp)
+        REG_L   t3, CPU_USER_REGS_T3(sp)
+        REG_L   t4, CPU_USER_REGS_T4(sp)
+        REG_L   t5, CPU_USER_REGS_T5(sp)
+        REG_L   t6, CPU_USER_REGS_T6(sp)
+
+        /* Restore sp */
+        REG_L   sp, CPU_USER_REGS_SP(sp)
+
+        sret
diff --git a/xen/arch/riscv/include/asm/traps.h b/xen/arch/riscv/include/asm/traps.h
new file mode 100644
index 0000000000..f3fb6b25d1
--- /dev/null
+++ b/xen/arch/riscv/include/asm/traps.h
@@ -0,0 +1,13 @@ 
+#ifndef __ASM_TRAPS_H__
+#define __ASM_TRAPS_H__
+
+#include <asm/processor.h>
+
+#ifndef __ASSEMBLY__
+
+void do_trap(struct cpu_user_regs *cpu_regs);
+void handle_trap(void);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_TRAPS_H__ */
diff --git a/xen/arch/riscv/traps.c b/xen/arch/riscv/traps.c
new file mode 100644
index 0000000000..ccd3593f5a
--- /dev/null
+++ b/xen/arch/riscv/traps.c
@@ -0,0 +1,13 @@ 
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2023 Vates
+ *
+ * RISC-V Trap handlers
+ */
+#include <asm/processor.h>
+#include <asm/traps.h>
+
+void do_trap(struct cpu_user_regs *cpu_regs)
+{
+    die();
+}