summaryrefslogtreecommitdiff
path: root/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_cpu.c')
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_cpu.c839
1 files changed, 358 insertions, 481 deletions
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_cpu.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_cpu.c
index b693f312a..dda13b934 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_cpu.c
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_cpu.c
@@ -1,145 +1,157 @@
/* Copyright 2018 SiFive, Inc */
/* SPDX-License-Identifier: Apache-2.0 */
-#include <stdint.h>
#include <metal/io.h>
-#include <metal/shutdown.h>
#include <metal/machine.h>
+#include <metal/shutdown.h>
+#include <stdint.h>
+
+#define __METAL_IRQ_VECTOR_HANDLER(id) \
+ 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[id].exint_data; \
+ intc->metal_int_table[id].handler(id, priv); \
+ }
extern void __metal_vector_table();
unsigned long long __metal_driver_cpu_mtime_get(struct metal_cpu *cpu);
-int __metal_driver_cpu_mtimecmp_set(struct metal_cpu *cpu, unsigned long long time);
+int __metal_driver_cpu_mtimecmp_set(struct metal_cpu *cpu,
+ unsigned long long time);
-struct metal_cpu *__metal_driver_cpu_get(int hartid)
-{
+struct metal_cpu *__metal_driver_cpu_get(int hartid) {
if (hartid < __METAL_DT_MAX_HARTS) {
return &(__metal_cpu_table[hartid]->cpu);
}
return (struct metal_cpu *)NULL;
}
-uintptr_t __metal_myhart_id (void)
-{
+uintptr_t __metal_myhart_id(void) {
uintptr_t myhart;
- __asm__ volatile ("csrr %0, mhartid" : "=r"(myhart));
+ __asm__ volatile("csrr %0, mhartid" : "=r"(myhart));
return myhart;
}
-void __metal_zero_memory (unsigned char *base, unsigned int size)
-{
+void __metal_zero_memory(unsigned char *base, unsigned int size) {
volatile unsigned char *ptr;
- for (ptr = base; ptr < (base + size); ptr++){
+ for (ptr = base; ptr < (base + size); ptr++) {
*ptr = 0;
}
}
-void __metal_interrupt_global_enable (void) {
+void __metal_interrupt_global_enable(void) {
uintptr_t m;
- __asm__ volatile ("csrrs %0, mstatus, %1" : "=r"(m) : "r"(METAL_MIE_INTERRUPT));
+ __asm__ volatile("csrrs %0, mstatus, %1"
+ : "=r"(m)
+ : "r"(METAL_MIE_INTERRUPT));
}
-void __metal_interrupt_global_disable (void) {
+void __metal_interrupt_global_disable(void) {
uintptr_t m;
- __asm__ volatile ("csrrc %0, mstatus, %1" : "=r"(m) : "r"(METAL_MIE_INTERRUPT));
+ __asm__ volatile("csrrc %0, mstatus, %1"
+ : "=r"(m)
+ : "r"(METAL_MIE_INTERRUPT));
}
-void __metal_interrupt_software_enable (void) {
+void __metal_interrupt_software_enable(void) {
uintptr_t m;
- __asm__ volatile ("csrrs %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_SW));
+ __asm__ volatile("csrrs %0, mie, %1"
+ : "=r"(m)
+ : "r"(METAL_LOCAL_INTERRUPT_SW));
}
-void __metal_interrupt_software_disable (void) {
+void __metal_interrupt_software_disable(void) {
uintptr_t m;
- __asm__ volatile ("csrrc %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_SW));
+ __asm__ volatile("csrrc %0, mie, %1"
+ : "=r"(m)
+ : "r"(METAL_LOCAL_INTERRUPT_SW));
}
-void __metal_interrupt_timer_enable (void) {
+void __metal_interrupt_timer_enable(void) {
uintptr_t m;
- __asm__ volatile ("csrrs %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_TMR));
+ __asm__ volatile("csrrs %0, mie, %1"
+ : "=r"(m)
+ : "r"(METAL_LOCAL_INTERRUPT_TMR));
}
-void __metal_interrupt_timer_disable (void) {
+void __metal_interrupt_timer_disable(void) {
uintptr_t m;
- __asm__ volatile ("csrrc %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_TMR));
+ __asm__ volatile("csrrc %0, mie, %1"
+ : "=r"(m)
+ : "r"(METAL_LOCAL_INTERRUPT_TMR));
}
-void __metal_interrupt_external_enable (void) {
+void __metal_interrupt_external_enable(void) {
uintptr_t m;
- __asm__ volatile ("csrrs %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_EXT));
+ __asm__ volatile("csrrs %0, mie, %1"
+ : "=r"(m)
+ : "r"(METAL_LOCAL_INTERRUPT_EXT));
}
-void __metal_interrupt_external_disable (void) {
+void __metal_interrupt_external_disable(void) {
unsigned long m;
- __asm__ volatile ("csrrc %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_EXT));
+ __asm__ volatile("csrrc %0, mie, %1"
+ : "=r"(m)
+ : "r"(METAL_LOCAL_INTERRUPT_EXT));
}
-void __metal_interrupt_local_enable (int id) {
+void __metal_interrupt_local_enable(int id) {
uintptr_t b = 1 << id;
uintptr_t m;
- __asm__ volatile ("csrrs %0, mie, %1" : "=r"(m) : "r"(b));
+ __asm__ volatile("csrrs %0, mie, %1" : "=r"(m) : "r"(b));
}
-void __metal_interrupt_local_disable (int id) {
+void __metal_interrupt_local_disable(int id) {
uintptr_t b = 1 << id;
uintptr_t m;
- __asm__ volatile ("csrrc %0, mie, %1" : "=r"(m) : "r"(b));
+ __asm__ volatile("csrrc %0, mie, %1" : "=r"(m) : "r"(b));
}
-void __metal_default_exception_handler (struct metal_cpu *cpu, int ecode) {
+void __metal_default_exception_handler(struct metal_cpu *cpu, int ecode) {
metal_shutdown(100);
}
-void __metal_default_interrupt_handler (int id, void *priv) {
+void __metal_default_interrupt_handler(int id, void *priv) {
metal_shutdown(200);
}
/* The metal_interrupt_vector_handler() function can be redefined. */
-void __attribute__((weak, interrupt)) metal_interrupt_vector_handler (void) {
+void __attribute__((weak, interrupt)) metal_interrupt_vector_handler(void) {
metal_shutdown(300);
}
/* The metal_software_interrupt_vector_handler() function can be redefined. */
-void __attribute__((weak, interrupt)) metal_software_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_SW].exint_data;
- intc->metal_int_table[METAL_INTERRUPT_ID_SW].handler(METAL_INTERRUPT_ID_SW, priv);
- }
+void __attribute__((weak, interrupt))
+metal_software_interrupt_vector_handler(void) {
+ __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_SW);
}
-void __metal_default_sw_handler (int id, void *priv) {
+void __metal_default_sw_handler(int id, void *priv) {
uintptr_t mcause;
struct __metal_driver_riscv_cpu_intc *intc;
struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()];
- __asm__ volatile ("csrr %0, mcause" : "=r"(mcause));
- if ( cpu ) {
+ __asm__ volatile("csrr %0, mcause" : "=r"(mcause));
+ if (cpu) {
intc = (struct __metal_driver_riscv_cpu_intc *)
- __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu);
- intc->metal_exception_table[mcause & METAL_MCAUSE_CAUSE]((struct metal_cpu *)cpu, id);
+ __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu);
+ intc->metal_exception_table[mcause & METAL_MCAUSE_CAUSE](
+ (struct metal_cpu *)cpu, id);
}
}
/* The metal_timer_interrupt_vector_handler() function can be redefined. */
-void __attribute__((weak, interrupt)) metal_timer_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_TMR].exint_data;
- intc->metal_int_table[METAL_INTERRUPT_ID_TMR].handler(METAL_INTERRUPT_ID_TMR, priv);
- }
+void __attribute__((weak, interrupt))
+metal_timer_interrupt_vector_handler(void) {
+ __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_TMR);
}
-void __metal_default_timer_handler (int id, void *priv) {
+void __metal_default_beu_handler(int id, void *priv) {}
+
+void __metal_default_timer_handler(int id, void *priv) {
struct metal_cpu *cpu = __metal_driver_cpu_get(__metal_myhart_id());
unsigned long long time = __metal_driver_cpu_mtime_get(cpu);
@@ -148,52 +160,49 @@ void __metal_default_timer_handler (int id, void *priv) {
}
/* The metal_external_interrupt_vector_handler() function can be redefined. */
-void __attribute__((weak, interrupt)) metal_external_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_EXT].exint_data;
- intc->metal_int_table[METAL_INTERRUPT_ID_EXT].handler(METAL_INTERRUPT_ID_EXT, priv);
- }
+void __attribute__((weak, interrupt))
+metal_external_interrupt_vector_handler(void) {
+ __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_EXT);
}
void __metal_exception_handler(void) __attribute__((interrupt, aligned(128)));
-void __metal_exception_handler (void) {
+void __metal_exception_handler(void) {
int id;
void *priv;
uintptr_t mcause, mepc, mtval, mtvec;
struct __metal_driver_riscv_cpu_intc *intc;
struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()];
- __asm__ volatile ("csrr %0, mcause" : "=r"(mcause));
- __asm__ volatile ("csrr %0, mepc" : "=r"(mepc));
- __asm__ volatile ("csrr %0, mtval" : "=r"(mtval));
- __asm__ volatile ("csrr %0, mtvec" : "=r"(mtvec));
+ __asm__ volatile("csrr %0, mcause" : "=r"(mcause));
+ __asm__ volatile("csrr %0, mepc" : "=r"(mepc));
+ __asm__ volatile("csrr %0, mtval" : "=r"(mtval));
+ __asm__ volatile("csrr %0, mtvec" : "=r"(mtvec));
- if ( cpu ) {
+ if (cpu) {
intc = (struct __metal_driver_riscv_cpu_intc *)
- __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu);
+ __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu);
id = mcause & METAL_MCAUSE_CAUSE;
if (mcause & METAL_MCAUSE_INTR) {
+ if (id == METAL_INTERRUPT_ID_BEU) {
+ priv = intc->metal_int_beu.exint_data;
+ intc->metal_int_beu.handler(id, priv);
+ return;
+ }
if ((id < METAL_INTERRUPT_ID_CSW) ||
- ((mtvec & METAL_MTVEC_MASK) == METAL_MTVEC_DIRECT)) {
+ ((mtvec & METAL_MTVEC_MASK) == METAL_MTVEC_DIRECT)) {
priv = intc->metal_int_table[id].exint_data;
intc->metal_int_table[id].handler(id, priv);
- return;
+ return;
}
if ((mtvec & METAL_MTVEC_MASK) == METAL_MTVEC_CLIC) {
- uintptr_t mtvt;
- metal_interrupt_handler_t mtvt_handler;
-
- __asm__ volatile ("csrr %0, 0x307" : "=r"(mtvt));
- priv = intc->metal_int_table[METAL_INTERRUPT_ID_SW].sub_int;
- mtvt_handler = (metal_interrupt_handler_t)*(uintptr_t *)mtvt;
- mtvt_handler(id, priv);
- return;
+ uintptr_t mtvt;
+ metal_interrupt_handler_t mtvt_handler;
+
+ __asm__ volatile("csrr %0, 0x307" : "=r"(mtvt));
+ priv = intc->metal_int_table[METAL_INTERRUPT_ID_SW].sub_int;
+ mtvt_handler = (metal_interrupt_handler_t) * (uintptr_t *)mtvt;
+ mtvt_handler(id, priv);
+ return;
}
} else {
intc->metal_exception_table[id]((struct metal_cpu *)cpu, id);
@@ -202,234 +211,95 @@ void __metal_exception_handler (void) {
}
/* 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);
- }
+void __attribute__((weak, interrupt)) metal_lc0_interrupt_vector_handler(void) {
+ __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC0);
}
/* 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);
- }
+void __attribute__((weak, interrupt)) metal_lc1_interrupt_vector_handler(void) {
+ __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC1);
}
/* 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);
- }
+void __attribute__((weak, interrupt)) metal_lc2_interrupt_vector_handler(void) {
+ __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC2);
}
/* 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);
- }
+void __attribute__((weak, interrupt)) metal_lc3_interrupt_vector_handler(void) {
+ __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC3);
}
/* 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);
- }
+void __attribute__((weak, interrupt)) metal_lc4_interrupt_vector_handler(void) {
+ __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC4);
}
/* 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);
- }
+void __attribute__((weak, interrupt)) metal_lc5_interrupt_vector_handler(void) {
+ __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC5);
}
/* 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);
- }
+void __attribute__((weak, interrupt)) metal_lc6_interrupt_vector_handler(void) {
+ __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC6);
}
/* 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);
- }
+void __attribute__((weak, interrupt)) metal_lc7_interrupt_vector_handler(void) {
+ __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC7);
}
/* 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);
- }
+void __attribute__((weak, interrupt)) metal_lc8_interrupt_vector_handler(void) {
+ __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC8);
}
/* 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);
- }
+void __attribute__((weak, interrupt)) metal_lc9_interrupt_vector_handler(void) {
+ __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC9);
}
/* 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);
- }
+void __attribute__((weak, interrupt))
+metal_lc10_interrupt_vector_handler(void) {
+ __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC10);
}
/* 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);
- }
+void __attribute__((weak, interrupt))
+metal_lc11_interrupt_vector_handler(void) {
+ __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC11);
}
/* 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);
- }
+void __attribute__((weak, interrupt))
+metal_lc12_interrupt_vector_handler(void) {
+ __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC12);
}
/* 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);
- }
+void __attribute__((weak, interrupt))
+metal_lc13_interrupt_vector_handler(void) {
+ __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC13);
}
/* 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);
- }
+void __attribute__((weak, interrupt))
+metal_lc14_interrupt_vector_handler(void) {
+ __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC14);
}
/* 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);
- }
+void __attribute__((weak, interrupt))
+metal_lc15_interrupt_vector_handler(void) {
+ __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC15);
}
-metal_vector_mode __metal_controller_interrupt_vector_mode (void)
-{
+metal_vector_mode __metal_controller_interrupt_vector_mode(void) {
uintptr_t val;
- asm volatile ("csrr %0, mtvec" : "=r"(val));
+ __asm__ volatile("csrr %0, mtvec" : "=r"(val));
val &= METAL_MTVEC_MASK;
switch (val) {
@@ -443,35 +313,37 @@ metal_vector_mode __metal_controller_interrupt_vector_mode (void)
return METAL_DIRECT_MODE;
}
-void __metal_controller_interrupt_vector (metal_vector_mode mode, void *vec_table)
-{
+void __metal_controller_interrupt_vector(metal_vector_mode mode,
+ void *vec_table) {
uintptr_t trap_entry, val;
- __asm__ volatile ("csrr %0, mtvec" : "=r"(val));
+ __asm__ volatile("csrr %0, mtvec" : "=r"(val));
val &= ~(METAL_MTVEC_CLIC_VECTORED | METAL_MTVEC_CLIC_RESERVED);
trap_entry = (uintptr_t)vec_table;
switch (mode) {
case METAL_SELECTIVE_NONVECTOR_MODE:
case METAL_SELECTIVE_VECTOR_MODE:
- __asm__ volatile ("csrw 0x307, %0" :: "r"(trap_entry));
- __asm__ volatile ("csrw mtvec, %0" :: "r"(val | METAL_MTVEC_CLIC));
+ __asm__ volatile("csrw 0x307, %0" ::"r"(trap_entry));
+ __asm__ volatile("csrw mtvec, %0" ::"r"(val | METAL_MTVEC_CLIC));
break;
case METAL_HARDWARE_VECTOR_MODE:
- __asm__ volatile ("csrw 0x307, %0" :: "r"(trap_entry));
- __asm__ volatile ("csrw mtvec, %0" :: "r"(val | METAL_MTVEC_CLIC_VECTORED));
+ __asm__ volatile("csrw 0x307, %0" ::"r"(trap_entry));
+ __asm__ volatile(
+ "csrw mtvec, %0" ::"r"(val | METAL_MTVEC_CLIC_VECTORED));
break;
case METAL_VECTOR_MODE:
- __asm__ volatile ("csrw mtvec, %0" :: "r"(trap_entry | METAL_MTVEC_VECTORED));
+ __asm__ volatile(
+ "csrw mtvec, %0" ::"r"(trap_entry | METAL_MTVEC_VECTORED));
break;
case METAL_DIRECT_MODE:
- __asm__ volatile ("csrw mtvec, %0" :: "r"(trap_entry & ~METAL_MTVEC_CLIC_VECTORED));
+ __asm__ volatile(
+ "csrw mtvec, %0" ::"r"(trap_entry & ~METAL_MTVEC_CLIC_VECTORED));
break;
}
}
-int __metal_valid_interrupt_id (int id)
-{
+int __metal_valid_interrupt_id(int id) {
switch (id) {
case METAL_INTERRUPT_ID_SW:
case METAL_INTERRUPT_ID_TMR:
@@ -492,6 +364,7 @@ int __metal_valid_interrupt_id (int id)
case METAL_INTERRUPT_ID_LC13:
case METAL_INTERRUPT_ID_LC14:
case METAL_INTERRUPT_ID_LC15:
+ case METAL_INTERRUPT_ID_BEU:
return 1;
default:
break;
@@ -500,13 +373,11 @@ int __metal_valid_interrupt_id (int id)
return 0;
}
-
-int __metal_local_interrupt_enable (struct metal_interrupt *controller,
- metal_interrupt_id_e id, int enable)
-{
+int __metal_local_interrupt_enable(struct metal_interrupt *controller,
+ metal_interrupt_id_e id, int enable) {
int rc = 0;
-
- if ( !controller) {
+
+ if (!controller) {
return -1;
}
@@ -527,11 +398,11 @@ int __metal_local_interrupt_enable (struct metal_interrupt *controller,
break;
case METAL_INTERRUPT_ID_TMR:
if (enable) {
- __metal_interrupt_timer_enable();
- } else {
- __metal_interrupt_timer_disable();
- }
- break;
+ __metal_interrupt_timer_enable();
+ } else {
+ __metal_interrupt_timer_disable();
+ }
+ break;
case METAL_INTERRUPT_ID_EXT:
if (enable) {
__metal_interrupt_external_enable();
@@ -567,9 +438,8 @@ int __metal_local_interrupt_enable (struct metal_interrupt *controller,
return rc;
}
-int __metal_exception_register (struct metal_interrupt *controller,
- int ecode, metal_exception_handler_t isr)
-{
+int __metal_exception_register(struct metal_interrupt *controller, int ecode,
+ metal_exception_handler_t isr) {
struct __metal_driver_riscv_cpu_intc *intc = (void *)(controller);
if ((ecode < METAL_MAX_EXCEPTION_CODE) && isr) {
@@ -579,199 +449,198 @@ int __metal_exception_register (struct metal_interrupt *controller,
return -1;
}
-void __metal_driver_riscv_cpu_controller_interrupt_init (struct metal_interrupt *controller)
-{
+extern void early_trap_vector(void);
+void __metal_driver_riscv_cpu_controller_interrupt_init(
+ struct metal_interrupt *controller) {
struct __metal_driver_riscv_cpu_intc *intc = (void *)(controller);
- uintptr_t val;
-
- if ( !intc->init_done ) {
- /* Disable and clear all interrupt sources */
- __asm__ volatile ("csrc mie, %0" :: "r"(-1));
- __asm__ volatile ("csrc mip, %0" :: "r"(-1));
-
- /* Read the misa CSR to determine if the delegation registers exist */
- uintptr_t misa;
- __asm__ volatile ("csrr %0, misa" : "=r" (misa));
-
- /* The delegation CSRs exist if user mode interrupts (N extension) or
- * supervisor mode (S extension) are supported */
- if((misa & METAL_ISA_N_EXTENSIONS) || (misa & METAL_ISA_S_EXTENSIONS)) {
- /* Disable interrupt and exception delegation */
- __asm__ volatile ("csrc mideleg, %0" :: "r"(-1));
- __asm__ volatile ("csrc medeleg, %0" :: "r"(-1));
- }
-
- /* The satp CSR exists if supervisor mode (S extension) is supported */
- if(misa & METAL_ISA_S_EXTENSIONS) {
- /* Clear the entire CSR to make sure that satp.MODE = 0 */
- __asm__ volatile ("csrc satp, %0" :: "r"(-1));
- }
+ if (!intc->init_done) {
/* Default to use direct interrupt, setup sw cb table*/
for (int i = 0; i < METAL_MAX_MI; i++) {
intc->metal_int_table[i].handler = NULL;
intc->metal_int_table[i].sub_int = NULL;
intc->metal_int_table[i].exint_data = NULL;
- }
- for (int i = 0; i < METAL_MAX_ME; i++) {
- intc->metal_exception_table[i] = __metal_default_exception_handler;
- }
- __metal_controller_interrupt_vector(METAL_DIRECT_MODE, (void *)(uintptr_t)&__metal_exception_handler);
- __asm__ volatile ("csrr %0, misa" : "=r"(val));
- if (val & (METAL_ISA_D_EXTENSIONS | METAL_ISA_F_EXTENSIONS | METAL_ISA_Q_EXTENSIONS)) {
- /* Floating point architecture, so turn on FP register saving*/
- __asm__ volatile ("csrr %0, mstatus" : "=r"(val));
- __asm__ volatile ("csrw mstatus, %0" :: "r"(val | METAL_MSTATUS_FS_INIT));
- }
- intc->init_done = 1;
+ }
+
+ for (int i = 0; i < METAL_MAX_ME; i++) {
+ intc->metal_exception_table[i] = __metal_default_exception_handler;
+ }
+
+ /*
+ * Set the real trap handler if the value of mtvec is equal to
+ * early_trap_vector. If mtvec is not equal to early_trap_vector,
+ * that means user has own trap handler, then we don't overwrite it.
+ */
+ uintptr_t mtvec;
+ __asm__ volatile("csrr %0, mtvec" : "=r"(mtvec));
+ if (mtvec == (uintptr_t)&early_trap_vector) {
+ __metal_controller_interrupt_vector(
+ METAL_DIRECT_MODE,
+ (void *)(uintptr_t)&__metal_exception_handler);
+ }
+ intc->init_done = 1;
}
}
-int __metal_driver_riscv_cpu_controller_interrupt_register(struct metal_interrupt *controller,
- int id, metal_interrupt_handler_t isr,
- void *priv)
-{
+int __metal_driver_riscv_cpu_controller_interrupt_register(
+ struct metal_interrupt *controller, int id, metal_interrupt_handler_t isr,
+ void *priv) {
int rc = 0;
struct __metal_driver_riscv_cpu_intc *intc = (void *)(controller);
-
- if ( !__metal_valid_interrupt_id(id) ) {
+
+ if (!__metal_valid_interrupt_id(id)) {
return -11;
}
+ if ((id == METAL_INTERRUPT_ID_BEU) &&
+ (__metal_controller_interrupt_vector_mode() != METAL_DIRECT_MODE)) {
+ /* Only allow registration of the bus error unit interrupt if
+ * interrupt vectoring if off */
+ return -13;
+ }
if (isr) {
- intc->metal_int_table[id].handler = isr;
- intc->metal_int_table[id].exint_data = priv;
+ if (id == METAL_INTERRUPT_ID_BEU) {
+ intc->metal_int_beu.handler = isr;
+ intc->metal_int_beu.exint_data = priv;
+ } else {
+ intc->metal_int_table[id].handler = isr;
+ intc->metal_int_table[id].exint_data = priv;
+ }
} else {
- switch (id) {
- case METAL_INTERRUPT_ID_SW:
+ switch (id) {
+ case METAL_INTERRUPT_ID_SW:
intc->metal_int_table[id].handler = __metal_default_sw_handler;
intc->metal_int_table[id].sub_int = priv;
- break;
- case METAL_INTERRUPT_ID_TMR:
+ break;
+ case METAL_INTERRUPT_ID_TMR:
intc->metal_int_table[id].handler = __metal_default_timer_handler;
intc->metal_int_table[id].sub_int = priv;
- break;
- case METAL_INTERRUPT_ID_EXT:
- case METAL_INTERRUPT_ID_LC0:
- case METAL_INTERRUPT_ID_LC1:
- case METAL_INTERRUPT_ID_LC2:
- case METAL_INTERRUPT_ID_LC3:
- case METAL_INTERRUPT_ID_LC4:
- case METAL_INTERRUPT_ID_LC5:
- case METAL_INTERRUPT_ID_LC6:
- case METAL_INTERRUPT_ID_LC7:
- case METAL_INTERRUPT_ID_LC8:
- case METAL_INTERRUPT_ID_LC9:
- case METAL_INTERRUPT_ID_LC10:
- case METAL_INTERRUPT_ID_LC11:
- case METAL_INTERRUPT_ID_LC12:
- case METAL_INTERRUPT_ID_LC13:
- case METAL_INTERRUPT_ID_LC14:
- case METAL_INTERRUPT_ID_LC15:
- intc->metal_int_table[id].handler = __metal_default_interrupt_handler;
+ break;
+ case METAL_INTERRUPT_ID_BEU:
+ intc->metal_int_beu.handler = __metal_default_beu_handler;
+ intc->metal_int_beu.exint_data = priv;
+ break;
+ case METAL_INTERRUPT_ID_EXT:
+ case METAL_INTERRUPT_ID_LC0:
+ case METAL_INTERRUPT_ID_LC1:
+ case METAL_INTERRUPT_ID_LC2:
+ case METAL_INTERRUPT_ID_LC3:
+ case METAL_INTERRUPT_ID_LC4:
+ case METAL_INTERRUPT_ID_LC5:
+ case METAL_INTERRUPT_ID_LC6:
+ case METAL_INTERRUPT_ID_LC7:
+ case METAL_INTERRUPT_ID_LC8:
+ case METAL_INTERRUPT_ID_LC9:
+ case METAL_INTERRUPT_ID_LC10:
+ case METAL_INTERRUPT_ID_LC11:
+ case METAL_INTERRUPT_ID_LC12:
+ case METAL_INTERRUPT_ID_LC13:
+ case METAL_INTERRUPT_ID_LC14:
+ case METAL_INTERRUPT_ID_LC15:
+ intc->metal_int_table[id].handler =
+ __metal_default_interrupt_handler;
intc->metal_int_table[id].sub_int = priv;
- break;
- default:
- rc = -12;
- }
+ break;
+ default:
+ rc = -12;
+ }
}
return rc;
}
-int __metal_driver_riscv_cpu_controller_interrupt_enable (struct metal_interrupt *controller,
- int id)
-{
+int __metal_driver_riscv_cpu_controller_interrupt_enable(
+ struct metal_interrupt *controller, int id) {
return __metal_local_interrupt_enable(controller, id, METAL_ENABLE);
}
-int __metal_driver_riscv_cpu_controller_interrupt_disable (struct metal_interrupt *controller,
- int id)
-{
+int __metal_driver_riscv_cpu_controller_interrupt_disable(
+ struct metal_interrupt *controller, int id) {
return __metal_local_interrupt_enable(controller, id, METAL_DISABLE);
}
-int __metal_driver_riscv_cpu_controller_interrupt_enable_vector(struct metal_interrupt *controller,
- int id, metal_vector_mode mode)
-{
+int __metal_driver_riscv_cpu_controller_interrupt_enable_vector(
+ struct metal_interrupt *controller, int id, metal_vector_mode mode) {
struct __metal_driver_riscv_cpu_intc *intc = (void *)(controller);
if (id == METAL_INTERRUPT_ID_BASE) {
if (mode == METAL_DIRECT_MODE) {
- __metal_controller_interrupt_vector(mode, (void *)(uintptr_t)&__metal_exception_handler);
+ __metal_controller_interrupt_vector(
+ mode, (void *)(uintptr_t)&__metal_exception_handler);
return 0;
- }
+ }
if (mode == METAL_VECTOR_MODE) {
- __metal_controller_interrupt_vector(mode, (void *)&intc->metal_mtvec_table);
+ __metal_controller_interrupt_vector(
+ mode, (void *)&intc->metal_mtvec_table);
return 0;
}
}
return -1;
}
-int __metal_driver_riscv_cpu_controller_interrupt_disable_vector(struct metal_interrupt *controller,
- int id)
-{
+int __metal_driver_riscv_cpu_controller_interrupt_disable_vector(
+ struct metal_interrupt *controller, int id) {
if (id == METAL_INTERRUPT_ID_BASE) {
- __metal_controller_interrupt_vector(METAL_DIRECT_MODE, (void *)(uintptr_t)&__metal_exception_handler);
+ __metal_controller_interrupt_vector(
+ METAL_DIRECT_MODE, (void *)(uintptr_t)&__metal_exception_handler);
return 0;
}
return -1;
}
-metal_vector_mode __metal_driver_riscv_cpu_controller_get_vector_mode (struct metal_interrupt *controller)
-{
+metal_vector_mode __metal_driver_riscv_cpu_controller_get_vector_mode(
+ struct metal_interrupt *controller) {
return __metal_controller_interrupt_vector_mode();
}
-int __metal_driver_riscv_cpu_controller_set_vector_mode (struct metal_interrupt *controller,
- metal_vector_mode mode)
-{
- struct __metal_driver_riscv_cpu_intc *intc = (void *)(controller);
- ( void ) intc;
+int __metal_driver_riscv_cpu_controller_set_vector_mode(
+ struct metal_interrupt *controller, metal_vector_mode mode) {
if (mode == METAL_DIRECT_MODE) {
- __metal_controller_interrupt_vector(mode, (void *)(uintptr_t)&__metal_exception_handler);
- return 0;
+ __metal_controller_interrupt_vector(
+ mode, (void *)(uintptr_t)&__metal_exception_handler);
+ return 0;
}
if (mode == METAL_VECTOR_MODE) {
- __metal_controller_interrupt_vector(mode, (void *)__metal_vector_table);
+ __metal_controller_interrupt_vector(
+ mode, (void *)(uintptr_t)__metal_vector_table);
return 0;
}
return -1;
}
-int __metal_driver_riscv_cpu_controller_command_request (struct metal_interrupt *controller,
- int cmd, void *data)
-{
- /* NOP for now, unless local interrupt lines the like of clic, clint, plic */
+int __metal_driver_riscv_cpu_controller_command_request(
+ struct metal_interrupt *controller, int cmd, void *data) {
+ /* NOP for now, unless local interrupt lines the like of clic, clint, plic
+ */
return 0;
}
/* CPU driver !!! */
-unsigned long long __metal_driver_cpu_mcycle_get(struct metal_cpu *cpu)
-{
+unsigned long long __metal_driver_cpu_mcycle_get(struct metal_cpu *cpu) {
unsigned long long val = 0;
#if __riscv_xlen == 32
unsigned long hi, hi1, lo;
- __asm__ volatile ("csrr %0, mcycleh" : "=r"(hi));
- __asm__ volatile ("csrr %0, mcycle" : "=r"(lo));
- __asm__ volatile ("csrr %0, mcycleh" : "=r"(hi1));
- if (hi == hi1) {
- val = ((unsigned long long)hi << 32) | lo;
- }
+ do {
+ __asm__ volatile("csrr %0, mcycleh" : "=r"(hi));
+ __asm__ volatile("csrr %0, mcycle" : "=r"(lo));
+ __asm__ volatile("csrr %0, mcycleh" : "=r"(hi1));
+ /* hi != hi1 means mcycle overflow during we get value,
+ * so we must retry. */
+ } while (hi != hi1);
+
+ val = ((unsigned long long)hi << 32) | lo;
#else
- __asm__ volatile ("csrr %0, mcycle" : "=r"(val));
+ __asm__ volatile("csrr %0, mcycle" : "=r"(val));
#endif
return val;
}
-unsigned long long __metal_driver_cpu_timebase_get(struct metal_cpu *cpu)
-{
- int timebase;
+unsigned long long __metal_driver_cpu_timebase_get(struct metal_cpu *cpu) {
+ int timebase;
if (!cpu) {
return 0;
}
@@ -780,44 +649,43 @@ unsigned long long __metal_driver_cpu_timebase_get(struct metal_cpu *cpu)
return timebase;
}
-unsigned long long __metal_driver_cpu_mtime_get (struct metal_cpu *cpu)
-{
+unsigned long long __metal_driver_cpu_mtime_get(struct metal_cpu *cpu) {
unsigned long long time = 0;
struct metal_interrupt *tmr_intc;
struct __metal_driver_riscv_cpu_intc *intc =
- (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu);
+ (struct __metal_driver_riscv_cpu_intc *)
+ __metal_driver_cpu_interrupt_controller(cpu);
if (intc) {
tmr_intc = intc->metal_int_table[METAL_INTERRUPT_ID_TMR].sub_int;
if (tmr_intc) {
- tmr_intc->vtable->command_request(tmr_intc,
- METAL_TIMER_MTIME_GET, &time);
+ tmr_intc->vtable->command_request(tmr_intc, METAL_TIMER_MTIME_GET,
+ &time);
}
}
return time;
}
-int __metal_driver_cpu_mtimecmp_set (struct metal_cpu *cpu, unsigned long long time)
-{
+int __metal_driver_cpu_mtimecmp_set(struct metal_cpu *cpu,
+ unsigned long long time) {
int rc = -1;
struct metal_interrupt *tmr_intc;
struct __metal_driver_riscv_cpu_intc *intc =
- (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu);
+ (struct __metal_driver_riscv_cpu_intc *)
+ __metal_driver_cpu_interrupt_controller(cpu);
if (intc) {
tmr_intc = intc->metal_int_table[METAL_INTERRUPT_ID_TMR].sub_int;
if (tmr_intc) {
- rc = tmr_intc->vtable->mtimecmp_set(tmr_intc,
- __metal_driver_cpu_hartid(cpu),
- time);
+ rc = tmr_intc->vtable->mtimecmp_set(
+ tmr_intc, __metal_driver_cpu_hartid(cpu), time);
}
}
return rc;
}
struct metal_interrupt *
-__metal_driver_cpu_timer_controller_interrupt(struct metal_cpu *cpu)
-{
+__metal_driver_cpu_timer_controller_interrupt(struct metal_cpu *cpu) {
#ifdef __METAL_DT_RISCV_CLINT0_HANDLE
return __METAL_DT_RISCV_CLINT0_HANDLE;
#else
@@ -830,14 +698,12 @@ __metal_driver_cpu_timer_controller_interrupt(struct metal_cpu *cpu)
#endif
}
-int __metal_driver_cpu_get_timer_interrupt_id(struct metal_cpu *cpu)
-{
+int __metal_driver_cpu_get_timer_interrupt_id(struct metal_cpu *cpu) {
return METAL_INTERRUPT_ID_TMR;
}
struct metal_interrupt *
-__metal_driver_cpu_sw_controller_interrupt(struct metal_cpu *cpu)
-{
+__metal_driver_cpu_sw_controller_interrupt(struct metal_cpu *cpu) {
#ifdef __METAL_DT_RISCV_CLINT0_HANDLE
return __METAL_DT_RISCV_CLINT0_HANDLE;
#else
@@ -850,142 +716,153 @@ __metal_driver_cpu_sw_controller_interrupt(struct metal_cpu *cpu)
#endif
}
-int __metal_driver_cpu_get_sw_interrupt_id(struct metal_cpu *cpu)
-{
+int __metal_driver_cpu_get_sw_interrupt_id(struct metal_cpu *cpu) {
return METAL_INTERRUPT_ID_SW;
}
-int __metal_driver_cpu_set_sw_ipi (struct metal_cpu *cpu, int hartid)
-{
+int __metal_driver_cpu_set_sw_ipi(struct metal_cpu *cpu, int hartid) {
int rc = -1;
struct metal_interrupt *sw_intc;
- struct __metal_driver_riscv_cpu_intc *intc =
- (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu);
+ struct __metal_driver_riscv_cpu_intc *intc =
+ (struct __metal_driver_riscv_cpu_intc *)
+ __metal_driver_cpu_interrupt_controller(cpu);
if (intc) {
sw_intc = intc->metal_int_table[METAL_INTERRUPT_ID_SW].sub_int;
if (sw_intc) {
- rc = sw_intc->vtable->command_request(sw_intc,
- METAL_SOFTWARE_IPI_SET, &hartid);
+ rc = sw_intc->vtable->command_request(
+ sw_intc, METAL_SOFTWARE_IPI_SET, &hartid);
}
}
return rc;
}
-int __metal_driver_cpu_clear_sw_ipi (struct metal_cpu *cpu, int hartid)
-{
+int __metal_driver_cpu_clear_sw_ipi(struct metal_cpu *cpu, int hartid) {
int rc = -1;
struct metal_interrupt *sw_intc;
struct __metal_driver_riscv_cpu_intc *intc =
- (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu);
+ (struct __metal_driver_riscv_cpu_intc *)
+ __metal_driver_cpu_interrupt_controller(cpu);
if (intc) {
sw_intc = intc->metal_int_table[METAL_INTERRUPT_ID_SW].sub_int;
if (sw_intc) {
- rc = sw_intc->vtable->command_request(sw_intc,
- METAL_SOFTWARE_IPI_CLEAR, &hartid);
+ rc = sw_intc->vtable->command_request(
+ sw_intc, METAL_SOFTWARE_IPI_CLEAR, &hartid);
}
}
return rc;
}
-int __metal_driver_cpu_get_msip (struct metal_cpu *cpu, int hartid)
-{
+int __metal_driver_cpu_get_msip(struct metal_cpu *cpu, int hartid) {
int rc = 0;
struct metal_interrupt *sw_intc;
struct __metal_driver_riscv_cpu_intc *intc =
- (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu);
+ (struct __metal_driver_riscv_cpu_intc *)
+ __metal_driver_cpu_interrupt_controller(cpu);
if (intc) {
sw_intc = intc->metal_int_table[METAL_INTERRUPT_ID_SW].sub_int;
if (sw_intc) {
- rc = sw_intc->vtable->command_request(sw_intc,
- METAL_SOFTWARE_MSIP_GET, &hartid);
+ rc = sw_intc->vtable->command_request(
+ sw_intc, METAL_SOFTWARE_MSIP_GET, &hartid);
}
}
return rc;
}
struct metal_interrupt *
-__metal_driver_cpu_controller_interrupt(struct metal_cpu *cpu)
-{
+__metal_driver_cpu_controller_interrupt(struct metal_cpu *cpu) {
return __metal_driver_cpu_interrupt_controller(cpu);
}
-int __metal_driver_cpu_enable_interrupt(struct metal_cpu *cpu, void *priv)
-{
- if ( __metal_driver_cpu_interrupt_controller(cpu) ) {
+int __metal_driver_cpu_enable_interrupt(struct metal_cpu *cpu, void *priv) {
+ if (__metal_driver_cpu_interrupt_controller(cpu)) {
/* Only support machine mode for now */
__metal_interrupt_global_enable();
- return 0;
+ return 0;
}
return -1;
}
-int __metal_driver_cpu_disable_interrupt(struct metal_cpu *cpu, void *priv)
-{
- if ( __metal_driver_cpu_interrupt_controller(cpu) ) {
+int __metal_driver_cpu_disable_interrupt(struct metal_cpu *cpu, void *priv) {
+ if (__metal_driver_cpu_interrupt_controller(cpu)) {
/* Only support machine mode for now */
__metal_interrupt_global_disable();
- return 0;
+ return 0;
}
return -1;
}
int __metal_driver_cpu_exception_register(struct metal_cpu *cpu, int ecode,
- metal_exception_handler_t isr)
-{
+ metal_exception_handler_t isr) {
struct __metal_driver_riscv_cpu_intc *intc =
- (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu);
+ (struct __metal_driver_riscv_cpu_intc *)
+ __metal_driver_cpu_interrupt_controller(cpu);
if (intc) {
- return __metal_exception_register((struct metal_interrupt *)intc, ecode, isr);
+ return __metal_exception_register((struct metal_interrupt *)intc, ecode,
+ isr);
}
return -1;
}
-int __metal_driver_cpu_get_instruction_length(struct metal_cpu *cpu, uintptr_t epc)
-{
+int __metal_driver_cpu_get_instruction_length(struct metal_cpu *cpu,
+ uintptr_t epc) {
/**
* Per ISA compressed instruction has last two bits of opcode set.
* The encoding '00' '01' '10' are used for compressed instruction.
* Only enconding '11' isn't regarded as compressed instruction (>16b).
*/
- return ((*(unsigned short*)epc & METAL_INSN_LENGTH_MASK)
- == METAL_INSN_NOT_COMPRESSED) ? 4 : 2;
+ return ((*(unsigned short *)epc & METAL_INSN_LENGTH_MASK) ==
+ METAL_INSN_NOT_COMPRESSED)
+ ? 4
+ : 2;
}
-uintptr_t __metal_driver_cpu_get_exception_pc(struct metal_cpu *cpu)
-{
+uintptr_t __metal_driver_cpu_get_exception_pc(struct metal_cpu *cpu) {
uintptr_t mepc;
- __asm__ volatile ("csrr %0, mepc" : "=r"(mepc));
+ __asm__ volatile("csrr %0, mepc" : "=r"(mepc));
return mepc;
}
-int __metal_driver_cpu_set_exception_pc(struct metal_cpu *cpu, uintptr_t mepc)
-{
- __asm__ volatile ("csrw mepc, %0" :: "r"(mepc));
+int __metal_driver_cpu_set_exception_pc(struct metal_cpu *cpu, uintptr_t mepc) {
+ __asm__ volatile("csrw mepc, %0" ::"r"(mepc));
return 0;
}
+struct metal_buserror *__metal_driver_cpu_get_buserror(struct metal_cpu *cpu) {
+ return __metal_driver_cpu_buserror(cpu);
+}
+
__METAL_DEFINE_VTABLE(__metal_driver_vtable_riscv_cpu_intc) = {
- .controller_vtable.interrupt_init = __metal_driver_riscv_cpu_controller_interrupt_init,
- .controller_vtable.interrupt_register = __metal_driver_riscv_cpu_controller_interrupt_register,
- .controller_vtable.interrupt_enable = __metal_driver_riscv_cpu_controller_interrupt_enable,
- .controller_vtable.interrupt_disable = __metal_driver_riscv_cpu_controller_interrupt_disable,
- .controller_vtable.interrupt_get_vector_mode = __metal_driver_riscv_cpu_controller_get_vector_mode,
- .controller_vtable.interrupt_set_vector_mode = __metal_driver_riscv_cpu_controller_set_vector_mode,
- .controller_vtable.command_request = __metal_driver_riscv_cpu_controller_command_request,
+ .controller_vtable.interrupt_init =
+ __metal_driver_riscv_cpu_controller_interrupt_init,
+ .controller_vtable.interrupt_register =
+ __metal_driver_riscv_cpu_controller_interrupt_register,
+ .controller_vtable.interrupt_enable =
+ __metal_driver_riscv_cpu_controller_interrupt_enable,
+ .controller_vtable.interrupt_disable =
+ __metal_driver_riscv_cpu_controller_interrupt_disable,
+ .controller_vtable.interrupt_get_vector_mode =
+ __metal_driver_riscv_cpu_controller_get_vector_mode,
+ .controller_vtable.interrupt_set_vector_mode =
+ __metal_driver_riscv_cpu_controller_set_vector_mode,
+ .controller_vtable.command_request =
+ __metal_driver_riscv_cpu_controller_command_request,
};
__METAL_DEFINE_VTABLE(__metal_driver_vtable_cpu) = {
- .cpu_vtable.mcycle_get = __metal_driver_cpu_mcycle_get,
- .cpu_vtable.timebase_get = __metal_driver_cpu_timebase_get,
+ .cpu_vtable.mcycle_get = __metal_driver_cpu_mcycle_get,
+ .cpu_vtable.timebase_get = __metal_driver_cpu_timebase_get,
.cpu_vtable.mtime_get = __metal_driver_cpu_mtime_get,
.cpu_vtable.mtimecmp_set = __metal_driver_cpu_mtimecmp_set,
- .cpu_vtable.tmr_controller_interrupt = __metal_driver_cpu_timer_controller_interrupt,
- .cpu_vtable.get_tmr_interrupt_id = __metal_driver_cpu_get_timer_interrupt_id,
- .cpu_vtable.sw_controller_interrupt = __metal_driver_cpu_sw_controller_interrupt,
+ .cpu_vtable.tmr_controller_interrupt =
+ __metal_driver_cpu_timer_controller_interrupt,
+ .cpu_vtable.get_tmr_interrupt_id =
+ __metal_driver_cpu_get_timer_interrupt_id,
+ .cpu_vtable.sw_controller_interrupt =
+ __metal_driver_cpu_sw_controller_interrupt,
.cpu_vtable.get_sw_interrupt_id = __metal_driver_cpu_get_sw_interrupt_id,
.cpu_vtable.set_sw_ipi = __metal_driver_cpu_set_sw_ipi,
.cpu_vtable.clear_sw_ipi = __metal_driver_cpu_clear_sw_ipi,
@@ -995,5 +872,5 @@ __METAL_DEFINE_VTABLE(__metal_driver_vtable_cpu) = {
.cpu_vtable.get_ilen = __metal_driver_cpu_get_instruction_length,
.cpu_vtable.get_epc = __metal_driver_cpu_get_exception_pc,
.cpu_vtable.set_epc = __metal_driver_cpu_set_exception_pc,
+ .cpu_vtable.get_buserror = __metal_driver_cpu_get_buserror,
};
-