From 9e7653a96a3708660e7f51ac583e55e030caabeb Mon Sep 17 00:00:00 2001 From: liangkangnan Date: Thu, 22 Jul 2021 09:40:26 +0800 Subject: [PATCH] sdk:bsp: adapt to rvic Signed-off-by: liangkangnan --- sdk/bsp/bsp.mk | 1 + sdk/bsp/include/rvic.h | 30 +++++++++ sdk/bsp/lib/rvic.c | 31 +++++++++ sdk/bsp/vector_table.S | 100 ++++++++++++++++++------------ sdk/examples/machine_timer/main.c | 6 +- 5 files changed, 128 insertions(+), 40 deletions(-) create mode 100644 sdk/bsp/include/rvic.h create mode 100644 sdk/bsp/lib/rvic.c diff --git a/sdk/bsp/bsp.mk b/sdk/bsp/bsp.mk index e9023c8..aab4e84 100644 --- a/sdk/bsp/bsp.mk +++ b/sdk/bsp/bsp.mk @@ -24,6 +24,7 @@ C_SRCS += $(BSP_DIR)/lib/uart.c C_SRCS += $(BSP_DIR)/lib/sim_ctrl.c C_SRCS += $(BSP_DIR)/lib/machine_timer.c C_SRCS += $(BSP_DIR)/lib/gpio.c +C_SRCS += $(BSP_DIR)/lib/rvic.c LINKER_SCRIPT := $(BSP_DIR)/link.lds diff --git a/sdk/bsp/include/rvic.h b/sdk/bsp/include/rvic.h new file mode 100644 index 0000000..8988454 --- /dev/null +++ b/sdk/bsp/include/rvic.h @@ -0,0 +1,30 @@ +#ifndef _RVIC_H_ +#define _RVIC_H_ + +#define RVIC_BASE (0xD0000000) +#define RVIC_IE (RVIC_BASE + (0x00)) +#define RVIC_IP (RVIC_BASE + (0x04)) +#define RVIC_PRIO0 (RVIC_BASE + (0x08)) +#define RVIC_PRIO1 (RVIC_BASE + (0x0C)) +#define RVIC_PRIO2 (RVIC_BASE + (0x10)) +#define RVIC_PRIO3 (RVIC_BASE + (0x14)) +#define RVIC_PRIO4 (RVIC_BASE + (0x18)) +#define RVIC_PRIO5 (RVIC_BASE + (0x1C)) +#define RVIC_PRIO6 (RVIC_BASE + (0x20)) +#define RVIC_PRIO7 (RVIC_BASE + (0x24)) +#define RVIC_ID (RVIC_BASE + (0x28)) + +#define RVIC_REG(addr) (*((volatile uint32_t *)addr)) + +typedef struct { + volatile uint32_t prio[8]; +} rvic_prio_t; + +#define RVIC_PRIO ((rvic_prio_t *)0xD0000008) + +void rvic_irq_enable(uint32_t id); +void rvic_irq_disable(uint32_t id); +void rvic_clear_irq_pending(uint32_t id); +void rvic_set_irq_prio_level(uint32_t id, uint8_t level); + +#endif diff --git a/sdk/bsp/lib/rvic.c b/sdk/bsp/lib/rvic.c new file mode 100644 index 0000000..be9342d --- /dev/null +++ b/sdk/bsp/lib/rvic.c @@ -0,0 +1,31 @@ +#include + +#include "../../bsp/include/rvic.h" + + +void rvic_irq_enable(uint32_t id) +{ + RVIC_REG(RVIC_IE) |= 1 << id; +} + +void rvic_irq_disable(uint32_t id) +{ + RVIC_REG(RVIC_IE) &= ~(1 << id); +} + +void rvic_clear_irq_pending(uint32_t id) +{ + RVIC_REG(RVIC_IP) |= 1 << id; +} + +void rvic_set_irq_prio_level(uint32_t id, uint8_t level) +{ + uint8_t reg; + uint8_t index; + + reg = id >> 2; + index = id % 4; + + RVIC_PRIO->prio[reg] &= ~(0xff << (index << 3)); + RVIC_PRIO->prio[reg] |= (level << (index << 3)); +} diff --git a/sdk/bsp/vector_table.S b/sdk/bsp/vector_table.S index ca1c022..50e7252 100644 --- a/sdk/bsp/vector_table.S +++ b/sdk/bsp/vector_table.S @@ -1,9 +1,13 @@ +#define REGBYTES 4 +#define STORE sw +#define LOAD lw .section .text.vector .align 2 .global vector_table vector_table: .org 0x00 + /* exception */ jal x0, illegal_instruction_handler jal x0, instruction_addr_misaligned_handler jal x0, ecall_handler @@ -12,18 +16,12 @@ vector_table: jal x0, store_misaligned_handler jal x0, handle_exception_unknown jal x0, handle_exception_unknown - jal x0, external_irq_handler - jal x0, software_irq_handler - jal x0, timer_irq_handler - jal x0, fast_irq0_handler - jal x0, fast_irq1_handler - jal x0, fast_irq2_handler - jal x0, fast_irq3_handler - jal x0, fast_irq4_handler - .rept 10 - jal x0, fast_irq_handler - .endr + /* interrupt */ + jal x0, irqs_handler +irqs_vector_table: + .word timer_irq_handler + /* add your ISR here */ .weak illegal_instruction_handler .weak instruction_addr_misaligned_handler @@ -32,15 +30,7 @@ vector_table: .weak load_misaligned_handler .weak store_misaligned_handler .weak handle_exception_unknown -.weak external_irq_handler -.weak software_irq_handler .weak timer_irq_handler -.weak fast_irq0_handler -.weak fast_irq1_handler -.weak fast_irq2_handler -.weak fast_irq3_handler -.weak fast_irq4_handler -.weak fast_irq_handler handle_exception_unknown: j handle_exception_unknown @@ -69,32 +59,64 @@ load_misaligned_handler: store_misaligned_handler: j store_misaligned_handler -external_irq_handler: - j external_irq_handler - -software_irq_handler: - j software_irq_handler - timer_irq_handler: j timer_irq_handler -fast_irq0_handler: - j fast_irq0_handler +irqs_handler: + addi sp, sp, -32*17 + sw x1, 0*4(sp) + sw x5, 1*4(sp) + sw x6, 2*4(sp) + sw x7, 3*4(sp) + sw x10, 4*4(sp) + sw x11, 5*4(sp) + sw x12, 6*4(sp) + sw x13, 7*4(sp) + sw x14, 8*4(sp) + sw x15, 9*4(sp) + sw x16, 10*4(sp) + sw x17, 11*4(sp) + sw x28, 12*4(sp) + sw x29, 13*4(sp) + sw x30, 14*4(sp) + sw x31, 15*4(sp) + csrr a0, mepc + sw a0, 16*4(sp) -fast_irq1_handler: - j fast_irq1_handler + /* 使能全局中断 */ + csrrsi x0, mstatus, 0x8 -fast_irq2_handler: - j fast_irq2_handler + /* 读取中断号 */ + csrr a1, mcause + /* 计算偏移地址: id * 4 */ + slli a1, a1, 2 + la a0, irqs_vector_table + add a1, a0, a1 + /* 读取中断处理函数地址 */ + lw a1, 0(a1) + /* 跳转到中断处理函数 */ + jalr ra, 0(a1) -fast_irq3_handler: - j fast_irq3_handler - -fast_irq4_handler: - j fast_irq4_handler - -fast_irq_handler: - j fast_irq_handler + lw a0, 16*4(sp) + csrw mepc, a0 + lw x1, 0*4(sp) + lw x5, 1*4(sp) + lw x6, 2*4(sp) + lw x7, 3*4(sp) + lw x10, 4*4(sp) + lw x11, 5*4(sp) + lw x12, 6*4(sp) + lw x13, 7*4(sp) + lw x14, 8*4(sp) + lw x15, 9*4(sp) + lw x16, 10*4(sp) + lw x17, 11*4(sp) + lw x28, 12*4(sp) + lw x29, 13*4(sp) + lw x30, 14*4(sp) + lw x31, 15*4(sp) + addi sp, sp, 32*17 + mret .section .rodata illegal_instruction_msg: diff --git a/sdk/examples/machine_timer/main.c b/sdk/examples/machine_timer/main.c index 8e851ed..2bf4726 100644 --- a/sdk/examples/machine_timer/main.c +++ b/sdk/examples/machine_timer/main.c @@ -2,6 +2,7 @@ #include "../../bsp/include/machine_timer.h" #include "../../bsp/include/utils.h" +#include "../../bsp/include/rvic.h" #include "../../bsp/include/gpio.h" static volatile uint32_t count; @@ -15,6 +16,7 @@ int main() machine_timer_clear_irq_pending(); global_irq_enable(); machine_timer_irq_enable(1); + rvic_irq_enable(0); machine_timer_enable(1); while (1) { @@ -32,6 +34,7 @@ int main() machine_timer_clear_irq_pending(); global_irq_enable(); machine_timer_irq_enable(1); + rvic_irq_enable(0); machine_timer_enable(1); gpio_output_enable(GPIO0); @@ -46,9 +49,10 @@ int main() #endif } -__attribute__((interrupt)) void timer_irq_handler() +void timer_irq_handler() { count++; machine_timer_clear_irq_pending(); + rvic_clear_irq_pending(0); }