[rtems commit] riscv: Rework exception handling

Sebastian Huber sebh at rtems.org
Wed Jul 25 08:10:39 UTC 2018


Module:    rtems
Branch:    master
Commit:    8db3f0e878b7f008ad05716f501220509662e2c4
Changeset: http://git.rtems.org/rtems/commit/?id=8db3f0e878b7f008ad05716f501220509662e2c4

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Thu Jul 19 12:11:19 2018 +0200

riscv: Rework exception handling

Remove _CPU_ISR_install_raw_handler() and _CPU_ISR_install_vector()
functions.  Applications can install an exception handler via the fatal
error handler to handle synchronous exceptions.

Handle interrupt exceptions via _RISCV_Interrupt_dispatch() which must
be provided by the BSP.

Update #3433.

---

 bsps/include/bsp/fatal.h                           |  4 +-
 bsps/riscv/include/bsp/linker-symbols.h            |  4 --
 bsps/riscv/riscv/btimer/btimer.c                   |  2 -
 bsps/riscv/riscv/clock/clockdrv.c                  | 19 ++++--
 bsps/riscv/riscv/include/bsp/irq.h                 | 15 ++++-
 bsps/riscv/riscv/irq/irq.c                         | 28 +++++++-
 .../riscv/riscv/start/bspstart.c                   | 17 ++---
 bsps/riscv/riscv/start/start.S                     | 37 +----------
 c/src/lib/libbsp/riscv/riscv/Makefile.am           |  2 +-
 c/src/lib/libbsp/riscv/riscv/configure.ac          |  3 +
 cpukit/score/cpu/riscv/Makefile.am                 |  1 -
 cpukit/score/cpu/riscv/cpu.c                       | 46 -------------
 cpukit/score/cpu/riscv/include/rtems/score/cpu.h   | 30 ---------
 .../score/cpu/riscv/include/rtems/score/cpuimpl.h  |  7 ++
 cpukit/score/cpu/riscv/riscv-exception-handler.S   | 75 ++++++++++++++--------
 15 files changed, 120 insertions(+), 170 deletions(-)

diff --git a/bsps/include/bsp/fatal.h b/bsps/include/bsp/fatal.h
index 77c0566..92ab55f 100644
--- a/bsps/include/bsp/fatal.h
+++ b/bsps/include/bsp/fatal.h
@@ -142,7 +142,9 @@ typedef enum {
   /* RISC-V fatal codes */
   RISCV_FATAL_NO_TIMEBASE_FREQUENCY_IN_DEVICE_TREE = BSP_FATAL_CODE_BLOCK(13),
   RISCV_FATAL_NO_NS16550_REG_IN_DEVICE_TREE,
-  RISCV_FATAL_NO_NS16550_CLOCK_FREQUENCY_IN_DEVICE_TREE
+  RISCV_FATAL_NO_NS16550_CLOCK_FREQUENCY_IN_DEVICE_TREE,
+  RISCV_FATAL_UNEXPECTED_INTERRUPT_EXCEPTION,
+  RISCV_FATAL_CLOCK_IRQ_INSTALL
 } bsp_fatal_code;
 
 RTEMS_NO_RETURN static inline void
diff --git a/bsps/riscv/include/bsp/linker-symbols.h b/bsps/riscv/include/bsp/linker-symbols.h
index 34bf487..426b174 100644
--- a/bsps/riscv/include/bsp/linker-symbols.h
+++ b/bsps/riscv/include/bsp/linker-symbols.h
@@ -63,10 +63,6 @@ LINKER_SYMBOL(bsp_vector_table_begin)
 LINKER_SYMBOL(bsp_vector_table_end)
 LINKER_SYMBOL(bsp_vector_table_size)
 
-LINKER_SYMBOL(bsp_start_vector_table_begin)
-LINKER_SYMBOL(bsp_start_vector_table_end)
-LINKER_SYMBOL(bsp_start_vector_table_size)
-
 LINKER_SYMBOL(bsp_translation_table_base)
 LINKER_SYMBOL(bsp_translation_table_end)
 
diff --git a/bsps/riscv/riscv/btimer/btimer.c b/bsps/riscv/riscv/btimer/btimer.c
index 4dd3193..796979f 100644
--- a/bsps/riscv/riscv/btimer/btimer.c
+++ b/bsps/riscv/riscv/btimer/btimer.c
@@ -29,8 +29,6 @@
 #include <rtems/btimer.h>
 #include <rtems/score/riscv-utility.h>
 
-extern char bsp_start_vector_table_begin[];
-
 bool benchmark_timer_find_average_overhead;
 
 static void benchmark_timer1_interrupt_handler(void)
diff --git a/bsps/riscv/riscv/clock/clockdrv.c b/bsps/riscv/riscv/clock/clockdrv.c
index d2d7a40..52fb441 100644
--- a/bsps/riscv/riscv/clock/clockdrv.c
+++ b/bsps/riscv/riscv/clock/clockdrv.c
@@ -72,11 +72,20 @@ static void riscv_clock_at_tick(void)
 #endif
 }
 
-static void riscv_clock_handler_install(proc_ptr new_isr)
+static void riscv_clock_handler_install(void)
 {
-  _CPU_ISR_install_vector(RISCV_MACHINE_TIMER_INTERRUPT,
-                          new_isr,
-                          NULL);
+  rtems_status_code sc;
+
+  sc = rtems_interrupt_handler_install(
+    RISCV_INTERRUPT_VECTOR_TIMER,
+    "Clock",
+    RTEMS_INTERRUPT_UNIQUE,
+    (rtems_interrupt_handler) Clock_isr,
+    NULL
+  );
+  if (sc != RTEMS_SUCCESSFUL) {
+    bsp_fatal(RISCV_FATAL_CLOCK_IRQ_INSTALL);
+  }
 }
 
 static uint32_t riscv_clock_get_timecount(struct timecounter *tc)
@@ -136,6 +145,6 @@ uint32_t _CPU_Counter_frequency( void )
 #define Clock_driver_support_initialize_hardware() riscv_clock_initialize()
 
 #define Clock_driver_support_install_isr(isr) \
-  riscv_clock_handler_install(isr)
+  riscv_clock_handler_install()
 
 #include "../../../shared/dev/clock/clockimpl.h"
diff --git a/bsps/riscv/riscv/include/bsp/irq.h b/bsps/riscv/riscv/include/bsp/irq.h
index d7ee45b..353005f 100644
--- a/bsps/riscv/riscv/include/bsp/irq.h
+++ b/bsps/riscv/riscv/include/bsp/irq.h
@@ -7,6 +7,7 @@
  */
 
 /*
+ * Copyright (c) 2018 embedded brains GmbH
  *
  * Copyright (c) 2015 University of York.
  * Hesham Almatary <hesham at alumni.york.ac.uk>
@@ -38,12 +39,20 @@
 
 #ifndef ASM
 
-#include <rtems.h>
+#include <bsp.h>
 #include <rtems/irq.h>
 #include <rtems/irq-extension.h>
 
-#define BSP_INTERRUPT_VECTOR_MIN  0x0
-#define BSP_INTERRUPT_VECTOR_MAX  0x24
+#define RISCV_INTERRUPT_VECTOR_SOFTWARE 0
+
+#define RISCV_INTERRUPT_VECTOR_TIMER 1
+
+#define RISCV_INTERRUPT_VECTOR_EXTERNAL(x) ((x) + 2)
+
+#define BSP_INTERRUPT_VECTOR_MIN 0
+
+#define BSP_INTERRUPT_VECTOR_MAX RISCV_INTERRUPT_VECTOR_EXTERNAL(RISCV_MAXIMUM_EXTERNAL_INTERRUPTS - 1)
 
 #endif /* ASM */
+
 #endif /* LIBBSP_GENERIC_RISCV_IRQ_H */
diff --git a/bsps/riscv/riscv/irq/irq.c b/bsps/riscv/riscv/irq/irq.c
index ac4f1ca..61cf131 100644
--- a/bsps/riscv/riscv/irq/irq.c
+++ b/bsps/riscv/riscv/irq/irq.c
@@ -7,7 +7,7 @@
  */
 
 /*
- * RISCV CPU Dependent Source
+ * Copyright (c) 2018 embedded brains GmbH
  *
  * Copyright (c) 2015 University of York.
  * Hesham Almatary <hesham at alumni.york.ac.uk>
@@ -35,11 +35,33 @@
  */
 
 #include <bsp/irq.h>
+#include <bsp/fatal.h>
 #include <bsp/irq-generic.h>
 
-rtems_status_code bsp_interrupt_facility_initialize()
+#include <rtems/score/percpu.h>
+
+void _RISCV_Interrupt_dispatch(uintptr_t mcause, Per_CPU_Control *cpu_self)
+{
+  /*
+   * Get rid of the most significant bit which indicates if the exception was
+   * caused by an interrupt or not.
+   */
+  mcause <<= 1;
+
+  if (mcause == (RISCV_INTERRUPT_TIMER_MACHINE << 1)) {
+    bsp_interrupt_handler_dispatch(RISCV_INTERRUPT_VECTOR_TIMER);
+  } else if (mcause == (RISCV_INTERRUPT_EXTERNAL_MACHINE << 1)) {
+    /* TODO: Handle PLIC interrupt */
+  } else if (mcause == (RISCV_INTERRUPT_SOFTWARE_MACHINE << 1)) {
+    bsp_interrupt_handler_dispatch(RISCV_INTERRUPT_VECTOR_SOFTWARE);
+  } else {
+    bsp_fatal(RISCV_FATAL_UNEXPECTED_INTERRUPT_EXCEPTION);
+  }
+}
+
+rtems_status_code bsp_interrupt_facility_initialize(void)
 {
-  return RTEMS_NOT_IMPLEMENTED;
+  return RTEMS_SUCCESSFUL;
 }
 
 void bsp_interrupt_vector_enable(rtems_vector_number vector)
diff --git a/cpukit/score/cpu/riscv/riscv-exception-default.c b/bsps/riscv/riscv/start/bspstart.c
similarity index 75%
rename from cpukit/score/cpu/riscv/riscv-exception-default.c
rename to bsps/riscv/riscv/start/bspstart.c
index 62d0dd3..217e6f2 100644
--- a/cpukit/score/cpu/riscv/riscv-exception-default.c
+++ b/bsps/riscv/riscv/start/bspstart.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Hesham Almatary <heshamelmatary at gmail.com>
+ * Copyright (c) 2018 embedded brains GmbH
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -23,17 +23,10 @@
  * SUCH DAMAGE.
  */
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include <bsp/bootcard.h>
+#include <bsp/irq-generic.h>
 
-#include <rtems/score/cpu.h>
-#include <rtems/fatal.h>
-#include <stdio.h>
-
-void _RISCV_Exception_default(uint32_t vector, CPU_Exception_frame *frame);
-
-void _RISCV_Exception_default(uint32_t vector, CPU_Exception_frame *frame)
+void bsp_start(void)
 {
-  rtems_fatal( RTEMS_FATAL_SOURCE_EXCEPTION, (rtems_fatal_code) frame );
+  bsp_interrupt_initialize();
 }
diff --git a/bsps/riscv/riscv/start/start.S b/bsps/riscv/riscv/start/start.S
index 0dad170..83926a9 100644
--- a/bsps/riscv/riscv/start/start.S
+++ b/bsps/riscv/riscv/start/start.S
@@ -1,4 +1,6 @@
 /*
+ * Copyright (c) 2018 embedded brains GmbH
+
  * Copyright (c) 2015 University of York.
  * Hesham Almatary <hesham at alumni.york.ac.uk>
  *
@@ -33,13 +35,6 @@
 #include <bsp/linker-symbols.h>
 #include <bspopts.h>
 
-EXTERN(bsp_section_bss_begin)
-EXTERN(bsp_section_bss_end)
-EXTERN(ISR_Handler)
-EXTERN(bsp_section_stack_begin)
-
-PUBLIC(bsp_start_vector_table_begin)
-PUBLIC(bsp_start_vector_table_end)
 PUBLIC(_start)
 
 	.section	.bsp_start_text, "wax", @progbits
@@ -70,7 +65,7 @@ SYM(_start):
 	call	bsp_fdt_copy
 #endif
 
-	LADDR	t0, ISR_Handler
+	LADDR	t0, _RISCV_Exception_handler
 	csrw	mtvec, t0
 
 	/* Clear .bss */
@@ -107,29 +102,3 @@ SYM(_start):
 .Lsecondary_processor_go:
 	.word	0xdeadbeef
 #endif
-
-#if __riscv_xlen == 32
-#define ADDR .word
-#elif __riscv_xlen == 64
-#define ADDR .quad
-#endif
-
-	.align	4
-bsp_start_vector_table_begin:
-	ADDR	_RISCV_Exception_default /* User int */
-	ADDR	_RISCV_Exception_default /* Supervisor int */
-	ADDR	_RISCV_Exception_default /* Reserved */
-	ADDR	_RISCV_Exception_default /* Machine int */
-	ADDR	_RISCV_Exception_default /* User timer int */
-	ADDR	_RISCV_Exception_default /* Supervisor Timer int */
-	ADDR	_RISCV_Exception_default /* Reserved */
-	ADDR	_RISCV_Exception_default /* Machine Timer int */
-	ADDR	_RISCV_Exception_default /* User external int */
-	ADDR	_RISCV_Exception_default /* Supervisor external int */
-	ADDR	_RISCV_Exception_default /* Reserved */
-	ADDR	_RISCV_Exception_default /* Machine external int */
-	ADDR	_RISCV_Exception_default
-	ADDR	_RISCV_Exception_default
-	ADDR	_RISCV_Exception_default
-	ADDR	_RISCV_Exception_default
-bsp_start_vector_table_end:
diff --git a/c/src/lib/libbsp/riscv/riscv/Makefile.am b/c/src/lib/libbsp/riscv/riscv/Makefile.am
index c8299f3..159b4fe 100644
--- a/c/src/lib/libbsp/riscv/riscv/Makefile.am
+++ b/c/src/lib/libbsp/riscv/riscv/Makefile.am
@@ -33,7 +33,7 @@ project_lib_LIBRARIES = librtemsbsp.a
 
 # Startup
 librtemsbsp_a_SOURCES = ../../../../../../bsps/shared/start/bspreset-empty.c
-librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspstart-empty.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/riscv/riscv/start/bspstart.c
 librtemsbsp_a_SOURCES += ../../../../../../bsps/riscv/riscv/start/bsp_fatal_halt.c
 
 # Shared
diff --git a/c/src/lib/libbsp/riscv/riscv/configure.ac b/c/src/lib/libbsp/riscv/riscv/configure.ac
index 17f4eb8..478e255 100644
--- a/c/src/lib/libbsp/riscv/riscv/configure.ac
+++ b/c/src/lib/libbsp/riscv/riscv/configure.ac
@@ -30,6 +30,9 @@ RTEMS_BSPOPTS_HELP([BSP_FDT_BLOB_COPY_TO_READ_ONLY_LOAD_AREA],[copy the FDT blob
 RTEMS_BSPOPTS_SET([BSP_CONSOLE_BAUD],[*],[115200])
 RTEMS_BSPOPTS_HELP([BSP_CONSOLE_BAUD],[default baud for console driver devices (default 115200)])
 
+RTEMS_BSPOPTS_SET([RISCV_MAXIMUM_EXTERNAL_INTERRUPTS],[*],[64])
+RTEMS_BSPOPTS_HELP([RISCV_MAXIMUM_EXTERNAL_INTERRUPTS],[maximum number of external interrupts supported by the BSP (default 64)])
+
 RTEMS_BSPOPTS_SET([RISCV_ENABLE_HTIF_SUPPORT],[*],[1])
 RTEMS_BSPOPTS_HELP([RISCV_ENABLE_HTIF_SUPPORT],[enables the HTIF support if defined to a non-zero value, otherwise it is disabled (enabled by default)])
 
diff --git a/cpukit/score/cpu/riscv/Makefile.am b/cpukit/score/cpu/riscv/Makefile.am
index 3630c03..40fcd1f 100644
--- a/cpukit/score/cpu/riscv/Makefile.am
+++ b/cpukit/score/cpu/riscv/Makefile.am
@@ -3,7 +3,6 @@ noinst_LIBRARIES = libscorecpu.a
 libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
 libscorecpu_a_SOURCES  = cpu.c
 libscorecpu_a_SOURCES += riscv-exception-handler.S
-libscorecpu_a_SOURCES += riscv-exception-default.c
 libscorecpu_a_SOURCES += riscv-exception-frame-print.c
 libscorecpu_a_SOURCES += riscv-context-switch.S
 libscorecpu_a_SOURCES += riscv-context-initialize.c
diff --git a/cpukit/score/cpu/riscv/cpu.c b/cpukit/score/cpu/riscv/cpu.c
index 6b29de2..64eef96 100644
--- a/cpukit/score/cpu/riscv/cpu.c
+++ b/cpukit/score/cpu/riscv/cpu.c
@@ -173,12 +173,6 @@ RTEMS_STATIC_ASSERT(
   riscv_interrupt_frame_size
 );
 
-/* bsp_start_vector_table_begin is the start address of the vector table
- * containing addresses to ISR Handlers. It's defined at the BSP linkcmds
- * and may differ from one BSP to another.
- */
-extern char bsp_start_vector_table_begin[];
-
 void _init(void);
 
 void _fini(void);
@@ -208,46 +202,6 @@ uint32_t _CPU_ISR_Get_level( void )
   return 1;
 }
 
-void _CPU_ISR_install_raw_handler(
-  uint32_t   vector,
-  proc_ptr    new_handler,
-  proc_ptr   *old_handler
-)
-{
-  /* Do nothing */
-}
-
-void _CPU_ISR_install_vector(
-  unsigned long    vector,
-  proc_ptr    new_handler,
-  proc_ptr   *old_handler
-)
-{
-  proc_ptr *table =
-    (proc_ptr *) bsp_start_vector_table_begin;
-  proc_ptr current_handler;
-
-  ISR_Level level;
-
-  _ISR_Local_disable( level );
-
-  current_handler = table [vector];
-
-  /* The current handler is now the old one */
-  if (old_handler != NULL) {
-    *old_handler = (proc_ptr) current_handler;
-  }
-
-  /* Write only if necessary to avoid writes to a maybe read-only
-   * memory */
-  if (current_handler != new_handler) {
-    table [vector] = new_handler;
-  }
-
-  _ISR_Local_enable( level );
-
-}
-
 void *_CPU_Thread_Idle_body( uintptr_t ignored )
 {
   do {
diff --git a/cpukit/score/cpu/riscv/include/rtems/score/cpu.h b/cpukit/score/cpu/riscv/include/rtems/score/cpu.h
index 5553fa9..724385c 100644
--- a/cpukit/score/cpu/riscv/include/rtems/score/cpu.h
+++ b/cpukit/score/cpu/riscv/include/rtems/score/cpu.h
@@ -361,36 +361,6 @@ void _CPU_Initialize(
 );
 
 /*
- *  _CPU_ISR_install_raw_handler
- *
- *  This routine installs a "raw" interrupt handler directly into the
- *  processor's vector table.
- *
- */
-
-void _CPU_ISR_install_raw_handler(
-  uint32_t    vector,
-  proc_ptr    new_handler,
-  proc_ptr   *old_handler
-);
-
-/*
- *  _CPU_ISR_install_vector
- *
- *  This routine installs an interrupt vector.
- *
- *  NO_CPU Specific Information:
- *
- *  XXX document implementation including references if appropriate
- */
-
-void _CPU_ISR_install_vector(
-  unsigned long    vector,
-  proc_ptr   new_handler,
-  proc_ptr   *old_handler
-);
-
-/*
  *  _CPU_Thread_Idle_body
  *
  *  This routine is the CPU dependent IDLE thread body.
diff --git a/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h
index cb60a52..313b671 100644
--- a/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h
@@ -289,6 +289,13 @@ typedef struct {
 } CPU_Per_CPU_control;
 #endif
 
+struct Per_CPU_Control;
+
+void _RISCV_Interrupt_dispatch(
+  uintptr_t               mcause,
+  struct Per_CPU_Control *cpu_self
+);
+
 static inline uint32_t _RISCV_Read_FCSR( void )
 {
   uint32_t fcsr;
diff --git a/cpukit/score/cpu/riscv/riscv-exception-handler.S b/cpukit/score/cpu/riscv/riscv-exception-handler.S
index 875566c..897a15c 100644
--- a/cpukit/score/cpu/riscv/riscv-exception-handler.S
+++ b/cpukit/score/cpu/riscv/riscv-exception-handler.S
@@ -41,15 +41,13 @@
 #include <rtems/asm.h>
 #include <rtems/score/percpu.h>
 
-EXTERN(bsp_start_vector_table_begin)
-EXTERN(_Thread_Dispatch)
-PUBLIC(ISR_Handler)
+PUBLIC(_RISCV_Exception_handler)
 
 	.section	.text, "ax", @progbits
 	.align	2
 
-TYPE_FUNC(ISR_Handler)
-SYM(ISR_Handler):
+TYPE_FUNC(_RISCV_Exception_handler)
+SYM(_RISCV_Exception_handler):
 	addi	sp, sp, -CPU_INTERRUPT_FRAME_SIZE
 
 	/* Save */
@@ -104,8 +102,8 @@ SYM(ISR_Handler):
 	FSREG	fa7, RISCV_INTERRUPT_FRAME_FA7(sp)
 #endif
 
-	/* FIXME Only handle interrupts for now (MSB = 1) */
-	andi	a0, a0, 0xf
+	/* Check if this is a synchronous or interrupt exception */
+	bgez	a0, .Lsynchronous_exception
 
 	/* Increment interrupt nest and thread dispatch disable level */
 	lw	t0, PER_CPU_ISR_NEST_LEVEL(s0)
@@ -117,32 +115,17 @@ SYM(ISR_Handler):
 
 	CLEAR_RESERVATIONS	s0
 
-	/* Keep sp (Exception frame address) in s1 */
+	/*
+	 * Remember current stack pointer in non-volatile register s1.  Switch
+	 * to interrupt stack if necessary.
+	 */
 	mv	s1, sp
-
-	/* Call the exception handler from vector table */
-
-	/* First function arg for C handler is vector number,
-		* and the second is a pointer to exception frame.
-		* a0/mcause/vector number is already loaded above */
-	mv	a1, sp
-
-	/* calculate the offset */
-	LADDR	t5, bsp_start_vector_table_begin
-#if	__riscv_xlen == 32
-	slli	t6, a0, 2
-#else	/* xlen = 64 */
-	slli	t6, a0, 3
-#endif
-	add	t5, t5, t6
-	LREG	t5, (t5)
-
-	/* Switch to interrupt stack if necessary */
 	bnez	t0, .Linterrupt_stack_switch_done
 	LREG	sp, PER_CPU_INTERRUPT_STACK_HIGH(s0)
 .Linterrupt_stack_switch_done:
 
-	jalr	t5
+	mv	a1, s0
+	call	_RISCV_Interrupt_dispatch
 
 	/* Load some per-CPU variables */
 	lw	t0, PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL(s0)
@@ -249,3 +232,39 @@ SYM(ISR_Handler):
 	addi	sp, sp, CPU_INTERRUPT_FRAME_SIZE
 
 	mret
+
+.Lsynchronous_exception:
+
+	SREG	a0, RISCV_EXCEPTION_FRAME_MCAUSE(sp)
+	addi	a0, sp, CPU_INTERRUPT_FRAME_SIZE
+	SREG	a0, RISCV_EXCEPTION_FRAME_SP(sp)
+	SREG	gp, RISCV_EXCEPTION_FRAME_GP(sp)
+	SREG	tp, RISCV_EXCEPTION_FRAME_TP(sp)
+	SREG	s2, RISCV_EXCEPTION_FRAME_S2(sp)
+	SREG	s3, RISCV_EXCEPTION_FRAME_S3(sp)
+	SREG	s4, RISCV_EXCEPTION_FRAME_S4(sp)
+	SREG	s5, RISCV_EXCEPTION_FRAME_S5(sp)
+	SREG	s6, RISCV_EXCEPTION_FRAME_S6(sp)
+	SREG	s7, RISCV_EXCEPTION_FRAME_S7(sp)
+	SREG	s8, RISCV_EXCEPTION_FRAME_S8(sp)
+	SREG	s9, RISCV_EXCEPTION_FRAME_S9(sp)
+	SREG	s10, RISCV_EXCEPTION_FRAME_S10(sp)
+	SREG	s11, RISCV_EXCEPTION_FRAME_S11(sp)
+#if __riscv_flen > 0
+	FSREG	fs0, RISCV_EXCEPTION_FRAME_FS0(sp)
+	FSREG	fs1, RISCV_EXCEPTION_FRAME_FS1(sp)
+	FSREG	fs2, RISCV_EXCEPTION_FRAME_FS2(sp)
+	FSREG	fs3, RISCV_EXCEPTION_FRAME_FS3(sp)
+	FSREG	fs4, RISCV_EXCEPTION_FRAME_FS4(sp)
+	FSREG	fs5, RISCV_EXCEPTION_FRAME_FS5(sp)
+	FSREG	fs6, RISCV_EXCEPTION_FRAME_FS6(sp)
+	FSREG	fs7, RISCV_EXCEPTION_FRAME_FS7(sp)
+	FSREG	fs8, RISCV_EXCEPTION_FRAME_FS8(sp)
+	FSREG	fs9, RISCV_EXCEPTION_FRAME_FS9(sp)
+	FSREG	fs10, RISCV_EXCEPTION_FRAME_FS10(sp)
+	FSREG	fs11, RISCV_EXCEPTION_FRAME_FS11(sp)
+#endif
+
+	li	a0, 9
+	mv	a1, sp
+	call	_Terminate




More information about the vc mailing list