parent
3227fb1ffd
commit
9e7653a96a
|
@ -24,6 +24,7 @@ C_SRCS += $(BSP_DIR)/lib/uart.c
|
||||||
C_SRCS += $(BSP_DIR)/lib/sim_ctrl.c
|
C_SRCS += $(BSP_DIR)/lib/sim_ctrl.c
|
||||||
C_SRCS += $(BSP_DIR)/lib/machine_timer.c
|
C_SRCS += $(BSP_DIR)/lib/machine_timer.c
|
||||||
C_SRCS += $(BSP_DIR)/lib/gpio.c
|
C_SRCS += $(BSP_DIR)/lib/gpio.c
|
||||||
|
C_SRCS += $(BSP_DIR)/lib/rvic.c
|
||||||
|
|
||||||
LINKER_SCRIPT := $(BSP_DIR)/link.lds
|
LINKER_SCRIPT := $(BSP_DIR)/link.lds
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -0,0 +1,31 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#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));
|
||||||
|
}
|
|
@ -1,9 +1,13 @@
|
||||||
|
#define REGBYTES 4
|
||||||
|
#define STORE sw
|
||||||
|
#define LOAD lw
|
||||||
|
|
||||||
.section .text.vector
|
.section .text.vector
|
||||||
.align 2
|
.align 2
|
||||||
.global vector_table
|
.global vector_table
|
||||||
vector_table:
|
vector_table:
|
||||||
.org 0x00
|
.org 0x00
|
||||||
|
/* exception */
|
||||||
jal x0, illegal_instruction_handler
|
jal x0, illegal_instruction_handler
|
||||||
jal x0, instruction_addr_misaligned_handler
|
jal x0, instruction_addr_misaligned_handler
|
||||||
jal x0, ecall_handler
|
jal x0, ecall_handler
|
||||||
|
@ -12,18 +16,12 @@ vector_table:
|
||||||
jal x0, store_misaligned_handler
|
jal x0, store_misaligned_handler
|
||||||
jal x0, handle_exception_unknown
|
jal x0, handle_exception_unknown
|
||||||
jal x0, handle_exception_unknown
|
jal x0, handle_exception_unknown
|
||||||
jal x0, external_irq_handler
|
/* interrupt */
|
||||||
jal x0, software_irq_handler
|
jal x0, irqs_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
|
|
||||||
|
|
||||||
|
irqs_vector_table:
|
||||||
|
.word timer_irq_handler
|
||||||
|
/* add your ISR here */
|
||||||
|
|
||||||
.weak illegal_instruction_handler
|
.weak illegal_instruction_handler
|
||||||
.weak instruction_addr_misaligned_handler
|
.weak instruction_addr_misaligned_handler
|
||||||
|
@ -32,15 +30,7 @@ vector_table:
|
||||||
.weak load_misaligned_handler
|
.weak load_misaligned_handler
|
||||||
.weak store_misaligned_handler
|
.weak store_misaligned_handler
|
||||||
.weak handle_exception_unknown
|
.weak handle_exception_unknown
|
||||||
.weak external_irq_handler
|
|
||||||
.weak software_irq_handler
|
|
||||||
.weak timer_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:
|
handle_exception_unknown:
|
||||||
j handle_exception_unknown
|
j handle_exception_unknown
|
||||||
|
@ -69,32 +59,64 @@ load_misaligned_handler:
|
||||||
store_misaligned_handler:
|
store_misaligned_handler:
|
||||||
j store_misaligned_handler
|
j store_misaligned_handler
|
||||||
|
|
||||||
external_irq_handler:
|
|
||||||
j external_irq_handler
|
|
||||||
|
|
||||||
software_irq_handler:
|
|
||||||
j software_irq_handler
|
|
||||||
|
|
||||||
timer_irq_handler:
|
timer_irq_handler:
|
||||||
j timer_irq_handler
|
j timer_irq_handler
|
||||||
|
|
||||||
fast_irq0_handler:
|
irqs_handler:
|
||||||
j fast_irq0_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:
|
lw a0, 16*4(sp)
|
||||||
j fast_irq3_handler
|
csrw mepc, a0
|
||||||
|
lw x1, 0*4(sp)
|
||||||
fast_irq4_handler:
|
lw x5, 1*4(sp)
|
||||||
j fast_irq4_handler
|
lw x6, 2*4(sp)
|
||||||
|
lw x7, 3*4(sp)
|
||||||
fast_irq_handler:
|
lw x10, 4*4(sp)
|
||||||
j fast_irq_handler
|
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
|
.section .rodata
|
||||||
illegal_instruction_msg:
|
illegal_instruction_msg:
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "../../bsp/include/machine_timer.h"
|
#include "../../bsp/include/machine_timer.h"
|
||||||
#include "../../bsp/include/utils.h"
|
#include "../../bsp/include/utils.h"
|
||||||
|
#include "../../bsp/include/rvic.h"
|
||||||
#include "../../bsp/include/gpio.h"
|
#include "../../bsp/include/gpio.h"
|
||||||
|
|
||||||
static volatile uint32_t count;
|
static volatile uint32_t count;
|
||||||
|
@ -15,6 +16,7 @@ int main()
|
||||||
machine_timer_clear_irq_pending();
|
machine_timer_clear_irq_pending();
|
||||||
global_irq_enable();
|
global_irq_enable();
|
||||||
machine_timer_irq_enable(1);
|
machine_timer_irq_enable(1);
|
||||||
|
rvic_irq_enable(0);
|
||||||
machine_timer_enable(1);
|
machine_timer_enable(1);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -32,6 +34,7 @@ int main()
|
||||||
machine_timer_clear_irq_pending();
|
machine_timer_clear_irq_pending();
|
||||||
global_irq_enable();
|
global_irq_enable();
|
||||||
machine_timer_irq_enable(1);
|
machine_timer_irq_enable(1);
|
||||||
|
rvic_irq_enable(0);
|
||||||
machine_timer_enable(1);
|
machine_timer_enable(1);
|
||||||
|
|
||||||
gpio_output_enable(GPIO0);
|
gpio_output_enable(GPIO0);
|
||||||
|
@ -46,9 +49,10 @@ int main()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((interrupt)) void timer_irq_handler()
|
void timer_irq_handler()
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
machine_timer_clear_irq_pending();
|
machine_timer_clear_irq_pending();
|
||||||
|
rvic_clear_irq_pending(0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue