添加timer外设

1.解决while(1)执行异常的问题
This commit is contained in:
2025-06-12 17:27:48 +08:00
parent fe515858e5
commit ff151012be
5 changed files with 166 additions and 8 deletions

View File

@@ -1,12 +1,15 @@
#include "riscv.h"
#include "debug.h"
#include "print.h"
#include "stdio.h"
#include "stdlib.h"
#include "errno.h"
#include "string.h"
// cpu外设
#include "print.h"
#include "timer.h"
#include "../main.h"
#define device_write(riscv,addr,value) \
@@ -194,30 +197,35 @@ void ins_auipc(riscv_t* riscv, int imm, int rd) {
void ins_beq(riscv_t* riscv, int rs2, int rs1, int imm) {
if (riscv->reg[rs1] == riscv->reg[rs2]) {
riscv->pc += imm;
riscv->pc_modify = 1;
}
}
void ins_bge(riscv_t* riscv, int rs2, int rs1, int imm) {
if ((int)riscv->reg[rs1] >= (int)riscv->reg[rs2]) {
riscv->pc += imm;
riscv->pc_modify = 1;
}
}
void ins_bgeu(riscv_t* riscv, int rs2, int rs1, int imm) {
if (riscv->reg[rs1] >= riscv->reg[rs2]) {
riscv->pc += imm;
riscv->pc_modify = 1;
}
}
void ins_blt(riscv_t* riscv, int rs2, int rs1, int imm) {
if ((int)riscv->reg[rs1] < (int)riscv->reg[rs2]) {
riscv->pc += imm;
riscv->pc_modify = 1;
}
}
void ins_bltu(riscv_t* riscv, int rs2, int rs1, int imm) {
if (riscv->reg[rs1] < riscv->reg[rs2]) {
riscv->pc += imm;
riscv->pc_modify = 1;
}
}
@@ -225,6 +233,7 @@ void ins_bne(riscv_t* riscv, int rs2, int rs1, int imm) {
// printf("bne %d %d imm=%08x\n", rs2, rs1, imm);
if (riscv->reg[rs1] != riscv->reg[rs2]) {
riscv->pc += imm;
riscv->pc_modify = 1;
}
}
@@ -276,6 +285,7 @@ void ins_ebreak(riscv_t* riscv) {
void ins_jal(riscv_t* riscv, int imm, int rd) {
riscv->reg[rd] = riscv->pc + 4;
riscv->pc += imm;
riscv->pc_modify = 1;
}
void ins_jalr(riscv_t* riscv, int rs1, int imm, int rd) {
@@ -283,6 +293,7 @@ void ins_jalr(riscv_t* riscv, int rs1, int imm, int rd) {
t = riscv->pc + 4;
riscv->pc = (riscv->reg[rs1] + imm) & (~1);
riscv->reg[rd] = t;
riscv->pc_modify = 1;
}
void ins_lb(riscv_t* riscv, int rs1, int imm, int rd) {
@@ -335,6 +346,7 @@ void ins_lui(riscv_t* riscv, int imm, int rd) {
void ins_mret(riscv_t* riscv) {
riscv->pc = riscv->mepc;
riscv->pc_modify = 1;
if (riscv->mstatus & MSTATUS_MPIE) {
riscv->mstatus &= ~MSTATUS_MPIE;
riscv->mstatus |= MSTATUS_MIE;
@@ -692,12 +704,33 @@ int riscv_register_device(riscv_t* riscv, const device_t* device) {
return 0;
}
// 跑外设(执行外设逻辑,设置中断等)
int riscv_device_run(riscv_t* riscv) {
for (int i = 0;i < riscv->device_num;i++) {
if (riscv->device_list[i] && riscv->device_list[i]->run) {
riscv->device_list[i]->run(riscv, riscv->device_list[i]);
}
}
return 0;
}
// 外设初始化
int riscv_device_init(riscv_t* riscv) {
for (int i = 0;i < riscv->device_num;i++) {
if (riscv->device_list[i] && riscv->device_list[i]->init) {
riscv->device_list[i]->init(riscv->device_list[i]);
}
}
return 0;
}
int riscv_init(riscv_t* riscv, uint32_t* rom, uint32_t rom_addr_base, uint32_t rom_size) {
riscv->rom = rom;
riscv->rom_size = rom_size;
riscv->rom_addr_base = rom_addr_base;
riscv->pc = riscv->rom_addr_base;
riscv->pc_modify = 0;
riscv->ra = 0xffffffff;
return 0;
}
@@ -708,6 +741,7 @@ 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;
riscv->pc_modify = 1;
// 禁用全局中断
if (riscv->mstatus & MSTATUS_MIE) {
riscv->mstatus &= ~MSTATUS_MIE;
@@ -745,7 +779,6 @@ int riscv_irq_check(riscv_t* riscv) {
int riscv_run(riscv_t* riscv) {
int ret = 0;
uint32_t pc;
while (1) {
if (riscv->pc == 0xfffffffe && riscv->ra == 0xffffffff) {
break;
@@ -763,17 +796,20 @@ int riscv_run(riscv_t* riscv) {
}
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);
riscv->zero = 0;
// 如果指令修改了pc则以修改后的为准如果pc未被修改则继续执行下一条指令
if (riscv->pc == pc) {
if (!riscv->pc_modify) {
riscv->pc += 4;
} else {
// printf("pc modify=1\n");
riscv->pc_modify = 0;
}
if (riscv->exc_code > 0) {
riscv_enter_trap(riscv, 0, riscv->exc_code);
riscv->exc_code = 0;
}
riscv_device_run(riscv);
riscv_irq_check(riscv);
// riscv_print(riscv);
if(ret){
@@ -843,7 +879,9 @@ int thread_fun(void* t)
fclose(file);
riscv_register_device(&riscv, print_dev());
riscv_register_device(&riscv, timer_dev());
riscv_init(&riscv, riscv.rom, 0x80000000, riscv.rom_size);
riscv_device_init(&riscv);
riscv_run(&riscv);
return 0;