实现中断与异常
This commit is contained in:
@@ -43,7 +43,7 @@ static void write(uint32_t addr, uint32_t data) {
|
||||
}
|
||||
if (data == '\n') {
|
||||
g_buff[g_index] = 0;
|
||||
printf("%s", g_buff);
|
||||
printf("\033[33m%s\033[0m", g_buff);
|
||||
g_index = 0;
|
||||
}
|
||||
}
|
||||
|
129
cpu/riscv.c
129
cpu/riscv.c
@@ -67,19 +67,33 @@
|
||||
|
||||
|
||||
void mem_w_write(riscv_t * riscv, uint32_t addr, uint32_t value) {
|
||||
if (addr & 0x3) {
|
||||
riscv->exc_code = 6;
|
||||
riscv->mtval = addr;
|
||||
return;
|
||||
}
|
||||
if (addr >= MEM_ADDR_BASE && addr < MEM_ADDR_BASE + MEM_SIZE) {
|
||||
mem_wr(addr) = value;
|
||||
} else {
|
||||
device_write(riscv, addr, value);
|
||||
riscv->exc_code = 7;
|
||||
riscv->mtval = addr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mem_wh_write(riscv_t* riscv, uint32_t addr, uint16_t value) {
|
||||
if (addr & 0x1) {
|
||||
riscv->exc_code = 6;
|
||||
riscv->mtval = addr;
|
||||
return;
|
||||
}
|
||||
if (addr >= MEM_ADDR_BASE && addr < MEM_ADDR_BASE + MEM_SIZE) {
|
||||
mem_wrh(addr) = value;
|
||||
} else {
|
||||
device_write(riscv, addr, value);
|
||||
riscv->exc_code = 7;
|
||||
riscv->mtval = addr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,17 +102,26 @@ void mem_wb_write(riscv_t* riscv, uint32_t addr, uint8_t value) {
|
||||
mem_wrb(addr) = value;
|
||||
} else {
|
||||
device_write(riscv, addr, value);
|
||||
riscv->exc_code = 7;
|
||||
riscv->mtval = addr;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t mem_w_read(riscv_t* riscv, uint32_t addr) {
|
||||
uint32_t ret = 0xaaaaaaaa;
|
||||
if (addr & 0x3) {
|
||||
riscv->exc_code = 4;
|
||||
riscv->mtval = addr;
|
||||
return ret;
|
||||
}
|
||||
if (addr >= MEM_ADDR_BASE && addr < MEM_ADDR_BASE + MEM_SIZE) {
|
||||
ret = mem_wr(addr);
|
||||
} else if (addr>=riscv->rom_addr_base && addr<riscv->rom_addr_base+riscv->rom_size){
|
||||
ret = rom_wr(addr);
|
||||
} else {
|
||||
device_read(riscv, addr, ret);
|
||||
riscv->exc_code = 5;
|
||||
riscv->mtval = addr;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -106,12 +129,19 @@ uint32_t mem_w_read(riscv_t* riscv, uint32_t addr) {
|
||||
|
||||
uint16_t mem_wh_read(riscv_t* riscv, uint32_t addr) {
|
||||
uint16_t ret = 0xaaaa;
|
||||
if (addr & 0x1) {
|
||||
riscv->exc_code = 4;
|
||||
riscv->mtval = addr;
|
||||
return ret;
|
||||
}
|
||||
if (addr >= MEM_ADDR_BASE && addr < MEM_ADDR_BASE + MEM_SIZE) {
|
||||
ret = mem_wrh(addr);
|
||||
} else if (addr>=riscv->rom_addr_base && addr<riscv->rom_addr_base+riscv->rom_size){
|
||||
ret = rom_wrh(addr);
|
||||
} else {
|
||||
device_read(riscv, addr, ret);
|
||||
riscv->exc_code = 5;
|
||||
riscv->mtval = addr;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -125,6 +155,8 @@ uint8_t mem_wb_read(riscv_t* riscv, uint32_t addr) {
|
||||
ret = rom_wrb(addr);
|
||||
} else {
|
||||
device_read(riscv, addr, ret);
|
||||
riscv->exc_code = 5;
|
||||
riscv->mtval = addr;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -302,8 +334,14 @@ void ins_lui(riscv_t* riscv, int imm, int rd) {
|
||||
}
|
||||
|
||||
void ins_mret(riscv_t* riscv) {
|
||||
riscv->pc = riscv->csrs[0x305];
|
||||
printf("mret\n");
|
||||
riscv->pc = riscv->mepc;
|
||||
if (riscv->mstatus & MSTATUS_MPIE) {
|
||||
riscv->mstatus &= ~MSTATUS_MPIE;
|
||||
riscv->mstatus |= MSTATUS_MIE;
|
||||
} else {
|
||||
riscv->mstatus &= ~MSTATUS_MIE;
|
||||
}
|
||||
printf("mret: pc=%08x\n", riscv->pc);
|
||||
}
|
||||
|
||||
void ins_or(riscv_t* riscv, int rs2, int rs1, int rd) {
|
||||
@@ -467,6 +505,7 @@ int riscv_decode(riscv_t* riscv, uint32_t ins) {
|
||||
ins_bgeu(riscv, rs2, rs1, imm);
|
||||
break;
|
||||
default:
|
||||
riscv->exc_code = 2;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -490,6 +529,7 @@ int riscv_decode(riscv_t* riscv, uint32_t ins) {
|
||||
ins_lhu(riscv, rs1, imm, rd);
|
||||
break;
|
||||
default:
|
||||
riscv->exc_code = 2;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -506,6 +546,7 @@ int riscv_decode(riscv_t* riscv, uint32_t ins) {
|
||||
ins_sw(riscv, rs2, rs1, imm);
|
||||
break;
|
||||
default:
|
||||
riscv->exc_code = 2;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -544,6 +585,7 @@ int riscv_decode(riscv_t* riscv, uint32_t ins) {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
riscv->exc_code = 2;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -583,6 +625,7 @@ int riscv_decode(riscv_t* riscv, uint32_t ins) {
|
||||
ins_and(riscv, rs2, rs1, rd);
|
||||
break;
|
||||
default:
|
||||
riscv->exc_code = 2;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -591,7 +634,15 @@ int riscv_decode(riscv_t* riscv, uint32_t ins) {
|
||||
switch (funct3)
|
||||
{
|
||||
case 0x0:
|
||||
ins_ebreak(riscv);
|
||||
if (imm == 1) {
|
||||
ins_ebreak(riscv);
|
||||
} else if (imm == 0) {
|
||||
ins_ecall(riscv);
|
||||
} else if (ins == 0x30200073) {
|
||||
ins_mret(riscv);
|
||||
} else{
|
||||
riscv->exc_code = 2;
|
||||
}
|
||||
break;
|
||||
case 0x1:
|
||||
ins_csrrw(riscv, rs1, rd, imm);
|
||||
@@ -613,12 +664,17 @@ int riscv_decode(riscv_t* riscv, uint32_t ins) {
|
||||
ins_csrrci(riscv, rs1, rd, imm);
|
||||
break;
|
||||
default:
|
||||
riscv->exc_code = 2;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
riscv->exc_code = 2;
|
||||
break;
|
||||
}
|
||||
if (riscv->exc_code == 2) {
|
||||
riscv->mtval = ins;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -645,15 +701,67 @@ int riscv_init(riscv_t* riscv, uint32_t* rom, uint32_t rom_addr_base, uint32_t r
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 进入中断 is_interrupt=1 进入中断 is_interrupt=0 进入异常
|
||||
// irq_num 中断号
|
||||
int riscv_enter_trap(riscv_t* riscv, int is_interrupt, int irq_num) {
|
||||
riscv->mepc = riscv->pc;
|
||||
riscv->mcause = (is_interrupt << 31) | irq_num;
|
||||
riscv->pc = riscv->mtvec;
|
||||
// 禁用全局中断
|
||||
if (riscv->mstatus & MSTATUS_MIE) {
|
||||
riscv->mstatus &= ~MSTATUS_MIE;
|
||||
riscv->mstatus |= MSTATUS_MPIE;
|
||||
} else {
|
||||
riscv->mstatus &= ~MSTATUS_MPIE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 检测是否产生了中断
|
||||
int riscv_irq_check(riscv_t* riscv) {
|
||||
uint32_t tmp;
|
||||
int irq_num = 0;
|
||||
tmp = riscv->mip & (MIP_MSIP | MIP_MTIP | MIP_MEIP);
|
||||
if (tmp) {
|
||||
if (riscv->mstatus & MSTATUS_MIE) {
|
||||
if ((riscv->mie & MIP_MSIP) && (tmp & MIP_MSIP)) {
|
||||
irq_num = 3;
|
||||
} else if ((riscv->mie & MIP_MTIP) && (tmp & MIP_MTIP)) {
|
||||
irq_num = 7;
|
||||
} else if ((riscv->mie & MIP_MEIP) && (tmp & MIP_MEIP)) {
|
||||
irq_num = 11;
|
||||
}
|
||||
riscv->mtval = 0;
|
||||
riscv_enter_trap(riscv, 1, irq_num);
|
||||
if (irq_num>0) {
|
||||
riscv->mip &= ~(1 << irq_num);
|
||||
irq_num = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int riscv_run(riscv_t* riscv) {
|
||||
int ret = 0;
|
||||
uint32_t pc;
|
||||
while (1) {
|
||||
if(riscv->pc >= riscv->rom_addr_base + riscv->rom_size || riscv->pc < riscv->rom_addr_base){
|
||||
printf("riscv run out of rom pc=%08x\n",riscv->pc);
|
||||
if (riscv->pc == 0) {
|
||||
break;
|
||||
}
|
||||
uint32_t instr = riscv->rom[(riscv->pc-riscv->rom_addr_base) >> 2];
|
||||
if (riscv->pc >= riscv->rom_addr_base + riscv->rom_size || riscv->pc < riscv->rom_addr_base) {
|
||||
// 指令访问失败
|
||||
riscv->mtval = riscv->pc;
|
||||
printf("riscv run out of rom pc=%08x\n",riscv->pc);
|
||||
riscv_enter_trap(riscv, 0, 1);
|
||||
printf("riscv run out of rom pc=%08x\n",riscv->pc);
|
||||
}
|
||||
if (riscv->pc & 0x3) {
|
||||
// 指令地址未对齐
|
||||
riscv->mtval = riscv->pc;
|
||||
riscv_enter_trap(riscv, 0, 0);
|
||||
}
|
||||
uint32_t instr = riscv->rom[(riscv->pc - riscv->rom_addr_base) >> 2];
|
||||
// printf("pc: %08x instr: %08x\n", riscv->pc, instr);
|
||||
pc = riscv->pc;
|
||||
ret = riscv_decode(riscv, instr);
|
||||
@@ -662,10 +770,19 @@ int riscv_run(riscv_t* riscv) {
|
||||
if (riscv->pc == pc) {
|
||||
riscv->pc += 4;
|
||||
}
|
||||
if (riscv->exc_code > 0) {
|
||||
riscv_enter_trap(riscv, 0, riscv->exc_code);
|
||||
riscv->exc_code = 0;
|
||||
}
|
||||
riscv_irq_check(riscv);
|
||||
// riscv_print(riscv);
|
||||
if(ret){
|
||||
break;
|
||||
}
|
||||
if (riscv->mscratch == 0xffffffff) {
|
||||
printf("proactively terminate\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("riscv run end\n");
|
||||
return 0;
|
||||
|
34
cpu/riscv.h
34
cpu/riscv.h
@@ -197,6 +197,7 @@ typedef struct {
|
||||
uint32_t rom_size;
|
||||
uint32_t rom_addr_base;
|
||||
uint32_t pc;
|
||||
int32_t exc_code;
|
||||
uint32_t reg[32];
|
||||
uint32_t csrs[4096];
|
||||
}riscv_t;
|
||||
@@ -210,4 +211,37 @@ typedef struct {
|
||||
#define rom_wrh(addr) ((uint16_t *)(riscv->rom))[(addr-riscv->rom_addr_base) >> 1]
|
||||
|
||||
|
||||
// trap 相关定义
|
||||
#define mstatus csrs[0x300] // 机器状态寄存器
|
||||
#define misa csrs[0x301] // ISA扩展
|
||||
#define medeleg csrs[0x302] // 异常委托寄存器
|
||||
#define mideleg csrs[0x303] // 中断委托寄存器
|
||||
#define mie csrs[0x304] // 中断使能寄存器
|
||||
#define mtvec csrs[0x305] // 异常向量寄存器
|
||||
#define mcounteren csrs[0x306] // 统计计数器使能寄存器
|
||||
#define mstatush csrs[0x310] // 添加的状态寄存器高
|
||||
|
||||
#define mscratch csrs[0x340] // 存储器 软件中可用于暂时存放一个字大小的数据
|
||||
#define mepc csrs[0x341] // 异常程序计数器 指向发生异常的指令
|
||||
#define mcause csrs[0x342] // 异常原因寄存器
|
||||
#define mtval csrs[0x343] // 异常值寄存器 地址例外出错的地址 非法指令本身
|
||||
#define mip csrs[0x344] // 中断请求寄存器 它列出正在准备处理的中断
|
||||
#define mtinst csrs[0x34a] // 存储器指令寄存器 当发生异常时,它包含异常指令
|
||||
#define mtval2 csrs[0x34b] // 坏的物理地址
|
||||
#define mcycle csrs[0xc00] // 循环计数器
|
||||
#define minstret csrs[0xc02] // 执行指令计数器
|
||||
|
||||
|
||||
// 只有机器模式的cpu只有这两个位起作用 清除这两个位表示禁用全局中断
|
||||
#define MSTATUS_MIE 0x00000008 // 中断使能位
|
||||
#define MSTATUS_MPIE 0x00000080 // 进异常时会自动清除MIE MPIE是清除之前的状态
|
||||
|
||||
|
||||
#define MIP_MSIP (1 << IRQ_M_SOFT)
|
||||
#define MIP_MTIP (1 << IRQ_M_TIMER)
|
||||
#define MIP_MEIP (1 << IRQ_M_EXT)
|
||||
#define IRQ_M_SOFT 3
|
||||
#define IRQ_M_TIMER 7
|
||||
#define IRQ_M_EXT 11
|
||||
|
||||
#endif
|
@@ -30,7 +30,9 @@ CFLAG=[
|
||||
SRC=[
|
||||
"riscv/main.c",
|
||||
"riscv/test.c",
|
||||
"riscv/start.S"
|
||||
"riscv/interrupt.c",
|
||||
"riscv/start.S",
|
||||
"riscv/trap.S"
|
||||
]
|
||||
|
||||
LD_FILE="riscv.ld"
|
||||
|
8
riscv.ld
8
riscv.ld
@@ -144,10 +144,14 @@ SECTIONS
|
||||
PROVIDE( end = . );
|
||||
PROVIDE( _heap_start = . );
|
||||
|
||||
.stack ORIGIN(dram) + LENGTH(dram) - __stack_size :
|
||||
.stack ORIGIN(dram) + LENGTH(dram) - __stack_size*3 :
|
||||
{
|
||||
PROVIDE( _heap_end = . );
|
||||
. = __stack_size;
|
||||
. += __stack_size;
|
||||
PROVIDE( _sp = . );
|
||||
. += __stack_size;
|
||||
PROVIDE( _irq_sp = . );
|
||||
. += __stack_size;
|
||||
PROVIDE( _exc_sp = . );
|
||||
} >dram AT>dram
|
||||
}
|
||||
|
49
riscv/context.h
Normal file
49
riscv/context.h
Normal file
@@ -0,0 +1,49 @@
|
||||
|
||||
#ifndef context_h__
|
||||
#define context_h__
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
typedef struct {
|
||||
uint32_t ra;//x1 0
|
||||
uint32_t sp;//x2 1
|
||||
uint32_t gp;//x3 2
|
||||
uint32_t tp;//x4 3
|
||||
uint32_t t0;//x5 4
|
||||
uint32_t t1;//x6 5
|
||||
uint32_t t2;//x7 6
|
||||
uint32_t t6;//x31 7
|
||||
uint32_t s1;//x9 8
|
||||
uint32_t a0;//x10 9
|
||||
uint32_t a1;//x11 10
|
||||
uint32_t a2;//x12 11
|
||||
uint32_t a3;//x13 12
|
||||
uint32_t a4;//x14 13
|
||||
uint32_t a5;//x15 14
|
||||
uint32_t a6;//x16 15
|
||||
uint32_t a7;//x17 16
|
||||
|
||||
uint32_t s2;//x18 17
|
||||
uint32_t s3;//x19 18
|
||||
uint32_t s4;//x20 19
|
||||
uint32_t s5;//x21 20
|
||||
uint32_t s6;//x22 21
|
||||
uint32_t s7;//x23 22
|
||||
uint32_t s8;//x24 23
|
||||
uint32_t s9;//x25 24
|
||||
uint32_t s10;//x26 25
|
||||
uint32_t s11;//x27 26
|
||||
uint32_t t3;//x28 27
|
||||
uint32_t t4;//x29 28
|
||||
uint32_t t5;//x30 29
|
||||
uint32_t s0;//fp(x8) 30
|
||||
|
||||
uint32_t mstatus;//31
|
||||
uint32_t mepc;//32
|
||||
} stack_context;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
37
riscv/head.h
37
riscv/head.h
@@ -2,6 +2,43 @@
|
||||
#ifndef head_h__
|
||||
#define head_h__
|
||||
|
||||
|
||||
|
||||
#define read_csr(reg) ({ unsigned long __tmp; \
|
||||
asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
|
||||
__tmp; })
|
||||
|
||||
#define write_csr(reg, val) ({ \
|
||||
if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
|
||||
asm volatile ("csrw " #reg ", %0" :: "i"(val)); \
|
||||
else \
|
||||
asm volatile ("csrw " #reg ", %0" :: "r"(val)); })
|
||||
|
||||
#define swap_csr(reg, val) ({ unsigned long __tmp; \
|
||||
if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
|
||||
asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "i"(val)); \
|
||||
else \
|
||||
asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "r"(val)); \
|
||||
__tmp; })
|
||||
|
||||
#define set_csr(reg, bit) ({ unsigned long __tmp; \
|
||||
if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
|
||||
asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
|
||||
else \
|
||||
asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
|
||||
__tmp; })
|
||||
|
||||
#define clear_csr(reg, bit) ({ unsigned long __tmp; \
|
||||
if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
|
||||
asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
|
||||
else \
|
||||
asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
|
||||
__tmp; })
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int my_printf(const char* fmt, ...);
|
||||
void cpu_test();
|
||||
|
||||
|
13
riscv/interrupt.c
Normal file
13
riscv/interrupt.c
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
#include "context.h"
|
||||
#include "head.h"
|
||||
|
||||
void interrupt_entry(uint32_t irq_num) {
|
||||
my_printf("interrupt_entry %d\n", irq_num);
|
||||
}
|
||||
|
||||
void trap_entry(uint32_t irq_num) {
|
||||
my_printf("trap_entry %d\n", irq_num);
|
||||
write_csr(mscratch, 0xffffffff);
|
||||
}
|
@@ -44,12 +44,19 @@ int main()
|
||||
{
|
||||
int a=1;
|
||||
int b=2;
|
||||
// typedef void (*fun_t)(void);
|
||||
// fun_t fun = (fun_t)0xffffffff;
|
||||
// fun();
|
||||
int c = add(a, b);
|
||||
my_printf("Hello World! %s\n", "Andy");
|
||||
my_printf("add(%d, %d)=%d\n", a, b, c);
|
||||
a = 67;b = -78;
|
||||
my_printf("mul(%d, %d)=%d\n", a, b, a * b);
|
||||
my_printf("ram_val test: %s\n", g_string);
|
||||
set_csr(mstatus, 0x00000008);
|
||||
set_csr(mie, (1 << 3));
|
||||
set_csr(mip, (1 << 3));
|
||||
cpu_test();
|
||||
|
||||
return 0;
|
||||
}
|
@@ -4,6 +4,7 @@
|
||||
.type _start,@function
|
||||
|
||||
.extern main
|
||||
.extern trap_handler
|
||||
_start:
|
||||
|
||||
la sp, _sp
|
||||
@@ -30,6 +31,8 @@ _start:
|
||||
addi a0, a0, 4
|
||||
bltu a0, a1, 1b
|
||||
2:
|
||||
la a0, trap_handler
|
||||
csrw mtvec, a0
|
||||
|
||||
/* Call global constructors */
|
||||
# la a0, __libc_fini_array
|
||||
|
116
riscv/trap.S
Normal file
116
riscv/trap.S
Normal file
@@ -0,0 +1,116 @@
|
||||
|
||||
.equ REGBYTES, 0x4
|
||||
|
||||
|
||||
.macro PUSH_ALL_REG
|
||||
addi sp, sp, -33*REGBYTES
|
||||
sw x1, 0*REGBYTES(sp) //ra
|
||||
|
||||
sw x2, 1*REGBYTES(sp) //sp
|
||||
sw x3, 2*REGBYTES(sp) //gp
|
||||
sw x4, 3*REGBYTES(sp) //tp
|
||||
|
||||
sw x5, 4*REGBYTES(sp) //t0
|
||||
sw x6, 5*REGBYTES(sp) //t1
|
||||
sw x7, 6*REGBYTES(sp) //t2
|
||||
sw x8, 30*REGBYTES(sp)
|
||||
sw x9, 8*REGBYTES(sp)
|
||||
sw x10, 9*REGBYTES(sp) //a0
|
||||
sw x11, 10*REGBYTES(sp) //a1
|
||||
sw x12, 11*REGBYTES(sp) //a2
|
||||
sw x13, 12*REGBYTES(sp) //a3
|
||||
sw x14, 13*REGBYTES(sp) //a4
|
||||
sw x15, 14*REGBYTES(sp) //a5
|
||||
sw x16, 15*REGBYTES(sp) //a6
|
||||
sw x17, 16*REGBYTES(sp) //a7
|
||||
sw x18, 17*REGBYTES(sp)
|
||||
sw x19, 18*REGBYTES(sp)
|
||||
sw x20, 19*REGBYTES(sp)
|
||||
sw x21, 20*REGBYTES(sp)
|
||||
sw x22, 21*REGBYTES(sp)
|
||||
sw x23, 22*REGBYTES(sp)
|
||||
sw x24, 23*REGBYTES(sp)
|
||||
sw x25, 24*REGBYTES(sp)
|
||||
sw x26, 25*REGBYTES(sp)
|
||||
sw x27, 26*REGBYTES(sp)
|
||||
sw x28, 27*REGBYTES(sp) //t3
|
||||
sw x29, 28*REGBYTES(sp) //t4
|
||||
sw x30, 29*REGBYTES(sp) //t5
|
||||
sw x31, 7*REGBYTES(sp) //t6
|
||||
csrr t0, mstatus
|
||||
sw t0, 31*REGBYTES(sp)
|
||||
csrr t0, mepc
|
||||
sw t0, 32*REGBYTES(sp)
|
||||
.endm
|
||||
|
||||
.macro POP_ALL_REG
|
||||
lw t0, 31* REGBYTES(sp)
|
||||
csrw mstatus, t0
|
||||
lw t0, 32 * REGBYTES(sp)
|
||||
csrw mepc, t0
|
||||
lw x1, 0*REGBYTES(sp) //ra
|
||||
|
||||
lw x5, 4*REGBYTES(sp)
|
||||
lw x6, 5*REGBYTES(sp)
|
||||
lw x7, 6*REGBYTES(sp)
|
||||
lw x8, 30*REGBYTES(sp)
|
||||
lw x9, 8*REGBYTES(sp)
|
||||
lw x10, 9*REGBYTES(sp)
|
||||
lw x11, 10*REGBYTES(sp)
|
||||
lw x12, 11*REGBYTES(sp)
|
||||
lw x13, 12*REGBYTES(sp)
|
||||
lw x14, 13*REGBYTES(sp)
|
||||
lw x15, 14*REGBYTES(sp)
|
||||
lw x16, 15*REGBYTES(sp)
|
||||
lw x17, 16*REGBYTES(sp)
|
||||
lw x18, 17*REGBYTES(sp)
|
||||
lw x19, 18*REGBYTES(sp)
|
||||
lw x20, 19*REGBYTES(sp)
|
||||
lw x21, 20*REGBYTES(sp)
|
||||
lw x22, 21*REGBYTES(sp)
|
||||
lw x23, 22*REGBYTES(sp)
|
||||
lw x24, 23*REGBYTES(sp)
|
||||
lw x25, 24*REGBYTES(sp)
|
||||
lw x26, 25*REGBYTES(sp)
|
||||
lw x27, 26*REGBYTES(sp)
|
||||
lw x28, 27*REGBYTES(sp)
|
||||
lw x29, 28*REGBYTES(sp)
|
||||
lw x30, 29*REGBYTES(sp)
|
||||
lw x31, 7*REGBYTES(sp)
|
||||
addi sp, sp, 33*REGBYTES
|
||||
.endm
|
||||
|
||||
# .section .interrupt.text
|
||||
.extern trap_entry
|
||||
.global trap_entry_
|
||||
.align 4
|
||||
trap_entry_:
|
||||
csrw mscratch, sp
|
||||
la sp, _exc_sp
|
||||
call trap_entry
|
||||
csrr sp, mscratch
|
||||
POP_ALL_REG
|
||||
mret
|
||||
|
||||
|
||||
# .section .interrupt.text
|
||||
.extern trap_entry
|
||||
.extern interrupt_entry
|
||||
.global trap_handler
|
||||
.equ TRAP_INTERRUPT_MODE_MASK, 0x80000000
|
||||
.align 4
|
||||
trap_handler:
|
||||
PUSH_ALL_REG
|
||||
csrr a0, mcause
|
||||
li a1, TRAP_INTERRUPT_MODE_MASK
|
||||
li a2, 0x000000ff
|
||||
and a1, a0, a1
|
||||
and a0, a2, a0
|
||||
beqz a1, trap_entry_
|
||||
csrw mscratch, sp
|
||||
la sp, _irq_sp
|
||||
call interrupt_entry
|
||||
csrr sp, mscratch
|
||||
|
||||
POP_ALL_REG
|
||||
mret
|
Reference in New Issue
Block a user