成功使用print外设打印出hello world
This commit is contained in:
65
cpu/print.c
Normal file
65
cpu/print.c
Normal file
@@ -0,0 +1,65 @@
|
||||
|
||||
|
||||
#include "riscv.h"
|
||||
#include "stdio.h"
|
||||
|
||||
|
||||
#define PRINT_BASE_ADDR 0x40000000
|
||||
#define PRINT_SIZE 0x4
|
||||
|
||||
#define dev_wr(addr) g_map[(addr-PRINT_BASE_ADDR) >> 2]
|
||||
#define dev_wrb(addr) ((uint8_t *)g_map)[(addr-PRINT_BASE_ADDR)]
|
||||
#define dev_wrh(addr) ((uint16_t *)g_map)[(addr-PRINT_BASE_ADDR) >> 1]
|
||||
|
||||
|
||||
|
||||
static uint32_t g_map[1];
|
||||
|
||||
static uint32_t read(uint32_t addr) {
|
||||
if (!(addr & 0x3)) {
|
||||
return dev_wr(addr);
|
||||
} else if (!(addr & 0x1)) {
|
||||
return dev_wrh(addr);
|
||||
} else {
|
||||
return dev_wrb(addr);
|
||||
}
|
||||
}
|
||||
|
||||
#define BUFF_LEN 1024
|
||||
static char g_buff[BUFF_LEN];
|
||||
static int g_index;
|
||||
|
||||
static void write(uint32_t addr, uint32_t data) {
|
||||
// printf("print: write data=%x\n", data);
|
||||
if (!(addr & 0x3)) {
|
||||
dev_wr(addr) = data;
|
||||
} else if (!(addr & 0x1)) {
|
||||
dev_wrh(addr) = data;
|
||||
} else {
|
||||
dev_wrb(addr) = data;
|
||||
}
|
||||
if (g_index < BUFF_LEN) {
|
||||
g_buff[g_index++] = data;
|
||||
}
|
||||
if (data == '\n') {
|
||||
g_buff[g_index] = 0;
|
||||
printf("%s", g_buff);
|
||||
g_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const static device_t g_print = {
|
||||
.addr = PRINT_BASE_ADDR,
|
||||
.size = PRINT_SIZE,
|
||||
.read = read,
|
||||
.write = write,
|
||||
};
|
||||
|
||||
|
||||
const device_t* print_dev() {
|
||||
return &g_print;
|
||||
}
|
||||
|
10
cpu/print.h
Normal file
10
cpu/print.h
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
#ifndef print_h__
|
||||
#define print_h__
|
||||
|
||||
#include "riscv.h"
|
||||
|
||||
|
||||
const device_t* print_dev();
|
||||
|
||||
#endif
|
392
cpu/riscv.c
392
cpu/riscv.c
@@ -1,145 +1,130 @@
|
||||
|
||||
#include "riscv.h"
|
||||
#include "debug.h"
|
||||
#include "print.h"
|
||||
|
||||
|
||||
#define device_write(riscv,addr,value) \
|
||||
for (int i = 0;i < riscv->device_num;i++) {\
|
||||
if (riscv->device_list[i] && riscv->device_list[i]->write) {\
|
||||
if(addr>=riscv->device_list[i]->addr && addr<riscv->device_list[i]->addr+riscv->device_list[i]->size) {\
|
||||
riscv->device_list[i]->write(addr, value);\
|
||||
return;\
|
||||
}\
|
||||
}\
|
||||
}
|
||||
|
||||
#define device_read(riscv,addr,ret) \
|
||||
for (int i = 0;i < riscv->device_num;i++) {\
|
||||
if (riscv->device_list[i] && riscv->device_list[i]->read) {\
|
||||
if(addr>=riscv->device_list[i]->addr && addr<riscv->device_list[i]->addr+riscv->device_list[i]->size) {\
|
||||
ret=riscv->device_list[i]->read(addr);\
|
||||
return ret;\
|
||||
}\
|
||||
}\
|
||||
}
|
||||
|
||||
int riscv_print(riscv_t* riscv) {
|
||||
printf("x0(zero): %08x\n", riscv->zero);
|
||||
printf("x1(ra): %08x\n", riscv->ra);
|
||||
printf("x2(sp): %08x\n", riscv->sp);
|
||||
printf("x3(gp): %08x\n", riscv->gp);
|
||||
printf("x4(tp): %08x\n", riscv->tp);
|
||||
printf("x5(t0): %08x\n", riscv->t0);
|
||||
printf("x6(t1): %08x\n", riscv->t1);
|
||||
printf("x7(t2): %08x\n", riscv->t2);
|
||||
printf("x8(s0|fp): %08x\n", riscv->fp);
|
||||
printf("x9(s1): %08x\n", riscv->s1);
|
||||
printf("x10(a0): %08x\n", riscv->a0);
|
||||
printf("x11(a1): %08x\n", riscv->a1);
|
||||
printf("x12(a2): %08x\n", riscv->a2);
|
||||
printf("x13(a3): %08x\n", riscv->a3);
|
||||
printf("x14(a4): %08x\n", riscv->a4);
|
||||
printf("x15(a5): %08x\n", riscv->a5);
|
||||
printf("x16(a6): %08x\n", riscv->a6);
|
||||
printf("x17(a7): %08x\n", riscv->a7);
|
||||
printf("x18(s2): %08x\n", riscv->s2);
|
||||
printf("x19(s3): %08x\n", riscv->s3);
|
||||
printf("x20(s4): %08x\n", riscv->s4);
|
||||
printf("x21(s5): %08x\n", riscv->s5);
|
||||
printf("x22(s6): %08x\n", riscv->s6);
|
||||
printf("x23(s7): %08x\n", riscv->s7);
|
||||
printf("x24(s8): %08x\n", riscv->s8);
|
||||
printf("x25(s9): %08x\n", riscv->s9);
|
||||
printf("x26(s10): %08x\n", riscv->s10);
|
||||
printf("x27(s11): %08x\n", riscv->s11);
|
||||
printf("x28(t3): %08x\n", riscv->t3);
|
||||
printf("x29(t4): %08x\n", riscv->t4);
|
||||
printf("x30(t5): %08x\n", riscv->t5);
|
||||
printf("x31(t6): %08x\n", riscv->t6);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
每个指令长度为32bit,分为6个类型
|
||||
|--------------+------------+-----------+-------------+--------------+---------------|
|
||||
| [31-25] | [24-20] | [19-15] | [14-12] | [11-7] | [6-0] |
|
||||
|--------------+------------+-----------+-------------+--------------+---------------|
|
||||
| funct7 | rs2 | rs1 | funct3 | rd | opcode | R-type 计算指令
|
||||
|--------------+------------+-----------+-------------+--------------+---------------|
|
||||
| imm[11:0] | rs1 | funct3 | rd | opcode | I-type 加载指令
|
||||
|--------------+------------+-----------+-------------+--------------+---------------|
|
||||
| imm[11:5] | rs2 | rs1 | funct3 | imm[4:0] | opcode | S-type 存储指令
|
||||
|--------------+------------+-----------+-------------+--------------+---------------|
|
||||
|imm[12] [10:5]| rs2 | rs1 | funct3 | imm[4:1][11] | opcode | B-type 分支指令
|
||||
|--------------+------------+-----------+-------------+--------------+---------------|
|
||||
| imm[31:12] | rd | opcode | U-type 立即数指令
|
||||
|-----------------------------------------------------+--------------+---------------|
|
||||
| imm[20] [10:1] [11] [19:12] | rd | opcode | J-type 跳转指令
|
||||
|-----------------------------------------------------+--------------+---------------|
|
||||
|
||||
*/
|
||||
|
||||
// 定义opcode
|
||||
#define opcode_lui 0x37 // U-type
|
||||
#define opcode_auipc 0x17 // U-type
|
||||
#define opcode_jal 0x6f // J-type
|
||||
#define opcode_jalr 0x67 // I-type
|
||||
|
||||
// B-type
|
||||
#define opcode_beq 0x63
|
||||
#define opcode_bne 0x63
|
||||
#define opcode_blt 0x63
|
||||
#define opcode_bge 0x63
|
||||
#define opcode_bltu 0x63
|
||||
#define opcode_bgeu 0x63
|
||||
|
||||
// I-type
|
||||
#define opcode_lb 0x03
|
||||
#define opcode_lh 0x03
|
||||
#define opcode_lw 0x03
|
||||
#define opcode_lbu 0x03
|
||||
#define opcode_lhu 0x03
|
||||
|
||||
// S-type
|
||||
#define opcode_sb 0x23
|
||||
#define opcode_sh 0x23
|
||||
#define opcode_sw 0x23
|
||||
|
||||
// I-type
|
||||
#define opcode_addi 0x13
|
||||
#define opcode_slti 0x13
|
||||
#define opcode_sltiu 0x13
|
||||
#define opcode_xori 0x13
|
||||
#define opcode_ori 0x13
|
||||
#define opcode_andi 0x13
|
||||
#define opcode_slli 0x13
|
||||
#define opcode_srli 0x13
|
||||
#define opcode_srai 0x13
|
||||
|
||||
// R-type
|
||||
#define opcode_add 0x33
|
||||
#define opcode_sub 0x33
|
||||
#define opcode_sll 0x33
|
||||
#define opcode_slt 0x33
|
||||
#define opcode_sltu 0x33
|
||||
#define opcode_xor 0x33
|
||||
#define opcode_srl 0x33
|
||||
#define opcode_sra 0x33
|
||||
#define opcode_or 0x33
|
||||
#define opcode_and 0x33
|
||||
|
||||
#define opcode_fence 0x0f
|
||||
#define opcode_fence_i 0x0f
|
||||
|
||||
// 系统调用
|
||||
#define opcode_ecall 0x73
|
||||
#define opcode_ebreak 0x73
|
||||
#define opcode_csrrw 0x73
|
||||
#define opcode_csrrs 0x73
|
||||
#define opcode_csrrc 0x73
|
||||
#define opcode_csrrwi 0x73
|
||||
#define opcode_csrrsi 0x73
|
||||
#define opcode_csrrci 0x73
|
||||
void mem_w_write(riscv_t * riscv, uint32_t addr, uint32_t value) {
|
||||
if (addr >= MEM_ADDR_BASE && addr < MEM_ADDR_BASE + MEM_SIZE) {
|
||||
mem_wr(addr) = value;
|
||||
} else {
|
||||
device_write(riscv, addr, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define MEM_SIZE 1024*1024
|
||||
#define MEM_ADDR_BASE 0x10000000
|
||||
void mem_wh_write(riscv_t* riscv, uint32_t addr, uint16_t value) {
|
||||
if (addr >= MEM_ADDR_BASE && addr < MEM_ADDR_BASE + MEM_SIZE) {
|
||||
mem_wrh(addr) = value;
|
||||
} else {
|
||||
device_write(riscv, addr, value);
|
||||
}
|
||||
}
|
||||
|
||||
#define zero reg[0]
|
||||
#define ra reg[1]
|
||||
#define sp reg[2]
|
||||
#define gp reg[3]
|
||||
#define tp reg[4]
|
||||
#define t0 reg[5]
|
||||
#define t1 reg[6]
|
||||
#define t2 reg[7]
|
||||
#define s0 reg[8]
|
||||
#define s1 reg[9]
|
||||
#define a0 reg[10]
|
||||
#define a1 reg[11]
|
||||
#define a2 reg[12]
|
||||
#define a3 reg[13]
|
||||
#define a4 reg[14]
|
||||
#define a5 reg[15]
|
||||
#define a6 reg[16]
|
||||
#define a7 reg[17]
|
||||
#define s2 reg[18]
|
||||
#define s3 reg[19]
|
||||
#define s4 reg[20]
|
||||
#define s5 reg[21]
|
||||
#define s6 reg[22]
|
||||
#define s7 reg[23]
|
||||
#define s8 reg[24]
|
||||
#define s9 reg[25]
|
||||
#define s10 reg[26]
|
||||
#define s11 reg[27]
|
||||
#define t3 reg[28]
|
||||
#define t4 reg[29]
|
||||
#define t5 reg[30]
|
||||
#define t6 reg[31]
|
||||
void mem_wb_write(riscv_t* riscv, uint32_t addr, uint8_t value) {
|
||||
if (addr >= MEM_ADDR_BASE && addr < MEM_ADDR_BASE + MEM_SIZE) {
|
||||
mem_wrb(addr) = value;
|
||||
} else {
|
||||
device_write(riscv, addr, value);
|
||||
}
|
||||
}
|
||||
|
||||
#define fp reg[8]
|
||||
uint32_t mem_w_read(riscv_t* riscv, uint32_t addr) {
|
||||
uint32_t ret = 0xaaaaaaaa;
|
||||
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);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
uint16_t mem_wh_read(riscv_t* riscv, uint32_t addr) {
|
||||
uint16_t ret = 0xaaaa;
|
||||
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);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t mem_wb_read(riscv_t* riscv, uint32_t addr) {
|
||||
uint8_t ret = 0xaa;
|
||||
// printf("read addr=%08x\n", addr);
|
||||
if (addr >= MEM_ADDR_BASE && addr < MEM_ADDR_BASE + MEM_SIZE) {
|
||||
ret = mem_wrb(addr);
|
||||
} else if (addr>=riscv->rom_addr_base && addr<riscv->rom_addr_base+riscv->rom_size){
|
||||
ret = rom_wrb(addr);
|
||||
} else {
|
||||
device_read(riscv, addr, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint32_t mem[MEM_SIZE];
|
||||
uint32_t* rom;
|
||||
uint32_t rom_size;
|
||||
uint32_t rom_addr_base;
|
||||
uint32_t pc;
|
||||
uint32_t reg[32];
|
||||
uint32_t csrs[4096];
|
||||
}riscv_t;
|
||||
|
||||
#define mem_wr(addr) riscv->mem[(addr-MEM_ADDR_BASE) >> 2]
|
||||
#define mem_wrb(addr) ((uint8_t *)riscv->mem)[(addr-MEM_ADDR_BASE)]
|
||||
#define mem_wrh(addr) ((uint16_t *)riscv->mem)[(addr-MEM_ADDR_BASE) >> 1]
|
||||
void ins_add(riscv_t* riscv, int rs2, int rs1, int rd) {
|
||||
riscv->reg[rd] = riscv->reg[rs1] + riscv->reg[rs2];
|
||||
}
|
||||
@@ -200,6 +185,7 @@ void ins_bltu(riscv_t* riscv, int rs2, int rs1, int imm) {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -264,38 +250,38 @@ void ins_jalr(riscv_t* riscv, int rs1, int imm, int rd) {
|
||||
|
||||
void ins_lb(riscv_t* riscv, int rs1, int imm, int rd) {
|
||||
uint32_t addr = riscv->reg[rs1] + imm;
|
||||
printf("lb %08x,imm=%d\n",addr,imm);
|
||||
riscv->reg[rd] = (int)mem_wrb(addr);
|
||||
// printf("lb %08x,imm=%d\n",addr,imm);
|
||||
riscv->reg[rd] = (int)mem_wb_read(riscv, addr);
|
||||
}
|
||||
|
||||
void ins_lbu(riscv_t* riscv, int rs1, int imm, int rd) {
|
||||
uint32_t addr = riscv->reg[rs1] + imm;
|
||||
printf("lbu %08x,imm=%d\n",addr,imm);
|
||||
riscv->reg[rd] = mem_wrb(addr);
|
||||
// printf("lbu %08x,imm=%d\n",addr,imm);
|
||||
riscv->reg[rd] = mem_wb_read(riscv, addr);
|
||||
}
|
||||
|
||||
void ins_lh(riscv_t* riscv, int rs1, int imm, int rd) {
|
||||
uint32_t addr = riscv->reg[rs1] + imm;
|
||||
printf("lh %08x,imm=%d\n",addr,imm);
|
||||
riscv->reg[rd] = (int)mem_wrh(addr);
|
||||
// printf("lh %08x,imm=%d\n",addr,imm);
|
||||
riscv->reg[rd] = (int)mem_wh_read(riscv, addr);
|
||||
}
|
||||
|
||||
void ins_lhu(riscv_t* riscv, int rs1, int imm, int rd) {
|
||||
uint32_t addr = riscv->reg[rs1] + imm;
|
||||
printf("lhu %08x,imm=%d\n",addr,imm);
|
||||
riscv->reg[rd] = mem_wrh(addr);
|
||||
// printf("lhu %08x,imm=%d\n",addr,imm);
|
||||
riscv->reg[rd] = mem_wh_read(riscv, addr);
|
||||
}
|
||||
|
||||
void ins_lw(riscv_t* riscv, int rs1, int imm, int rd) {
|
||||
uint32_t addr = riscv->reg[rs1] + imm;
|
||||
printf("lw %08x,imm=%d\n",addr,imm);
|
||||
riscv->reg[rd] = mem_wr(addr);
|
||||
// printf("lw %08x,imm=%d\n",addr,imm);
|
||||
riscv->reg[rd] = (int)mem_w_read(riscv, addr);
|
||||
}
|
||||
|
||||
void ins_lwu(riscv_t* riscv, int rs1, int imm, int rd) {
|
||||
uint32_t addr = riscv->reg[rs1] + imm;
|
||||
printf("lwu %08x,imm=%d\n",addr,imm);
|
||||
riscv->reg[rd] = mem_wr(addr);
|
||||
// printf("lwu %08x,imm=%d\n",addr,imm);
|
||||
riscv->reg[rd] = mem_w_read(riscv, addr);
|
||||
}
|
||||
|
||||
void ins_lui(riscv_t* riscv, int imm, int rd) {
|
||||
@@ -317,20 +303,20 @@ void ins_ori(riscv_t* riscv, int rs1, int imm, int rd) {
|
||||
|
||||
void ins_sb(riscv_t* riscv, int rs2, int rs1, int imm) {
|
||||
uint32_t addr = riscv->reg[rs1] + imm;
|
||||
printf("sb %08x,imm=%d\n",addr,imm);
|
||||
mem_wrb(addr) = riscv->reg[rs2];
|
||||
// printf("sb %08x,imm=%d\n",addr,imm);
|
||||
mem_wb_write(riscv, addr, riscv->reg[rs2]);
|
||||
}
|
||||
|
||||
void ins_sh(riscv_t* riscv, int rs2, int rs1, int imm) {
|
||||
uint32_t addr = riscv->reg[rs1] + imm;
|
||||
printf("sh %08x,imm=%d\n",addr,imm);
|
||||
mem_wrh(addr) = riscv->reg[rs2];
|
||||
// printf("sh %08x,imm=%d\n",addr,imm);
|
||||
mem_wh_write(riscv, addr, riscv->reg[rs2]);
|
||||
}
|
||||
|
||||
void ins_sw(riscv_t* riscv, int rs2, int rs1, int imm) {
|
||||
uint32_t addr = riscv->reg[rs1] + imm;
|
||||
printf("sw %08x,imm=%d\n",addr,imm);
|
||||
mem_wr(addr) = riscv->reg[rs2];
|
||||
// printf("sw %08x,imm=%d\n",addr,imm);
|
||||
mem_w_write(riscv, addr, riscv->reg[rs2]);
|
||||
}
|
||||
|
||||
void ins_sll(riscv_t* riscv, int rs2, int rs1, int rd) {
|
||||
@@ -417,54 +403,6 @@ void ins_xori(riscv_t* riscv, int rs1, int imm, int rd) {
|
||||
riscv->reg[rd] = riscv->reg[rs1] ^ imm;
|
||||
}
|
||||
|
||||
// 不需要做符号扩展
|
||||
#define imm_u_type(_ins,_imm) {\
|
||||
_imm = (_ins >> 12) << 12;\
|
||||
}
|
||||
|
||||
// 20位符号扩展
|
||||
#define imm_j_type(_ins,_imm) {\
|
||||
_imm = ((_ins >> 21) & 0x3ff) << 1;\
|
||||
_imm |= ((_ins >> 20) & 1) << 11;\
|
||||
_imm |= ((_ins >> 12) & 0xff) << 12;\
|
||||
_imm |= ((_ins >> 31) & 1) << 20;\
|
||||
if(_imm&(1<<20)){\
|
||||
_imm|=0xfff00000;\
|
||||
}\
|
||||
}
|
||||
|
||||
// 12位符号扩展
|
||||
#define imm_i_type(_ins,_imm) {\
|
||||
_imm = (_ins >> 20) & 0xfff;\
|
||||
if(_imm&(1<<11)){\
|
||||
_imm|=0xfffff000;\
|
||||
}\
|
||||
}
|
||||
|
||||
// 13位符号扩展
|
||||
#define imm_b_type(_ins,_imm) {\
|
||||
_imm = ((_ins >> 31) & 1) << 12;\
|
||||
_imm |= ((_ins >> 7) & 0x1) << 11;\
|
||||
_imm |= ((_ins >> 8) & 0xf) << 1;\
|
||||
_imm |= ((_ins >> 25) & 0x1f) << 5;\
|
||||
if(_imm&(1<<12)){\
|
||||
_imm|=0xfffff000;\
|
||||
}\
|
||||
}
|
||||
|
||||
// 12位符号扩展
|
||||
#define imm_s_type(_ins,_imm) {\
|
||||
_imm = ((_ins >> 7) & 0x1f);\
|
||||
_imm |= (_ins >> 25) << 5;\
|
||||
if(_imm&(1<<11)){\
|
||||
_imm|=0xfffff000;\
|
||||
}\
|
||||
}
|
||||
|
||||
#define imm_csr(_ins,_imm) {\
|
||||
_imm = (_ins >> 20) & 0xfff;\
|
||||
}
|
||||
|
||||
// 解析指令
|
||||
int riscv_decode(riscv_t* riscv, uint32_t ins) {
|
||||
int imm = 0;
|
||||
@@ -671,47 +609,27 @@ int riscv_decode(riscv_t* riscv, uint32_t ins) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 注册外设
|
||||
int riscv_register_device(riscv_t* riscv, const device_t* device) {
|
||||
if (riscv->device_num >= DEVICE_MAX_NUM) {
|
||||
printf("riscv register device failed, device num out of range\n");
|
||||
return -1;
|
||||
}
|
||||
// printf("device: base_addr=%08x, size=%08x\n", device->addr, device->size);
|
||||
riscv->device_list[riscv->device_num] = device;
|
||||
riscv->device_num++;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
int riscv_print(riscv_t* riscv) {
|
||||
printf("x0(zero): %08x\n", riscv->zero);
|
||||
printf("x1(ra): %08x\n", riscv->ra);
|
||||
printf("x2(sp): %08x\n", riscv->sp);
|
||||
printf("x3(gp): %08x\n", riscv->gp);
|
||||
printf("x4(tp): %08x\n", riscv->tp);
|
||||
printf("x5(t0): %08x\n", riscv->t0);
|
||||
printf("x6(t1): %08x\n", riscv->t1);
|
||||
printf("x7(t2): %08x\n", riscv->t2);
|
||||
printf("x8(fp): %08x\n", riscv->fp);
|
||||
printf("x9(s0): %08x\n", riscv->s0);
|
||||
printf("x10(s1): %08x\n", riscv->s1);
|
||||
printf("x11(a0): %08x\n", riscv->a0);
|
||||
printf("x12(a1): %08x\n", riscv->a1);
|
||||
printf("x13(a2): %08x\n", riscv->a2);
|
||||
printf("x14(a3): %08x\n", riscv->a3);
|
||||
printf("x15(a4): %08x\n", riscv->a4);
|
||||
printf("x16(a5): %08x\n", riscv->a5);
|
||||
printf("x17(a6): %08x\n", riscv->a6);
|
||||
printf("x18(s2): %08x\n", riscv->s2);
|
||||
printf("x19(s3): %08x\n", riscv->s3);
|
||||
printf("x20(s4): %08x\n", riscv->s4);
|
||||
printf("x21(s5): %08x\n", riscv->s5);
|
||||
printf("x22(s6): %08x\n", riscv->s6);
|
||||
printf("x23(s7): %08x\n", riscv->s7);
|
||||
printf("x24(s8): %08x\n", riscv->s8);
|
||||
printf("x25(s9): %08x\n", riscv->s9);
|
||||
printf("x26(s10): %08x\n", riscv->s10);
|
||||
printf("x27(s11): %08x\n", riscv->s11);
|
||||
printf("x28(t3): %08x\n", riscv->t3);
|
||||
printf("x29(t4): %08x\n", riscv->t4);
|
||||
printf("x30(t5): %08x\n", riscv->t5);
|
||||
printf("x31(t6): %08x\n", riscv->t6);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int riscv_run(riscv_t* riscv) {
|
||||
@@ -719,11 +637,11 @@ int riscv_run(riscv_t* riscv) {
|
||||
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\n");
|
||||
printf("riscv run out of rom pc=%08x\n",riscv->pc);
|
||||
break;
|
||||
}
|
||||
uint32_t instr = riscv->rom[(riscv->pc-riscv->rom_addr_base) >> 2];
|
||||
printf("pc: %08x instr: %08x\n", riscv->pc, instr);
|
||||
// printf("pc: %08x instr: %08x\n", riscv->pc, instr);
|
||||
pc = riscv->pc;
|
||||
ret = riscv_decode(riscv, instr);
|
||||
riscv->zero = 0;
|
||||
@@ -731,12 +649,13 @@ int riscv_run(riscv_t* riscv) {
|
||||
if (riscv->pc == pc) {
|
||||
riscv->pc += 4;
|
||||
}
|
||||
riscv_print(riscv);
|
||||
// riscv_print(riscv);
|
||||
if(ret){
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("riscv run end\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include "stdio.h"
|
||||
@@ -767,7 +686,11 @@ long get_file_size(FILE *stream)
|
||||
return file_size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
riscv_t riscv = { 0 };
|
||||
|
||||
|
||||
int thread_fun(void* t)
|
||||
{
|
||||
printf("riscv start\n");
|
||||
@@ -783,6 +706,7 @@ int thread_fun(void* t)
|
||||
fread(riscv.rom, 1, riscv.rom_size, file);
|
||||
fclose(file);
|
||||
|
||||
riscv_register_device(&riscv, print_dev());
|
||||
riscv_init(&riscv, riscv.rom, 0x80000000, riscv.rom_size);
|
||||
riscv_run(&riscv);
|
||||
|
||||
|
204
cpu/riscv.h
204
cpu/riscv.h
@@ -6,4 +6,208 @@
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
每个指令长度为32bit,分为6个类型
|
||||
|--------------+------------+-----------+-------------+--------------+---------------|
|
||||
| [31-25] | [24-20] | [19-15] | [14-12] | [11-7] | [6-0] |
|
||||
|--------------+------------+-----------+-------------+--------------+---------------|
|
||||
| funct7 | rs2 | rs1 | funct3 | rd | opcode | R-type 计算指令
|
||||
|--------------+------------+-----------+-------------+--------------+---------------|
|
||||
| imm[11:0] | rs1 | funct3 | rd | opcode | I-type 加载指令
|
||||
|--------------+------------+-----------+-------------+--------------+---------------|
|
||||
| imm[11:5] | rs2 | rs1 | funct3 | imm[4:0] | opcode | S-type 存储指令
|
||||
|--------------+------------+-----------+-------------+--------------+---------------|
|
||||
|imm[12] [10:5]| rs2 | rs1 | funct3 | imm[4:1][11] | opcode | B-type 分支指令
|
||||
|--------------+------------+-----------+-------------+--------------+---------------|
|
||||
| imm[31:12] | rd | opcode | U-type 立即数指令
|
||||
|-----------------------------------------------------+--------------+---------------|
|
||||
| imm[20] [10:1] [11] [19:12] | rd | opcode | J-type 跳转指令
|
||||
|-----------------------------------------------------+--------------+---------------|
|
||||
|
||||
*/
|
||||
|
||||
// 定义opcode
|
||||
#define opcode_lui 0x37 // U-type
|
||||
#define opcode_auipc 0x17 // U-type
|
||||
#define opcode_jal 0x6f // J-type
|
||||
#define opcode_jalr 0x67 // I-type
|
||||
|
||||
// B-type
|
||||
#define opcode_beq 0x63
|
||||
#define opcode_bne 0x63
|
||||
#define opcode_blt 0x63
|
||||
#define opcode_bge 0x63
|
||||
#define opcode_bltu 0x63
|
||||
#define opcode_bgeu 0x63
|
||||
|
||||
// I-type
|
||||
#define opcode_lb 0x03
|
||||
#define opcode_lh 0x03
|
||||
#define opcode_lw 0x03
|
||||
#define opcode_lbu 0x03
|
||||
#define opcode_lhu 0x03
|
||||
|
||||
// S-type
|
||||
#define opcode_sb 0x23
|
||||
#define opcode_sh 0x23
|
||||
#define opcode_sw 0x23
|
||||
|
||||
// I-type
|
||||
#define opcode_addi 0x13
|
||||
#define opcode_slti 0x13
|
||||
#define opcode_sltiu 0x13
|
||||
#define opcode_xori 0x13
|
||||
#define opcode_ori 0x13
|
||||
#define opcode_andi 0x13
|
||||
#define opcode_slli 0x13
|
||||
#define opcode_srli 0x13
|
||||
#define opcode_srai 0x13
|
||||
|
||||
// R-type
|
||||
#define opcode_add 0x33
|
||||
#define opcode_sub 0x33
|
||||
#define opcode_sll 0x33
|
||||
#define opcode_slt 0x33
|
||||
#define opcode_sltu 0x33
|
||||
#define opcode_xor 0x33
|
||||
#define opcode_srl 0x33
|
||||
#define opcode_sra 0x33
|
||||
#define opcode_or 0x33
|
||||
#define opcode_and 0x33
|
||||
|
||||
#define opcode_fence 0x0f
|
||||
#define opcode_fence_i 0x0f
|
||||
|
||||
// 系统调用
|
||||
#define opcode_ecall 0x73
|
||||
#define opcode_ebreak 0x73
|
||||
#define opcode_csrrw 0x73
|
||||
#define opcode_csrrs 0x73
|
||||
#define opcode_csrrc 0x73
|
||||
#define opcode_csrrwi 0x73
|
||||
#define opcode_csrrsi 0x73
|
||||
#define opcode_csrrci 0x73
|
||||
|
||||
|
||||
#define MEM_SIZE 1024*1024
|
||||
#define MEM_ADDR_BASE 0x10000000
|
||||
|
||||
#define zero reg[0]
|
||||
#define ra reg[1]
|
||||
#define sp reg[2]
|
||||
#define gp reg[3]
|
||||
#define tp reg[4]
|
||||
#define t0 reg[5]
|
||||
#define t1 reg[6]
|
||||
#define t2 reg[7]
|
||||
#define s0 reg[8]
|
||||
#define s1 reg[9]
|
||||
#define a0 reg[10]
|
||||
#define a1 reg[11]
|
||||
#define a2 reg[12]
|
||||
#define a3 reg[13]
|
||||
#define a4 reg[14]
|
||||
#define a5 reg[15]
|
||||
#define a6 reg[16]
|
||||
#define a7 reg[17]
|
||||
#define s2 reg[18]
|
||||
#define s3 reg[19]
|
||||
#define s4 reg[20]
|
||||
#define s5 reg[21]
|
||||
#define s6 reg[22]
|
||||
#define s7 reg[23]
|
||||
#define s8 reg[24]
|
||||
#define s9 reg[25]
|
||||
#define s10 reg[26]
|
||||
#define s11 reg[27]
|
||||
#define t3 reg[28]
|
||||
#define t4 reg[29]
|
||||
#define t5 reg[30]
|
||||
#define t6 reg[31]
|
||||
|
||||
#define fp reg[8]
|
||||
|
||||
|
||||
|
||||
// 不需要做符号扩展
|
||||
#define imm_u_type(_ins,_imm) {\
|
||||
_imm = (_ins >> 12) << 12;\
|
||||
}
|
||||
|
||||
// 20位符号扩展
|
||||
#define imm_j_type(_ins,_imm) {\
|
||||
_imm = ((_ins >> 21) & 0x3ff) << 1;\
|
||||
_imm |= ((_ins >> 20) & 1) << 11;\
|
||||
_imm |= ((_ins >> 12) & 0xff) << 12;\
|
||||
_imm |= ((_ins >> 31) & 1) << 20;\
|
||||
if(_imm&(1<<20)){\
|
||||
_imm|=0xfff00000;\
|
||||
}\
|
||||
}
|
||||
|
||||
// 12位符号扩展
|
||||
#define imm_i_type(_ins,_imm) {\
|
||||
_imm = (_ins >> 20) & 0xfff;\
|
||||
if(_imm&(1<<11)){\
|
||||
_imm|=0xfffff000;\
|
||||
}\
|
||||
}
|
||||
|
||||
// 13位符号扩展
|
||||
#define imm_b_type(_ins,_imm) {\
|
||||
_imm = ((_ins >> 31) & 1) << 12;\
|
||||
_imm |= ((_ins >> 7) & 0x1) << 11;\
|
||||
_imm |= ((_ins >> 8) & 0xf) << 1;\
|
||||
_imm |= ((_ins >> 25) & 0x3f) << 5;\
|
||||
if(_imm&(1<<12)){\
|
||||
_imm|=0xfffff000;\
|
||||
}\
|
||||
}
|
||||
|
||||
// 12位符号扩展
|
||||
#define imm_s_type(_ins,_imm) {\
|
||||
_imm = ((_ins >> 7) & 0x1f);\
|
||||
_imm |= (_ins >> 25) << 5;\
|
||||
if(_imm&(1<<11)){\
|
||||
_imm|=0xfffff000;\
|
||||
}\
|
||||
}
|
||||
|
||||
#define imm_csr(_ins,_imm) {\
|
||||
_imm = (_ins >> 20) & 0xfff;\
|
||||
}
|
||||
|
||||
|
||||
#define DEVICE_MAX_NUM 16
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t addr;
|
||||
uint32_t size;
|
||||
uint32_t (*read)(uint32_t addr);
|
||||
void (*write)(uint32_t addr,uint32_t data);
|
||||
}device_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t mem[MEM_SIZE];
|
||||
const device_t* device_list[DEVICE_MAX_NUM];
|
||||
uint32_t device_num;
|
||||
uint32_t* rom;
|
||||
uint32_t rom_size;
|
||||
uint32_t rom_addr_base;
|
||||
uint32_t pc;
|
||||
uint32_t reg[32];
|
||||
uint32_t csrs[4096];
|
||||
}riscv_t;
|
||||
|
||||
#define mem_wr(addr) riscv->mem[(addr-MEM_ADDR_BASE) >> 2]
|
||||
#define mem_wrb(addr) ((uint8_t *)riscv->mem)[(addr-MEM_ADDR_BASE)]
|
||||
#define mem_wrh(addr) ((uint16_t *)riscv->mem)[(addr-MEM_ADDR_BASE) >> 1]
|
||||
|
||||
#define rom_wr(addr) riscv->rom[(addr-riscv->rom_addr_base) >> 2]
|
||||
#define rom_wrb(addr) ((uint8_t *)(riscv->rom))[(addr-riscv->rom_addr_base)]
|
||||
#define rom_wrh(addr) ((uint16_t *)(riscv->rom))[(addr-riscv->rom_addr_base) >> 1]
|
||||
|
||||
|
||||
#endif
|
32
riscv/main.c
32
riscv/main.c
@@ -1,3 +1,26 @@
|
||||
#include "stdint.h"
|
||||
|
||||
|
||||
#define PRINT_BASE_ADDR *(uint8_t *)0x40000000
|
||||
|
||||
int my_putc(int c) {
|
||||
PRINT_BASE_ADDR = c;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
int my_puts(char *s) {
|
||||
while (*s) {
|
||||
my_putc(*s);
|
||||
s++;
|
||||
}
|
||||
// for (int i = 0;i < 10;i++) {
|
||||
// my_putc(*s);
|
||||
// s++;
|
||||
// }
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int add(int a, int b) {
|
||||
@@ -6,8 +29,9 @@ int add(int a, int b) {
|
||||
|
||||
int main()
|
||||
{
|
||||
int a=1;
|
||||
int b=2;
|
||||
int c = add(a, b);
|
||||
return c;
|
||||
// int a=1;
|
||||
// int b=2;
|
||||
// int c = add(a, b);
|
||||
my_puts("Hello World!\n");
|
||||
return 0;
|
||||
}
|
@@ -7,4 +7,31 @@
|
||||
_start:
|
||||
|
||||
la sp, _sp
|
||||
|
||||
/* Load data section */
|
||||
la a0, _data_lma
|
||||
la a1, _data
|
||||
la a2, _edata
|
||||
bgeu a1, a2, 2f
|
||||
1:
|
||||
lw t0, (a0)
|
||||
sw t0, (a1)
|
||||
addi a0, a0, 4
|
||||
addi a1, a1, 4
|
||||
bltu a1, a2, 1b
|
||||
2:
|
||||
|
||||
/* Clear bss section */
|
||||
la a0, __bss_start
|
||||
la a1, _end
|
||||
bgeu a0, a1, 2f
|
||||
1:
|
||||
sw zero, (a0)
|
||||
addi a0, a0, 4
|
||||
bltu a0, a1, 1b
|
||||
2:
|
||||
|
||||
/* Call global constructors */
|
||||
# la a0, __libc_fini_array
|
||||
# call __libc_init_array
|
||||
j main
|
Reference in New Issue
Block a user