+/* The metal_lc0_interrupt_vector_handler() function can be redefined. */
+void __attribute__((weak, interrupt)) metal_lc0_interrupt_vector_handler (void) {
+ void *priv;
+ struct __metal_driver_riscv_cpu_intc *intc;
+ struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()];
+
+ if ( cpu ) {
+ intc = (struct __metal_driver_riscv_cpu_intc *)
+ __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu);
+ priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC0].exint_data;
+ intc->metal_int_table[METAL_INTERRUPT_ID_LC0].handler(METAL_INTERRUPT_ID_LC0, priv);
+ }
+}
+
+/* The metal_lc1_interrupt_vector_handler() function can be redefined. */
+void __attribute__((weak, interrupt)) metal_lc1_interrupt_vector_handler (void) {
+ void *priv;
+ struct __metal_driver_riscv_cpu_intc *intc;
+ struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()];
+
+ if ( cpu ) {
+ intc = (struct __metal_driver_riscv_cpu_intc *)
+ __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu);
+ priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC1].exint_data;
+ intc->metal_int_table[METAL_INTERRUPT_ID_LC1].handler(METAL_INTERRUPT_ID_LC1, priv);
+ }
+}
+
+/* The metal_lc2_interrupt_vector_handler() function can be redefined. */
+void __attribute__((weak, interrupt)) metal_lc2_interrupt_vector_handler (void) {
+ void *priv;
+ struct __metal_driver_riscv_cpu_intc *intc;
+ struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()];
+
+ if ( cpu ) {
+ intc = (struct __metal_driver_riscv_cpu_intc *)
+ __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu);
+ priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC2].exint_data;
+ intc->metal_int_table[METAL_INTERRUPT_ID_LC2].handler(METAL_INTERRUPT_ID_LC2, priv);
+ }
+}
+
+/* The metal_lc3_interrupt_vector_handler() function can be redefined. */
+void __attribute__((weak, interrupt)) metal_lc3_interrupt_vector_handler (void) {
+ void *priv;
+ struct __metal_driver_riscv_cpu_intc *intc;
+ struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()];
+
+ if ( cpu ) {
+ intc = (struct __metal_driver_riscv_cpu_intc *)
+ __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu);
+ priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC3].exint_data;
+ intc->metal_int_table[METAL_INTERRUPT_ID_LC3].handler(METAL_INTERRUPT_ID_LC3, priv);
+ }
+}
+
+/* The metal_lc4_interrupt_vector_handler() function can be redefined. */
+void __attribute__((weak, interrupt)) metal_lc4_interrupt_vector_handler (void) {
+ void *priv;
+ struct __metal_driver_riscv_cpu_intc *intc;
+ struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()];
+
+ if ( cpu ) {
+ intc = (struct __metal_driver_riscv_cpu_intc *)
+ __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu);
+ priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC4].exint_data;
+ intc->metal_int_table[METAL_INTERRUPT_ID_LC4].handler(METAL_INTERRUPT_ID_LC4, priv);
+ }
+}
+
+/* The metal_lc5_interrupt_vector_handler() function can be redefined. */
+void __attribute__((weak, interrupt)) metal_lc5_interrupt_vector_handler (void) {
+ void *priv;
+ struct __metal_driver_riscv_cpu_intc *intc;
+ struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()];
+
+ if ( cpu ) {
+ intc = (struct __metal_driver_riscv_cpu_intc *)
+ __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu);
+ priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC5].exint_data;
+ intc->metal_int_table[METAL_INTERRUPT_ID_LC5].handler(METAL_INTERRUPT_ID_LC5, priv);
+ }
+}
+
+/* The metal_lc6_interrupt_vector_handler() function can be redefined. */
+void __attribute__((weak, interrupt)) metal_lc6_interrupt_vector_handler (void) {
+ void *priv;
+ struct __metal_driver_riscv_cpu_intc *intc;
+ struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()];
+
+ if ( cpu ) {
+ intc = (struct __metal_driver_riscv_cpu_intc *)
+ __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu);
+ priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC6].exint_data;
+ intc->metal_int_table[METAL_INTERRUPT_ID_LC6].handler(METAL_INTERRUPT_ID_LC6, priv);
+ }
+}
+
+/* The metal_lc7_interrupt_vector_handler() function can be redefined. */
+void __attribute__((weak, interrupt)) metal_lc7_interrupt_vector_handler (void) {
+ void *priv;
+ struct __metal_driver_riscv_cpu_intc *intc;
+ struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()];
+
+ if ( cpu ) {
+ intc = (struct __metal_driver_riscv_cpu_intc *)
+ __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu);
+ priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC7].exint_data;
+ intc->metal_int_table[METAL_INTERRUPT_ID_LC7].handler(METAL_INTERRUPT_ID_LC7, priv);
+ }
+}
+
+/* The metal_lc8_interrupt_vector_handler() function can be redefined. */
+void __attribute__((weak, interrupt)) metal_lc8_interrupt_vector_handler (void) {
+ void *priv;
+ struct __metal_driver_riscv_cpu_intc *intc;
+ struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()];
+
+ if ( cpu ) {
+ intc = (struct __metal_driver_riscv_cpu_intc *)
+ __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu);
+ priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC8].exint_data;
+ intc->metal_int_table[METAL_INTERRUPT_ID_LC8].handler(METAL_INTERRUPT_ID_LC8, priv);
+ }
+}
+
+/* The metal_lc9_interrupt_vector_handler() function can be redefined. */
+void __attribute__((weak, interrupt)) metal_lc9_interrupt_vector_handler (void) {
+ void *priv;
+ struct __metal_driver_riscv_cpu_intc *intc;
+ struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()];
+
+ if ( cpu ) {
+ intc = (struct __metal_driver_riscv_cpu_intc *)
+ __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu);
+ priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC9].exint_data;
+ intc->metal_int_table[METAL_INTERRUPT_ID_LC9].handler(METAL_INTERRUPT_ID_LC9, priv);
+ }
+}
+
+/* The metal_lc10_interrupt_vector_handler() function can be redefined. */
+void __attribute__((weak, interrupt)) metal_lc10_interrupt_vector_handler (void) {
+ void *priv;
+ struct __metal_driver_riscv_cpu_intc *intc;
+ struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()];
+
+ if ( cpu ) {
+ intc = (struct __metal_driver_riscv_cpu_intc *)
+ __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu);
+ priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC10].exint_data;
+ intc->metal_int_table[METAL_INTERRUPT_ID_LC10].handler(METAL_INTERRUPT_ID_LC10, priv);
+ }
+}
+
+/* The metal_lc11_interrupt_vector_handler() function can be redefined. */
+void __attribute__((weak, interrupt)) metal_lc11_interrupt_vector_handler (void) {
+ void *priv;
+ struct __metal_driver_riscv_cpu_intc *intc;
+ struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()];
+
+ if ( cpu ) {
+ intc = (struct __metal_driver_riscv_cpu_intc *)
+ __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu);
+ priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC11].exint_data;
+ intc->metal_int_table[METAL_INTERRUPT_ID_LC11].handler(METAL_INTERRUPT_ID_LC11, priv);
+ }
+}
+
+/* The metal_lc12_interrupt_vector_handler() function can be redefined. */
+void __attribute__((weak, interrupt)) metal_lc12_interrupt_vector_handler (void) {
+ void *priv;
+ struct __metal_driver_riscv_cpu_intc *intc;
+ struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()];
+
+ if ( cpu ) {
+ intc = (struct __metal_driver_riscv_cpu_intc *)
+ __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu);
+ priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC12].exint_data;
+ intc->metal_int_table[METAL_INTERRUPT_ID_LC12].handler(METAL_INTERRUPT_ID_LC12, priv);
+ }
+}
+
+/* The metal_lc13_interrupt_vector_handler() function can be redefined. */
+void __attribute__((weak, interrupt)) metal_lc13_interrupt_vector_handler (void) {
+ void *priv;
+ struct __metal_driver_riscv_cpu_intc *intc;
+ struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()];
+
+ if ( cpu ) {
+ intc = (struct __metal_driver_riscv_cpu_intc *)
+ __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu);
+ priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC13].exint_data;
+ intc->metal_int_table[METAL_INTERRUPT_ID_LC13].handler(METAL_INTERRUPT_ID_LC13, priv);
+ }
+}
+
+/* The metal_lc14_interrupt_vector_handler() function can be redefined. */
+void __attribute__((weak, interrupt)) metal_lc14_interrupt_vector_handler (void) {
+ void *priv;
+ struct __metal_driver_riscv_cpu_intc *intc;
+ struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()];
+
+ if ( cpu ) {
+ intc = (struct __metal_driver_riscv_cpu_intc *)
+ __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu);
+ priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC14].exint_data;
+ intc->metal_int_table[METAL_INTERRUPT_ID_LC14].handler(METAL_INTERRUPT_ID_LC14, priv);
+ }
+}
+
+/* The metal_lc15_interrupt_vector_handler() function can be redefined. */
+void __attribute__((weak, interrupt)) metal_lc15_interrupt_vector_handler (void) {
+ void *priv;
+ struct __metal_driver_riscv_cpu_intc *intc;
+ struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()];
+
+ if ( cpu ) {
+ intc = (struct __metal_driver_riscv_cpu_intc *)
+ __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu);
+ priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC15].exint_data;
+ intc->metal_int_table[METAL_INTERRUPT_ID_LC15].handler(METAL_INTERRUPT_ID_LC15, priv);
+ }
+}
+
+metal_vector_mode __metal_controller_interrupt_vector_mode (void)
+{
+ uintptr_t val;
+
+ asm volatile ("csrr %0, mtvec" : "=r"(val));
+ val &= METAL_MTVEC_MASK;
+
+ switch (val) {
+ case METAL_MTVEC_CLIC:
+ return METAL_SELECTIVE_VECTOR_MODE;
+ case METAL_MTVEC_CLIC_VECTORED:
+ return METAL_HARDWARE_VECTOR_MODE;
+ case METAL_MTVEC_VECTORED:
+ return METAL_VECTOR_MODE;
+ }
+ return METAL_DIRECT_MODE;
+}
+