b9e4fcfc68
整合libcpu/riscv中的移植文件 提供一份公共代码于common 在提交本pr时,除hpmicro的内核,rv32内核bsp已完成去除大部分的冗余,大部分代码采用common中的实现。本pr的作用是进一步统一common中的文件,从而提供一份公用代码,新移植的RV32内核的BSP可以全部使用common代码。 - 在common中提供一份公用文件:interrupt_gcc.S - 修改原有的文件,将原有的中断中上下文切换代码替换为interrupt_gcc.S - 基于上述修改,修改仓库中risc-v内核的BSP与移植相关的部分 (主要包含中断入口函数 中断栈等) - 在common中提供一份公用文件:trap_common.c;提供统一中断入口函数,中断入口函数初始化,中断入口注册等函数,并完善异常时的信息输出 - 在common中提供一份公用文件:rt_hw_stack_frame.h;将栈帧结构体剥离,供用户使用 - 在上述工作完成后,在上述工作的基础上测试仓库中risc-v内核的BSP - 完善函数中的命名,完善中断栈的获取 - 提供一份详细的基于现有common文件的移植指南 #### 在什么测试环境下测试通过 - 1.CH32V307V-R1-R0 - 2.CH32V208W-R0-1V4 - 3.HPM6750EVKMINI - 4.GD32VF103V-EVAL - 5.qemu(CORE-V-MCU ) > 与上述开发板使用同样芯片的BSP均测试通过 在CH32V307V-R1-R0与HPM6750EVKMINI上基于现有移植文件进行多线程复杂场景下的长时间测试,测试过程系统运行正常。
106 lines
3.0 KiB
C
106 lines
3.0 KiB
C
#include <rthw.h>
|
|
#include <rtthread.h>
|
|
#include "riscv-ops.h"
|
|
#include "rt_hw_stack_frame.h"
|
|
|
|
#define ISR_NUMBER 32
|
|
static volatile rt_hw_stack_frame_t *s_stack_frame;
|
|
static struct rt_irq_desc rv32irq_table[ISR_NUMBER];
|
|
void rt_show_stack_frame(void);
|
|
|
|
/**
|
|
* Temporary interrupt entry function
|
|
*
|
|
* @param mcause Machine Cause Register
|
|
* @return RT_NULL
|
|
*/
|
|
rt_weak rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t mcause)
|
|
{
|
|
rt_kprintf("UN-handled interrupt %d occurred!!!\n", mcause);
|
|
return RT_NULL;
|
|
}
|
|
|
|
/**
|
|
* Interrupt entry function initialization
|
|
*/
|
|
rt_weak void rt_hw_interrupt_init(void)
|
|
{
|
|
int idx = 0;
|
|
|
|
for (idx = 0; idx < ISR_NUMBER; idx++)
|
|
{
|
|
rv32irq_table[idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle;
|
|
rv32irq_table[idx].param = RT_NULL;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Break Entry Function Binding
|
|
*
|
|
* @param vector interrupt number
|
|
* @param handler Break-in function requiring binding
|
|
* @param param NULL
|
|
* @param name NULL
|
|
* @return NULL
|
|
*/
|
|
rt_weak rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
|
|
void *param, const char *name)
|
|
{
|
|
void *user_param = param;
|
|
char *user_name = name;
|
|
if(vector < ISR_NUMBER)
|
|
{
|
|
if (handler != RT_NULL)
|
|
{
|
|
rv32irq_table[vector].handler = (rt_isr_handler_t)handler;
|
|
rv32irq_table[vector].param = param;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Query and Distribution Entry for Exception and Interrupt Sources
|
|
*
|
|
* @param mcause Machine Cause Register
|
|
*/
|
|
rt_weak void rt_rv32_system_irq_handler(rt_uint32_t mcause)
|
|
{
|
|
rt_uint32_t mscratch = read_csr(0x340);
|
|
rt_uint32_t irq_id = (mcause & 0x1F);
|
|
rt_uint32_t exception = !(mcause & 0x80000000);
|
|
if(exception)
|
|
{
|
|
s_stack_frame = (rt_hw_stack_frame_t *)mscratch;
|
|
rt_show_stack_frame();
|
|
}
|
|
else
|
|
{
|
|
rv32irq_table[irq_id].handler(irq_id, rv32irq_table[irq_id].param);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Register Print on Exception
|
|
*/
|
|
rt_weak void rt_show_stack_frame(void)
|
|
{
|
|
rt_kprintf("Stack frame:\r\n----------------------------------------\r\n");
|
|
rt_kprintf("ra : 0x%08x\r\n", s_stack_frame->ra);
|
|
rt_kprintf("mstatus : 0x%08x\r\n", read_csr(0x300));//mstatus
|
|
rt_kprintf("t0 : 0x%08x\r\n", s_stack_frame->t0);
|
|
rt_kprintf("t1 : 0x%08x\r\n", s_stack_frame->t1);
|
|
rt_kprintf("t2 : 0x%08x\r\n", s_stack_frame->t2);
|
|
rt_kprintf("a0 : 0x%08x\r\n", s_stack_frame->a0);
|
|
rt_kprintf("a1 : 0x%08x\r\n", s_stack_frame->a1);
|
|
rt_kprintf("a2 : 0x%08x\r\n", s_stack_frame->a2);
|
|
rt_kprintf("a3 : 0x%08x\r\n", s_stack_frame->a3);
|
|
rt_kprintf("a4 : 0x%08x\r\n", s_stack_frame->a4);
|
|
rt_kprintf("a5 : 0x%08x\r\n", s_stack_frame->a5);
|
|
rt_kprintf("a6 : 0x%08x\r\n", s_stack_frame->a6);
|
|
rt_kprintf("a7 : 0x%08x\r\n", s_stack_frame->a7);
|
|
rt_kprintf("t3 : 0x%08x\r\n", s_stack_frame->t3);
|
|
rt_kprintf("t4 : 0x%08x\r\n", s_stack_frame->t4);
|
|
rt_kprintf("t5 : 0x%08x\r\n", s_stack_frame->t5);
|
|
rt_kprintf("t6 : 0x%08x\r\n", s_stack_frame->t6);
|
|
}
|