CH32V10X 适配
This commit is contained in:
+14
-1
@@ -28,7 +28,10 @@
|
|||||||
OS_STATIC_FORCE_INLINE
|
OS_STATIC_FORCE_INLINE
|
||||||
os_uint_t cpu_save_disable_irq_in_isr(void){
|
os_uint_t cpu_save_disable_irq_in_isr(void){
|
||||||
os_uint_t result;
|
os_uint_t result;
|
||||||
__asm volatile ("csrrw %0, mstatus, %1":"=r"(result):"r"(0x1800):"memory");
|
__asm volatile ("csrrw %0, mstatus, %1"
|
||||||
|
:"=r"(result)
|
||||||
|
:"r"(0x1800)
|
||||||
|
:"memory");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,4 +47,14 @@ void cpu_restore_irq_in_isr(os_uint_t value){
|
|||||||
#define os_port_save_disable_irq cpu_save_disable_irq_in_isr
|
#define os_port_save_disable_irq cpu_save_disable_irq_in_isr
|
||||||
#define os_port_restore_irq cpu_restore_irq_in_isr
|
#define os_port_restore_irq cpu_restore_irq_in_isr
|
||||||
|
|
||||||
|
OS_STATIC_FORCE_INLINE
|
||||||
|
void cpu_set_isr_sp(void){
|
||||||
|
__asm volatile("csrrw sp,mscratch,sp");
|
||||||
|
}
|
||||||
|
|
||||||
|
OS_STATIC_FORCE_INLINE
|
||||||
|
void cpu_set_task_sp(void){
|
||||||
|
__asm volatile("csrrw sp,mscratch,sp");
|
||||||
|
}
|
||||||
|
|
||||||
#endif /*INCLUDED_CPU_H*/
|
#endif /*INCLUDED_CPU_H*/
|
||||||
|
|||||||
+41
-65
@@ -1,3 +1,4 @@
|
|||||||
|
#include <os_isr.h>
|
||||||
#include "os_port.h"
|
#include "os_port.h"
|
||||||
#include "os_stack.h"
|
#include "os_stack.h"
|
||||||
#include "os_macros.h"
|
#include "os_macros.h"
|
||||||
@@ -5,7 +6,6 @@
|
|||||||
#include "os_compiler.h"
|
#include "os_compiler.h"
|
||||||
#include "os_systick.h"
|
#include "os_systick.h"
|
||||||
#include "os_sched.h"
|
#include "os_sched.h"
|
||||||
#include "os_isr.h"
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||||
@@ -20,7 +20,7 @@ uint32_t _SysTick_Config(os_tick_t ticks)
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
NVIC->CFGR = (CPU_KEY1<<16) | (1<<1/*NESTCTRL*/) | (1<<0/*HWSTKCTRL*/); /* 关闭硬件压栈和嵌套 */
|
NVIC->CFGR = 0xFA050003; /* 关闭硬件压栈和嵌套 */
|
||||||
|
|
||||||
NVIC_SetPriority(SysTick_IRQn,0xf0);
|
NVIC_SetPriority(SysTick_IRQn,0xf0);
|
||||||
NVIC_SetPriority(Software_IRQn,0xf0);
|
NVIC_SetPriority(Software_IRQn,0xf0);
|
||||||
@@ -44,6 +44,38 @@ uint32_t _SysTick_Config(os_tick_t ticks)
|
|||||||
/* */
|
/* */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
os_uintptr_t mstatus; /* zero, 用于 mstatus 保存 */
|
||||||
|
os_uintptr_t ra; /* 返回地址 */
|
||||||
|
os_uintptr_t mepc; /* 栈指针, mepc */
|
||||||
|
os_uintptr_t x3; /* 全局指针 */
|
||||||
|
os_uintptr_t x4; /* 线程指针 */
|
||||||
|
os_uintptr_t x5; /* 临时寄存器0 */
|
||||||
|
os_uintptr_t x6; /* 临时寄存器1 */
|
||||||
|
os_uintptr_t x7; /* 临时寄存器2 */
|
||||||
|
os_uintptr_t x8; /* s0/fp */
|
||||||
|
os_uintptr_t x9; /* 保存寄存器1 */
|
||||||
|
os_uintptr_t a0; /* 函数参数/返回值 */
|
||||||
|
os_uintptr_t x11; /* 函数参数 */
|
||||||
|
os_uintptr_t x12; /* 函数参数 */
|
||||||
|
os_uintptr_t x13; /* 函数参数 */
|
||||||
|
os_uintptr_t x14; /* 函数参数 */
|
||||||
|
os_uintptr_t x15; /* 函数参数 */
|
||||||
|
os_uintptr_t x16; /* 函数参数 */
|
||||||
|
os_uintptr_t x17; /* 函数参数 */
|
||||||
|
os_uintptr_t x18; /* 保存寄存器 */
|
||||||
|
os_uintptr_t x19; /* 保存寄存器 */
|
||||||
|
os_uintptr_t x20; /* 保存寄存器 */
|
||||||
|
os_uintptr_t x21; /* 保存寄存器 */
|
||||||
|
os_uintptr_t x22; /* 保存寄存器 */
|
||||||
|
os_uintptr_t x23; /* 保存寄存器 */
|
||||||
|
os_uintptr_t x24; /* 保存寄存器 */
|
||||||
|
os_uintptr_t x25; /* 保存寄存器 */
|
||||||
|
os_uintptr_t x26; /* 保存寄存器 */
|
||||||
|
os_uintptr_t x27; /* 保存寄存器 */
|
||||||
|
os_uintptr_t x28; /* 临时寄存器 */
|
||||||
|
os_uintptr_t x29; /* 临时寄存器 */
|
||||||
|
os_uintptr_t x30; /* 临时寄存器 */
|
||||||
|
os_uintptr_t x31; /* 临时寄存器 */
|
||||||
#if (OS_CFG_CPU_FPU_PRESENT)
|
#if (OS_CFG_CPU_FPU_PRESENT)
|
||||||
os_uintptr_t f0;
|
os_uintptr_t f0;
|
||||||
os_uintptr_t f1;
|
os_uintptr_t f1;
|
||||||
@@ -78,55 +110,23 @@ typedef struct {
|
|||||||
os_uintptr_t f30;
|
os_uintptr_t f30;
|
||||||
os_uintptr_t f31;
|
os_uintptr_t f31;
|
||||||
#endif
|
#endif
|
||||||
os_uintptr_t mstatus; /* zero, 用于 mstatus 保存 */
|
|
||||||
os_uintptr_t ra; /* 返回地址 */
|
|
||||||
os_uintptr_t mepc; /* 栈指针, mepc */
|
|
||||||
os_uintptr_t x3; /* 全局指针 */
|
|
||||||
os_uintptr_t x4; /* 线程指针 */
|
|
||||||
os_uintptr_t x5; /* 临时寄存器0 */
|
|
||||||
os_uintptr_t x6; /* 临时寄存器1 */
|
|
||||||
os_uintptr_t x7; /* 临时寄存器2 */
|
|
||||||
os_uintptr_t x8; /* s0/fp */
|
|
||||||
os_uintptr_t x9; /* 保存寄存器1 */
|
|
||||||
os_uintptr_t a0; /* 函数参数/返回值 */
|
|
||||||
os_uintptr_t x11; /* 函数参数 */
|
|
||||||
os_uintptr_t x12; /* 函数参数 */
|
|
||||||
os_uintptr_t x13; /* 函数参数 */
|
|
||||||
os_uintptr_t x14; /* 函数参数 */
|
|
||||||
os_uintptr_t x15; /* 函数参数 */
|
|
||||||
os_uintptr_t x16; /* 函数参数 */
|
|
||||||
os_uintptr_t x17; /* 函数参数 */
|
|
||||||
os_uintptr_t x18; /* 保存寄存器 */
|
|
||||||
os_uintptr_t x19; /* 保存寄存器 */
|
|
||||||
os_uintptr_t x20; /* 保存寄存器 */
|
|
||||||
os_uintptr_t x21; /* 保存寄存器 */
|
|
||||||
os_uintptr_t x22; /* 保存寄存器 */
|
|
||||||
os_uintptr_t x23; /* 保存寄存器 */
|
|
||||||
os_uintptr_t x24; /* 保存寄存器 */
|
|
||||||
os_uintptr_t x25; /* 保存寄存器 */
|
|
||||||
os_uintptr_t x26; /* 保存寄存器 */
|
|
||||||
os_uintptr_t x27; /* 保存寄存器 */
|
|
||||||
os_uintptr_t x28; /* 临时寄存器 */
|
|
||||||
os_uintptr_t x29; /* 临时寄存器 */
|
|
||||||
os_uintptr_t x30; /* 临时寄存器 */
|
|
||||||
os_uintptr_t x31; /* 临时寄存器 */
|
|
||||||
}os_stack_frame_t;
|
}os_stack_frame_t;
|
||||||
|
|
||||||
#define STACK_FRAME_SIZE sizeof(os_stack_frame_t)
|
#define STACK_FRAME_SIZE sizeof(os_stack_frame_t)
|
||||||
#define MSTATUS_MPIE (1<<7)
|
|
||||||
|
|
||||||
os_stack_t os_port_cpu_stack_init(os_task_entry_t entry, void* param
|
os_stack_t os_port_cpu_stack_init(os_task_entry_t entry, void* param
|
||||||
, void* stack_base, os_size_t stack_size, void(*exit_entry)(void)){
|
, void* stack_base, os_size_t stack_size, void(*exit_entry)(void)){
|
||||||
os_uintptr_t stack_max = (os_uintptr_t)((uint8_t *) stack_base + stack_size);
|
os_uintptr_t stack_max = (os_uintptr_t)((uint8_t *) stack_base + stack_size);
|
||||||
os_uintptr_t real_max = OS_ALIGN_DOWN(stack_max, OS_ALIGN_SIZE); /* 实际栈顶的位置,对齐后的位置 */
|
os_uintptr_t real_max = OS_ALIGN_DOWN(stack_max, OS_ALIGN_SIZE); /* 实际栈顶的位置,对齐后的位置 */
|
||||||
stack_size -= (stack_max - real_max); /* 实际栈大小 */
|
stack_size -= (stack_max - real_max); /* 实际栈大小 */
|
||||||
|
uint8_t value = 0x01;
|
||||||
os_stack_frame_t* p_frame = (os_stack_frame_t*)(real_max - STACK_FRAME_SIZE);
|
os_stack_frame_t* p_frame = (os_stack_frame_t*)(real_max - STACK_FRAME_SIZE);
|
||||||
for(os_size_t i=0; i<STACK_FRAME_SIZE/sizeof(os_uintptr_t); i++){
|
for(os_size_t i=0; i<STACK_FRAME_SIZE/sizeof(os_uintptr_t); i++){
|
||||||
((os_uintptr_t*)(p_frame))[i] = 0x5ac0ffee;
|
((os_uintptr_t*)(p_frame))[i] = (value<<24) | (value<<16) | (value << 8) | value;
|
||||||
|
value++;
|
||||||
}
|
}
|
||||||
|
|
||||||
p_frame->mstatus = MSTATUS_MPIE;
|
p_frame->mstatus = 0x1880;
|
||||||
p_frame->mepc = (os_uintptr_t)entry;
|
p_frame->mepc = (os_uintptr_t)entry;
|
||||||
p_frame->a0 = (os_uintptr_t)param;
|
p_frame->a0 = (os_uintptr_t)param;
|
||||||
p_frame->ra = (os_uintptr_t)exit_entry;
|
p_frame->ra = (os_uintptr_t)exit_entry;
|
||||||
@@ -139,29 +139,6 @@ os_stack_t os_port_cpu_stack_init(os_task_entry_t entry, void* param
|
|||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
//void os_port_disable_irq(void){
|
|
||||||
// RISCV_disable_irq();
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//void os_port_enable_irq(void){
|
|
||||||
// RISCV_enable_irq();
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//os_uint_t os_port_save_disable_irq(void){
|
|
||||||
// return os_port_save_disable_irq_in_isr();
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//void os_port_restore_irq(os_uint_t level){
|
|
||||||
// os_port_restore_irq_in_isr(level);
|
|
||||||
//}
|
|
||||||
|
|
||||||
//os_uint_t os_port_save_disable_irq_in_isr(void){
|
|
||||||
// return RISCV_get_set_MSTATUS(0x1800);
|
|
||||||
//}
|
|
||||||
|
|
||||||
//void os_port_restore_irq_in_isr(os_uint_t level){
|
|
||||||
// RISCV_set_MSTATUS(level);
|
|
||||||
//}
|
|
||||||
|
|
||||||
void os_sched(void){
|
void os_sched(void){
|
||||||
os_sched_in_isr();
|
os_sched_in_isr();
|
||||||
@@ -204,22 +181,21 @@ void os_port_context_switch(void* from_sp, void* to_sp){
|
|||||||
g_os_port_switch_from_sp = from_sp;
|
g_os_port_switch_from_sp = from_sp;
|
||||||
g_os_port_switch_to_sp = to_sp;
|
g_os_port_switch_to_sp = to_sp;
|
||||||
g_os_port_context_switch_flag = OS_TRUE;
|
g_os_port_context_switch_flag = OS_TRUE;
|
||||||
os_critical_leave_in_isr();
|
|
||||||
if(from_sp==0){
|
if(from_sp==0){
|
||||||
|
os_critical_leave_in_isr();
|
||||||
os_port_context_switch_to((os_uintptr_t)to_sp);
|
os_port_context_switch_to((os_uintptr_t)to_sp);
|
||||||
}else{
|
}else{
|
||||||
|
os_critical_leave_in_isr();
|
||||||
os_port_send_context_switch_request();
|
os_port_send_context_switch_request();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SysTick_Handler(void) __attribute__((interrupt()));
|
void SysTick_Handler_C(void){
|
||||||
void SysTick_Handler(void){
|
|
||||||
SysTick->CTLR=0;
|
SysTick->CTLR=0;
|
||||||
SysTick->CNTL0=0;SysTick->CNTL1=0;SysTick->CNTL2=0;SysTick->CNTL3=0;
|
SysTick->CNTL0=0;SysTick->CNTL1=0;SysTick->CNTL2=0;SysTick->CNTL3=0;
|
||||||
SysTick->CNTH0=0;SysTick->CNTH1=0;SysTick->CNTH2=0;SysTick->CNTH3=0;
|
SysTick->CNTH0=0;SysTick->CNTH1=0;SysTick->CNTH2=0;SysTick->CNTH3=0;
|
||||||
SysTick->CTLR=0x1;
|
SysTick->CTLR=0x1;
|
||||||
|
|
||||||
// 调用系统心跳处理
|
// 调用系统心跳处理
|
||||||
os_systick_tick();
|
os_systick_tick();
|
||||||
}
|
}
|
||||||
|
|||||||
+283
-178
@@ -33,39 +33,73 @@ cpu_clz:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
.section .text.os_port_context_switch_to,"ax",%progbits
|
.section .text.os_port_context_switch_to,"ax",%progbits
|
||||||
.align 8
|
.align 2
|
||||||
.func
|
.func
|
||||||
.global os_port_context_switch_to
|
.global os_port_context_switch_to
|
||||||
.extern os_port_on_switch_success
|
.extern os_port_on_switch_success
|
||||||
os_port_context_switch_to:
|
os_port_context_switch_to:
|
||||||
/* machine mode, disable ISR */
|
|
||||||
li t0, 0x1800
|
li t0, 0x1800
|
||||||
csrw mstatus, t0
|
csrw mstatus, t0 // 1. 关中断
|
||||||
|
|
||||||
/* first save interrupt stack */
|
/* 设置中断栈/系统栈空间 */
|
||||||
la t0, _eusrstack
|
la t0, _eusrstack
|
||||||
addi t0, t0, -512
|
addi t0, t0, -512
|
||||||
csrw mscratch,t0
|
csrw mscratch, t0 // 备用栈指针存入 mscratch
|
||||||
|
|
||||||
/* restore sp */
|
/* =====================================================================
|
||||||
LOAD sp, (a0)
|
* 第一步:切换到中断栈,安全调用通知 C 函数
|
||||||
|
* ===================================================================== */
|
||||||
|
jal os_port_on_switch_success // 调用 C 函数(此时随便它怎么污染寄存器)
|
||||||
|
|
||||||
csrrw sp, mscratch, sp
|
/* =====================================================================
|
||||||
jal os_port_on_switch_success
|
* 第二步:获取新任务的栈指针 SP
|
||||||
csrrw sp, mscratch, sp
|
* ===================================================================== */
|
||||||
|
LOAD sp, 0(a0) // a0 是传入的 &g_os_port_switch_to_sp,从中取出 sp
|
||||||
|
|
||||||
/* restore mstatus.MPIE */
|
/* =====================================================================
|
||||||
LOAD a0, 0*REG_BYTES(sp)
|
* 第三步:恢复 FPU 浮点寄存器(与保存栈帧严格镜像)
|
||||||
csrs mstatus, a0
|
* 修复宏定义:将 MPU 改回 FPU
|
||||||
|
* ===================================================================== */
|
||||||
|
#if (OS_CFG_CPU_FPU_PRESENT)
|
||||||
|
FLOAD f0, (CONTEXT_SIZE + 0 * REG_BYTES)(sp)
|
||||||
|
FLOAD f1, (CONTEXT_SIZE + 1 * REG_BYTES)(sp)
|
||||||
|
FLOAD f2, (CONTEXT_SIZE + 2 * REG_BYTES)(sp)
|
||||||
|
FLOAD f3, (CONTEXT_SIZE + 3 * REG_BYTES)(sp)
|
||||||
|
FLOAD f4, (CONTEXT_SIZE + 4 * REG_BYTES)(sp)
|
||||||
|
FLOAD f5, (CONTEXT_SIZE + 5 * REG_BYTES)(sp)
|
||||||
|
FLOAD f6, (CONTEXT_SIZE + 6 * REG_BYTES)(sp)
|
||||||
|
FLOAD f7, (CONTEXT_SIZE + 7 * REG_BYTES)(sp)
|
||||||
|
FLOAD f8, (CONTEXT_SIZE + 8 * REG_BYTES)(sp)
|
||||||
|
FLOAD f9, (CONTEXT_SIZE + 9 * REG_BYTES)(sp)
|
||||||
|
FLOAD f10, (CONTEXT_SIZE + 10 * REG_BYTES)(sp)
|
||||||
|
FLOAD f11, (CONTEXT_SIZE + 11 * REG_BYTES)(sp)
|
||||||
|
FLOAD f12, (CONTEXT_SIZE + 12 * REG_BYTES)(sp)
|
||||||
|
FLOAD f13, (CONTEXT_SIZE + 13 * REG_BYTES)(sp)
|
||||||
|
FLOAD f14, (CONTEXT_SIZE + 14 * REG_BYTES)(sp)
|
||||||
|
FLOAD f15, (CONTEXT_SIZE + 15 * REG_BYTES)(sp)
|
||||||
|
FLOAD f16, (CONTEXT_SIZE + 16 * REG_BYTES)(sp)
|
||||||
|
FLOAD f17, (CONTEXT_SIZE + 17 * REG_BYTES)(sp)
|
||||||
|
FLOAD f18, (CONTEXT_SIZE + 18 * REG_BYTES)(sp)
|
||||||
|
FLOAD f19, (CONTEXT_SIZE + 19 * REG_BYTES)(sp)
|
||||||
|
FLOAD f20, (CONTEXT_SIZE + 20 * REG_BYTES)(sp)
|
||||||
|
FLOAD f21, (CONTEXT_SIZE + 21 * REG_BYTES)(sp)
|
||||||
|
FLOAD f22, (CONTEXT_SIZE + 22 * REG_BYTES)(sp)
|
||||||
|
FLOAD f23, (CONTEXT_SIZE + 23 * REG_BYTES)(sp)
|
||||||
|
FLOAD f24, (CONTEXT_SIZE + 24 * REG_BYTES)(sp)
|
||||||
|
FLOAD f25, (CONTEXT_SIZE + 25 * REG_BYTES)(sp)
|
||||||
|
FLOAD f26, (CONTEXT_SIZE + 26 * REG_BYTES)(sp)
|
||||||
|
FLOAD f27, (CONTEXT_SIZE + 27 * REG_BYTES)(sp)
|
||||||
|
FLOAD f28, (CONTEXT_SIZE + 28 * REG_BYTES)(sp)
|
||||||
|
FLOAD f29, (CONTEXT_SIZE + 29 * REG_BYTES)(sp)
|
||||||
|
FLOAD f30, (CONTEXT_SIZE + 30 * REG_BYTES)(sp)
|
||||||
|
FLOAD f31, (CONTEXT_SIZE + 31 * REG_BYTES)(sp)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* restore mepc */
|
/* =====================================================================
|
||||||
LOAD a0, 2 * REG_BYTES(sp)
|
* 第四步:恢复通用寄存器(最后恢复 t0)
|
||||||
csrw mepc, a0
|
* ===================================================================== */
|
||||||
|
|
||||||
/* return address */
|
|
||||||
LOAD x1, 1 * REG_BYTES(sp)
|
LOAD x1, 1 * REG_BYTES(sp)
|
||||||
LOAD x4, 4 * REG_BYTES(sp)
|
LOAD x4, 4 * REG_BYTES(sp)
|
||||||
LOAD x5, 5 * REG_BYTES(sp)
|
|
||||||
LOAD x6, 6 * REG_BYTES(sp)
|
LOAD x6, 6 * REG_BYTES(sp)
|
||||||
LOAD x7, 7 * REG_BYTES(sp)
|
LOAD x7, 7 * REG_BYTES(sp)
|
||||||
LOAD x8, 8 * REG_BYTES(sp)
|
LOAD x8, 8 * REG_BYTES(sp)
|
||||||
@@ -92,161 +126,193 @@ os_port_context_switch_to:
|
|||||||
LOAD x29, 29 * REG_BYTES(sp)
|
LOAD x29, 29 * REG_BYTES(sp)
|
||||||
LOAD x30, 30 * REG_BYTES(sp)
|
LOAD x30, 30 * REG_BYTES(sp)
|
||||||
LOAD x31, 31 * REG_BYTES(sp)
|
LOAD x31, 31 * REG_BYTES(sp)
|
||||||
|
|
||||||
|
/* =====================================================================
|
||||||
|
* 第五步:恢复特权级控制 CSR 寄存器
|
||||||
|
* ===================================================================== */
|
||||||
|
LOAD t0, 2 * REG_BYTES(sp) // 恢复初始 PC 到 mepc
|
||||||
|
csrw mepc, t0
|
||||||
|
|
||||||
|
LOAD t0, 0 * REG_BYTES(sp) // 从栈中读取准备好的初始 mstatus
|
||||||
|
csrw mstatus, t0 // 修复:改用 csrw 强行覆盖
|
||||||
|
|
||||||
|
LOAD x5, 5 * REG_BYTES(sp) // 此时最后安全恢复 t0(x5)
|
||||||
|
|
||||||
|
/* =====================================================================
|
||||||
|
* 第六步:统一释放栈空间并退出
|
||||||
|
* ===================================================================== */
|
||||||
|
#if (OS_CFG_CPU_FPU_PRESENT)
|
||||||
|
addi sp, sp, (CONTEXT_SIZE + 32 * REG_BYTES)
|
||||||
|
#else
|
||||||
addi sp, sp, CONTEXT_SIZE
|
addi sp, sp, CONTEXT_SIZE
|
||||||
|
|
||||||
/* load float reg */
|
|
||||||
#if (OS_CFG_CPU_MPU_PRESENT)
|
|
||||||
FLOAD f0, 0 * REG_BYTES(sp)
|
|
||||||
FLOAD f1, 1 * REG_BYTES(sp)
|
|
||||||
FLOAD f2, 2 * REG_BYTES(sp)
|
|
||||||
FLOAD f3, 3 * REG_BYTES(sp)
|
|
||||||
FLOAD f4, 4 * REG_BYTES(sp)
|
|
||||||
FLOAD f5, 5 * REG_BYTES(sp)
|
|
||||||
FLOAD f6, 6 * REG_BYTES(sp)
|
|
||||||
FLOAD f7, 7 * REG_BYTES(sp)
|
|
||||||
FLOAD f8, 8 * REG_BYTES(sp)
|
|
||||||
FLOAD f9, 9 * REG_BYTES(sp)
|
|
||||||
FLOAD f10, 10 * REG_BYTES(sp)
|
|
||||||
FLOAD f11, 11 * REG_BYTES(sp)
|
|
||||||
FLOAD f12, 12 * REG_BYTES(sp)
|
|
||||||
FLOAD f13, 13 * REG_BYTES(sp)
|
|
||||||
FLOAD f14, 14 * REG_BYTES(sp)
|
|
||||||
FLOAD f15, 15 * REG_BYTES(sp)
|
|
||||||
FLOAD f16, 16 * REG_BYTES(sp)
|
|
||||||
FLOAD f17, 17 * REG_BYTES(sp)
|
|
||||||
FLOAD f18, 18 * REG_BYTES(sp)
|
|
||||||
FLOAD f19, 19 * REG_BYTES(sp)
|
|
||||||
FLOAD f20, 20 * REG_BYTES(sp)
|
|
||||||
FLOAD f21, 21 * REG_BYTES(sp)
|
|
||||||
FLOAD f22, 22 * REG_BYTES(sp)
|
|
||||||
FLOAD f23, 23 * REG_BYTES(sp)
|
|
||||||
FLOAD f24, 24 * REG_BYTES(sp)
|
|
||||||
FLOAD f25, 25 * REG_BYTES(sp)
|
|
||||||
FLOAD f26, 26 * REG_BYTES(sp)
|
|
||||||
FLOAD f27, 27 * REG_BYTES(sp)
|
|
||||||
FLOAD f28, 28 * REG_BYTES(sp)
|
|
||||||
FLOAD f29, 29 * REG_BYTES(sp)
|
|
||||||
FLOAD f30, 30 * REG_BYTES(sp)
|
|
||||||
FLOAD f31, 31 * REG_BYTES(sp)
|
|
||||||
addi sp, sp, 32 * REG_BYTES
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mret
|
mret
|
||||||
|
|
||||||
.endfunc
|
.endfunc
|
||||||
|
|
||||||
|
|
||||||
.section .text.SW_Handler,"ax",%progbits
|
.section .text.SW_Handler,"ax",%progbits
|
||||||
.align 8
|
.align 2
|
||||||
.func
|
.func
|
||||||
.global SW_Handler
|
.global SW_Handler
|
||||||
.extern g_os_port_switch_from_sp
|
.extern g_os_port_switch_from_sp
|
||||||
.extern g_os_port_switch_to_sp
|
.extern g_os_port_switch_to_sp
|
||||||
.extern os_isr_enter
|
|
||||||
.extern os_isr_leave
|
|
||||||
.extern os_port_on_switch_success
|
.extern os_port_on_switch_success
|
||||||
.extern g_t0
|
|
||||||
SW_Handler:
|
SW_Handler:
|
||||||
|
csrci mstatus, 0x08 // 立刻关闭全局中断 MIE = 0
|
||||||
|
|
||||||
|
/* =====================================================================
|
||||||
|
* 第一步:一揽子分配所有栈空间(防止碎片和二次偏移错误)
|
||||||
|
* ===================================================================== */
|
||||||
#if (OS_CFG_CPU_FPU_PRESENT)
|
#if (OS_CFG_CPU_FPU_PRESENT)
|
||||||
addi sp, sp, -32 * REG_BYTES
|
addi sp, sp, -(CONTEXT_SIZE + 32 * REG_BYTES)
|
||||||
FSTORE f0, 0 * REG_BYTES(sp)
|
#else
|
||||||
FSTORE f1, 1 * REG_BYTES(sp)
|
addi sp, sp, -CONTEXT_SIZE
|
||||||
FSTORE f2, 2 * REG_BYTES(sp)
|
|
||||||
FSTORE f3, 3 * REG_BYTES(sp)
|
|
||||||
FSTORE f4, 4 * REG_BYTES(sp)
|
|
||||||
FSTORE f5, 5 * REG_BYTES(sp)
|
|
||||||
FSTORE f6, 6 * REG_BYTES(sp)
|
|
||||||
FSTORE f7, 7 * REG_BYTES(sp)
|
|
||||||
FSTORE f8, 8 * REG_BYTES(sp)
|
|
||||||
FSTORE f9, 9 * REG_BYTES(sp)
|
|
||||||
FSTORE f10, 10 * REG_BYTES(sp)
|
|
||||||
FSTORE f11, 11 * REG_BYTES(sp)
|
|
||||||
FSTORE f12, 12 * REG_BYTES(sp)
|
|
||||||
FSTORE f13, 13 * REG_BYTES(sp)
|
|
||||||
FSTORE f14, 14 * REG_BYTES(sp)
|
|
||||||
FSTORE f15, 15 * REG_BYTES(sp)
|
|
||||||
FSTORE f16, 16 * REG_BYTES(sp)
|
|
||||||
FSTORE f17, 17 * REG_BYTES(sp)
|
|
||||||
FSTORE f18, 18 * REG_BYTES(sp)
|
|
||||||
FSTORE f19, 19 * REG_BYTES(sp)
|
|
||||||
FSTORE f20, 20 * REG_BYTES(sp)
|
|
||||||
FSTORE f21, 21 * REG_BYTES(sp)
|
|
||||||
FSTORE f22, 22 * REG_BYTES(sp)
|
|
||||||
FSTORE f23, 23 * REG_BYTES(sp)
|
|
||||||
FSTORE f24, 24 * REG_BYTES(sp)
|
|
||||||
FSTORE f25, 25 * REG_BYTES(sp)
|
|
||||||
FSTORE f26, 26 * REG_BYTES(sp)
|
|
||||||
FSTORE f27, 27 * REG_BYTES(sp)
|
|
||||||
FSTORE f28, 28 * REG_BYTES(sp)
|
|
||||||
FSTORE f29, 29 * REG_BYTES(sp)
|
|
||||||
FSTORE f30, 30 * REG_BYTES(sp)
|
|
||||||
FSTORE f31, 31 * REG_BYTES(sp)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
addi sp, sp, -CONTEXT_SIZE // 留出栈空间
|
/* =====================================================================
|
||||||
STORE t0, 5*REG_BYTES(sp) // 保存 t0
|
* 第二步:保存通用寄存器
|
||||||
|
* ===================================================================== */
|
||||||
|
STORE x5, 5 * REG_BYTES(sp) // 优先保存 t0,腾出临时寄存器
|
||||||
|
|
||||||
li t0, 0x80
|
li t0, 0x1800
|
||||||
|
csrw mstatus, t0 // M 模式
|
||||||
|
|
||||||
|
li t0, 0x1880
|
||||||
STORE t0, 0 * REG_BYTES(sp) // 设置 MPIE
|
STORE t0, 0 * REG_BYTES(sp) // 设置 MPIE
|
||||||
|
|
||||||
csrr t0, mepc
|
csrr t0, mepc
|
||||||
STORE t0, 2*REG_BYTES(sp) // 保存正在运行任务的 pc 指针
|
STORE t0, 2*REG_BYTES(sp) // 保存正在运行任务的 pc 指针
|
||||||
|
|
||||||
STORE x1, 1 * REG_BYTES(sp) // return address
|
STORE x1, 1 * REG_BYTES(sp) // ra
|
||||||
STORE x4, 4 * REG_BYTES(sp)
|
STORE x4, 4 * REG_BYTES(sp) // tp
|
||||||
STORE x6, 6 * REG_BYTES(sp)
|
STORE x6, 6 * REG_BYTES(sp) // t1
|
||||||
STORE x7, 7 * REG_BYTES(sp)
|
STORE x7, 7 * REG_BYTES(sp) // t2
|
||||||
STORE x8, 8 * REG_BYTES(sp)
|
STORE x8, 8 * REG_BYTES(sp) // s0/fp
|
||||||
STORE x9, 9 * REG_BYTES(sp)
|
STORE x9, 9 * REG_BYTES(sp) // s1
|
||||||
STORE x10, 10 * REG_BYTES(sp)
|
STORE x10, 10 * REG_BYTES(sp) // a0
|
||||||
STORE x11, 11 * REG_BYTES(sp)
|
STORE x11, 11 * REG_BYTES(sp) // a1
|
||||||
STORE x12, 12 * REG_BYTES(sp)
|
STORE x12, 12 * REG_BYTES(sp) // a2
|
||||||
STORE x13, 13 * REG_BYTES(sp)
|
STORE x13, 13 * REG_BYTES(sp) // a3
|
||||||
STORE x14, 14 * REG_BYTES(sp)
|
STORE x14, 14 * REG_BYTES(sp) // a4
|
||||||
STORE x15, 15 * REG_BYTES(sp)
|
STORE x15, 15 * REG_BYTES(sp) // a5
|
||||||
STORE x16, 16 * REG_BYTES(sp)
|
STORE x16, 16 * REG_BYTES(sp) // a6
|
||||||
STORE x17, 17 * REG_BYTES(sp)
|
STORE x17, 17 * REG_BYTES(sp) // a7
|
||||||
STORE x18, 18 * REG_BYTES(sp)
|
STORE x18, 18 * REG_BYTES(sp) // s2
|
||||||
STORE x19, 19 * REG_BYTES(sp)
|
STORE x19, 19 * REG_BYTES(sp) // s3
|
||||||
STORE x20, 20 * REG_BYTES(sp)
|
STORE x20, 20 * REG_BYTES(sp) // s4
|
||||||
STORE x21, 21 * REG_BYTES(sp)
|
STORE x21, 21 * REG_BYTES(sp) // s5
|
||||||
STORE x22, 22 * REG_BYTES(sp)
|
STORE x22, 22 * REG_BYTES(sp) // s6
|
||||||
STORE x23, 23 * REG_BYTES(sp)
|
STORE x23, 23 * REG_BYTES(sp) // s7
|
||||||
STORE x24, 24 * REG_BYTES(sp)
|
STORE x24, 24 * REG_BYTES(sp) // s8
|
||||||
STORE x25, 25 * REG_BYTES(sp)
|
STORE x25, 25 * REG_BYTES(sp) // s9
|
||||||
STORE x26, 26 * REG_BYTES(sp)
|
STORE x26, 26 * REG_BYTES(sp) // s10
|
||||||
STORE x27, 27 * REG_BYTES(sp)
|
STORE x27, 27 * REG_BYTES(sp) // s11
|
||||||
STORE x28, 28 * REG_BYTES(sp)
|
STORE x28, 28 * REG_BYTES(sp) // t3
|
||||||
STORE x29, 29 * REG_BYTES(sp)
|
STORE x29, 29 * REG_BYTES(sp) // t4
|
||||||
STORE x30, 30 * REG_BYTES(sp)
|
STORE x30, 30 * REG_BYTES(sp) // t5
|
||||||
STORE x31, 31 * REG_BYTES(sp)
|
STORE x31, 31 * REG_BYTES(sp) // t6
|
||||||
|
|
||||||
la s0, g_os_port_switch_from_sp
|
/* =====================================================================
|
||||||
LOAD s1, 0(s0)
|
* 第三步:保存 FPU 浮点寄存器(使用确定的、不受干扰的高位偏移)
|
||||||
STORE sp, 0(s1) // 将 sp 存入 g_os_port_switch_from_sp
|
* ===================================================================== */
|
||||||
|
#if (OS_CFG_CPU_FPU_PRESENT)
|
||||||
|
FSTORE f0, (CONTEXT_SIZE + 0 * REG_BYTES)(sp)
|
||||||
|
FSTORE f1, (CONTEXT_SIZE + 1 * REG_BYTES)(sp)
|
||||||
|
FSTORE f2, (CONTEXT_SIZE + 2 * REG_BYTES)(sp)
|
||||||
|
FSTORE f3, (CONTEXT_SIZE + 3 * REG_BYTES)(sp)
|
||||||
|
FSTORE f4, (CONTEXT_SIZE + 4 * REG_BYTES)(sp)
|
||||||
|
FSTORE f5, (CONTEXT_SIZE + 5 * REG_BYTES)(sp)
|
||||||
|
FSTORE f6, (CONTEXT_SIZE + 6 * REG_BYTES)(sp)
|
||||||
|
FSTORE f7, (CONTEXT_SIZE + 7 * REG_BYTES)(sp)
|
||||||
|
FSTORE f8, (CONTEXT_SIZE + 8 * REG_BYTES)(sp)
|
||||||
|
FSTORE f9, (CONTEXT_SIZE + 9 * REG_BYTES)(sp)
|
||||||
|
FSTORE f10, (CONTEXT_SIZE + 10 * REG_BYTES)(sp)
|
||||||
|
FSTORE f11, (CONTEXT_SIZE + 11 * REG_BYTES)(sp)
|
||||||
|
FSTORE f12, (CONTEXT_SIZE + 12 * REG_BYTES)(sp)
|
||||||
|
FSTORE f13, (CONTEXT_SIZE + 13 * REG_BYTES)(sp)
|
||||||
|
FSTORE f14, (CONTEXT_SIZE + 14 * REG_BYTES)(sp)
|
||||||
|
FSTORE f15, (CONTEXT_SIZE + 15 * REG_BYTES)(sp)
|
||||||
|
FSTORE f16, (CONTEXT_SIZE + 16 * REG_BYTES)(sp)
|
||||||
|
FSTORE f17, (CONTEXT_SIZE + 17 * REG_BYTES)(sp)
|
||||||
|
FSTORE f18, (CONTEXT_SIZE + 18 * REG_BYTES)(sp)
|
||||||
|
FSTORE f19, (CONTEXT_SIZE + 19 * REG_BYTES)(sp)
|
||||||
|
FSTORE f20, (CONTEXT_SIZE + 20 * REG_BYTES)(sp)
|
||||||
|
FSTORE f21, (CONTEXT_SIZE + 21 * REG_BYTES)(sp)
|
||||||
|
FSTORE f22, (CONTEXT_SIZE + 22 * REG_BYTES)(sp)
|
||||||
|
FSTORE f23, (CONTEXT_SIZE + 23 * REG_BYTES)(sp)
|
||||||
|
FSTORE f24, (CONTEXT_SIZE + 24 * REG_BYTES)(sp)
|
||||||
|
FSTORE f25, (CONTEXT_SIZE + 25 * REG_BYTES)(sp)
|
||||||
|
FSTORE f26, (CONTEXT_SIZE + 26 * REG_BYTES)(sp)
|
||||||
|
FSTORE f27, (CONTEXT_SIZE + 27 * REG_BYTES)(sp)
|
||||||
|
FSTORE f28, (CONTEXT_SIZE + 28 * REG_BYTES)(sp)
|
||||||
|
FSTORE f29, (CONTEXT_SIZE + 29 * REG_BYTES)(sp)
|
||||||
|
FSTORE f30, (CONTEXT_SIZE + 30 * REG_BYTES)(sp)
|
||||||
|
FSTORE f31, (CONTEXT_SIZE + 31 * REG_BYTES)(sp)
|
||||||
|
#endif
|
||||||
|
|
||||||
// 切换到 isr stack
|
/* =====================================================================
|
||||||
csrrw sp,mscratch,sp
|
* 第四步:保存旧任务 sp,并安全调用通知函数
|
||||||
|
* ===================================================================== */
|
||||||
|
la t0, g_os_port_switch_from_sp
|
||||||
|
LOAD t0, 0(t0)
|
||||||
|
STORE sp, 0(t0) // 将 sp 存入 g_os_port_switch_from_sp
|
||||||
|
|
||||||
|
// 此时调用 C 函数是完全安全的,因为所有寄存器都已在任务栈里备考
|
||||||
jal os_port_on_switch_success
|
jal os_port_on_switch_success
|
||||||
csrrw sp,mscratch,sp
|
|
||||||
|
|
||||||
la s0, g_os_port_switch_to_sp
|
/* =====================================================================
|
||||||
LOAD s1, 0(s0)
|
* 第五步:载入新任务的栈指针(SP)
|
||||||
LOAD sp, 0(s1) // 将 sp 指向 g_os_port_switch_to_sp 栈
|
* ===================================================================== */
|
||||||
|
la t0, g_os_port_switch_to_sp
|
||||||
|
LOAD t0, 0(t0)
|
||||||
|
LOAD sp, 0(t0) // 将 sp 指向 g_os_port_switch_to_sp 栈
|
||||||
|
|
||||||
LOAD a0, 2 * REG_BYTES(sp) // 加载/恢复 mepc
|
/* =====================================================================
|
||||||
csrw mepc, a0
|
* 第六步:恢复新任务的 FPU 浮点寄存器
|
||||||
|
* ===================================================================== */
|
||||||
|
#if (OS_CFG_CPU_FPU_PRESENT)
|
||||||
|
FLOAD f0, (CONTEXT_SIZE + 0 * REG_BYTES)(sp)
|
||||||
|
FLOAD f1, (CONTEXT_SIZE + 1 * REG_BYTES)(sp)
|
||||||
|
FLOAD f2, (CONTEXT_SIZE + 2 * REG_BYTES)(sp)
|
||||||
|
FLOAD f3, (CONTEXT_SIZE + 3 * REG_BYTES)(sp)
|
||||||
|
FLOAD f4, (CONTEXT_SIZE + 4 * REG_BYTES)(sp)
|
||||||
|
FLOAD f5, (CONTEXT_SIZE + 5 * REG_BYTES)(sp)
|
||||||
|
FLOAD f6, (CONTEXT_SIZE + 6 * REG_BYTES)(sp)
|
||||||
|
FLOAD f7, (CONTEXT_SIZE + 7 * REG_BYTES)(sp)
|
||||||
|
FLOAD f8, (CONTEXT_SIZE + 8 * REG_BYTES)(sp)
|
||||||
|
FLOAD f9, (CONTEXT_SIZE + 9 * REG_BYTES)(sp)
|
||||||
|
FLOAD f10, (CONTEXT_SIZE + 10 * REG_BYTES)(sp)
|
||||||
|
FLOAD f11, (CONTEXT_SIZE + 11 * REG_BYTES)(sp)
|
||||||
|
FLOAD f12, (CONTEXT_SIZE + 12 * REG_BYTES)(sp)
|
||||||
|
FLOAD f13, (CONTEXT_SIZE + 13 * REG_BYTES)(sp)
|
||||||
|
FLOAD f14, (CONTEXT_SIZE + 14 * REG_BYTES)(sp)
|
||||||
|
FLOAD f15, (CONTEXT_SIZE + 15 * REG_BYTES)(sp)
|
||||||
|
FLOAD f16, (CONTEXT_SIZE + 16 * REG_BYTES)(sp)
|
||||||
|
FLOAD f17, (CONTEXT_SIZE + 17 * REG_BYTES)(sp)
|
||||||
|
FLOAD f18, (CONTEXT_SIZE + 18 * REG_BYTES)(sp)
|
||||||
|
FLOAD f19, (CONTEXT_SIZE + 19 * REG_BYTES)(sp)
|
||||||
|
FLOAD f20, (CONTEXT_SIZE + 20 * REG_BYTES)(sp)
|
||||||
|
FLOAD f21, (CONTEXT_SIZE + 21 * REG_BYTES)(sp)
|
||||||
|
FLOAD f22, (CONTEXT_SIZE + 22 * REG_BYTES)(sp)
|
||||||
|
FLOAD f23, (CONTEXT_SIZE + 23 * REG_BYTES)(sp)
|
||||||
|
FLOAD f24, (CONTEXT_SIZE + 24 * REG_BYTES)(sp)
|
||||||
|
FLOAD f25, (CONTEXT_SIZE + 25 * REG_BYTES)(sp)
|
||||||
|
FLOAD f26, (CONTEXT_SIZE + 26 * REG_BYTES)(sp)
|
||||||
|
FLOAD f27, (CONTEXT_SIZE + 27 * REG_BYTES)(sp)
|
||||||
|
FLOAD f28, (CONTEXT_SIZE + 28 * REG_BYTES)(sp)
|
||||||
|
FLOAD f29, (CONTEXT_SIZE + 29 * REG_BYTES)(sp)
|
||||||
|
FLOAD f30, (CONTEXT_SIZE + 30 * REG_BYTES)(sp)
|
||||||
|
FLOAD f31, (CONTEXT_SIZE + 31 * REG_BYTES)(sp)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* =====================================================================
|
||||||
|
* 第七步:全面恢复通用寄存器(最后恢复 t0)
|
||||||
|
* ===================================================================== */
|
||||||
LOAD x1, 1 * REG_BYTES(sp)
|
LOAD x1, 1 * REG_BYTES(sp)
|
||||||
|
|
||||||
li t0, 0x1800
|
|
||||||
csrs mstatus, t0 // 确保 M 模式
|
|
||||||
|
|
||||||
LOAD t0, 0*REG_BYTES(sp) // 加载 mstatus
|
|
||||||
csrs mstatus, t0 // 恢复 mstatus
|
|
||||||
|
|
||||||
LOAD x4, 4 * REG_BYTES(sp)
|
LOAD x4, 4 * REG_BYTES(sp)
|
||||||
LOAD x5, 5 * REG_BYTES(sp)
|
// LOAD x5, 5 * REG_BYTES(sp) // 恢复 t0
|
||||||
LOAD x6, 6 * REG_BYTES(sp)
|
LOAD x6, 6 * REG_BYTES(sp)
|
||||||
LOAD x7, 7 * REG_BYTES(sp)
|
LOAD x7, 7 * REG_BYTES(sp)
|
||||||
LOAD x8, 8 * REG_BYTES(sp)
|
LOAD x8, 8 * REG_BYTES(sp)
|
||||||
@@ -273,49 +339,88 @@ SW_Handler:
|
|||||||
LOAD x29, 29 * REG_BYTES(sp)
|
LOAD x29, 29 * REG_BYTES(sp)
|
||||||
LOAD x30, 30 * REG_BYTES(sp)
|
LOAD x30, 30 * REG_BYTES(sp)
|
||||||
LOAD x31, 31 * REG_BYTES(sp)
|
LOAD x31, 31 * REG_BYTES(sp)
|
||||||
addi sp, sp, CONTEXT_SIZE // 恢复栈指针
|
|
||||||
|
|
||||||
/* load float reg */
|
|
||||||
|
/* =====================================================================
|
||||||
|
* 第八步:恢复新任务的 CSR 寄存器
|
||||||
|
* ===================================================================== */
|
||||||
|
LOAD t0, 2 * REG_BYTES(sp) // 恢复 mepc
|
||||||
|
csrw mepc, t0
|
||||||
|
|
||||||
|
LOAD t0, 0 * REG_BYTES(sp) // 恢复 mstatus
|
||||||
|
csrw mstatus, t0
|
||||||
|
|
||||||
|
LOAD x5, 5 * REG_BYTES(sp) // 恢复 t0
|
||||||
|
|
||||||
|
/* =====================================================================
|
||||||
|
* 第九步:彻底释放栈空间并退出
|
||||||
|
* ===================================================================== */
|
||||||
#if (OS_CFG_CPU_FPU_PRESENT)
|
#if (OS_CFG_CPU_FPU_PRESENT)
|
||||||
FLOAD f0, 0 * REG_BYTES(sp)
|
addi sp, sp, (CONTEXT_SIZE + 32 * REG_BYTES)
|
||||||
FLOAD f1, 1 * REG_BYTES(sp)
|
#else
|
||||||
FLOAD f2, 2 * REG_BYTES(sp)
|
addi sp, sp, CONTEXT_SIZE
|
||||||
FLOAD f3, 3 * REG_BYTES(sp)
|
|
||||||
FLOAD f4, 4 * REG_BYTES(sp)
|
|
||||||
FLOAD f5, 5 * REG_BYTES(sp)
|
|
||||||
FLOAD f6, 6 * REG_BYTES(sp)
|
|
||||||
FLOAD f7, 7 * REG_BYTES(sp)
|
|
||||||
FLOAD f8, 8 * REG_BYTES(sp)
|
|
||||||
FLOAD f9, 9 * REG_BYTES(sp)
|
|
||||||
FLOAD f10, 10 * REG_BYTES(sp)
|
|
||||||
FLOAD f11, 11 * REG_BYTES(sp)
|
|
||||||
FLOAD f12, 12 * REG_BYTES(sp)
|
|
||||||
FLOAD f13, 13 * REG_BYTES(sp)
|
|
||||||
FLOAD f14, 14 * REG_BYTES(sp)
|
|
||||||
FLOAD f15, 15 * REG_BYTES(sp)
|
|
||||||
FLOAD f16, 16 * REG_BYTES(sp)
|
|
||||||
FLOAD f17, 17 * REG_BYTES(sp)
|
|
||||||
FLOAD f18, 18 * REG_BYTES(sp)
|
|
||||||
FLOAD f19, 19 * REG_BYTES(sp)
|
|
||||||
FLOAD f20, 20 * REG_BYTES(sp)
|
|
||||||
FLOAD f21, 21 * REG_BYTES(sp)
|
|
||||||
FLOAD f22, 22 * REG_BYTES(sp)
|
|
||||||
FLOAD f23, 23 * REG_BYTES(sp)
|
|
||||||
FLOAD f24, 24 * REG_BYTES(sp)
|
|
||||||
FLOAD f25, 25 * REG_BYTES(sp)
|
|
||||||
FLOAD f26, 26 * REG_BYTES(sp)
|
|
||||||
FLOAD f27, 27 * REG_BYTES(sp)
|
|
||||||
FLOAD f28, 28 * REG_BYTES(sp)
|
|
||||||
FLOAD f29, 29 * REG_BYTES(sp)
|
|
||||||
FLOAD f30, 30 * REG_BYTES(sp)
|
|
||||||
FLOAD f31, 31 * REG_BYTES(sp)
|
|
||||||
addi sp, sp, 32 * REG_BYTES
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* 执行 mret。此时:
|
||||||
|
* 1. 硬件会自动把当前 mstatus.MPIE (1) 复制到 mstatus.MIE,从而开启全局中断。
|
||||||
|
* 2. 程序跳转到 mepc 寄存器指向的地址(即新任务继续运行的代码处)。 */
|
||||||
mret // 从 M 模式退出
|
mret // 从 M 模式退出
|
||||||
.endfunc
|
.endfunc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.section .text.SysTick_Handler,"ax",%progbits
|
||||||
|
.align 2
|
||||||
|
.global SysTick_Handler
|
||||||
|
.extern SysTick_Handler_C
|
||||||
|
.func
|
||||||
|
SysTick_Handler:
|
||||||
|
// csrci mstatus, 8 // 关闭中断
|
||||||
|
/* 1. 因为是硬件中断,先在当前栈上保存必要的临时寄存器(Caller-saved) */
|
||||||
|
addi sp, sp, -16 * REG_BYTES
|
||||||
|
STORE x1, 0 * REG_BYTES(sp) # ra
|
||||||
|
STORE x5, 1 * REG_BYTES(sp) # t0
|
||||||
|
STORE x6, 2 * REG_BYTES(sp) # t1
|
||||||
|
STORE x7, 3 * REG_BYTES(sp) # t2
|
||||||
|
STORE x10, 4 * REG_BYTES(sp) # a0
|
||||||
|
STORE x11, 5 * REG_BYTES(sp) # a1
|
||||||
|
STORE x12, 6 * REG_BYTES(sp) # a2
|
||||||
|
STORE x13, 7 * REG_BYTES(sp) # a3
|
||||||
|
STORE x14, 8 * REG_BYTES(sp) # a4
|
||||||
|
STORE x15, 9 * REG_BYTES(sp) # a5
|
||||||
|
STORE x16, 10 * REG_BYTES(sp) # a6
|
||||||
|
STORE x17, 11 * REG_BYTES(sp) # a7
|
||||||
|
STORE x28, 12 * REG_BYTES(sp) # t3
|
||||||
|
STORE x29, 13 * REG_BYTES(sp) # t4
|
||||||
|
STORE x30, 14 * REG_BYTES(sp) # t5
|
||||||
|
STORE x31, 15 * REG_BYTES(sp) # t6
|
||||||
|
|
||||||
|
/* 2. 清除定时器硬件中断标志位(防止重复触发),并调用 C 语言的时钟处理函数 */
|
||||||
|
jal SysTick_Handler_C
|
||||||
|
|
||||||
|
/* 3. 恢复临时寄存器 */
|
||||||
|
LOAD x1, 0 * REG_BYTES(sp) # ra
|
||||||
|
LOAD x5, 1 * REG_BYTES(sp) # t0
|
||||||
|
LOAD x6, 2 * REG_BYTES(sp) # t1
|
||||||
|
LOAD x7, 3 * REG_BYTES(sp) # t2
|
||||||
|
LOAD x10, 4 * REG_BYTES(sp) # a0
|
||||||
|
LOAD x11, 5 * REG_BYTES(sp) # a1
|
||||||
|
LOAD x12, 6 * REG_BYTES(sp) # a2
|
||||||
|
LOAD x13, 7 * REG_BYTES(sp) # a3
|
||||||
|
LOAD x14, 8 * REG_BYTES(sp) # a4
|
||||||
|
LOAD x15, 9 * REG_BYTES(sp) # a5
|
||||||
|
LOAD x16, 10 * REG_BYTES(sp) # a6
|
||||||
|
LOAD x17, 11 * REG_BYTES(sp) # a7
|
||||||
|
LOAD x28, 12 * REG_BYTES(sp) # t3
|
||||||
|
LOAD x29, 13 * REG_BYTES(sp) # t4
|
||||||
|
LOAD x30, 14 * REG_BYTES(sp) # t5
|
||||||
|
LOAD x31, 15 * REG_BYTES(sp) # t6
|
||||||
|
|
||||||
|
addi sp, sp, 16 * REG_BYTES
|
||||||
|
|
||||||
|
/* 4. 退出硬件中断 */
|
||||||
|
mret
|
||||||
|
.endfunc
|
||||||
|
|
||||||
.align 4
|
.align 4
|
||||||
.end
|
.end
|
||||||
Reference in New Issue
Block a user