Added CSR_TIME support
This commit is contained in:
parent
256a56f70e
commit
326b52ef86
21
src/cpu/csr.c
Normal file
21
src/cpu/csr.c
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#include "csr.h"
|
||||||
|
#include "rv32cpu.h"
|
||||||
|
|
||||||
|
uint32_t csr_read(struct RV32_CPU* cpu, uint32_t csr)
|
||||||
|
{
|
||||||
|
switch(csr)
|
||||||
|
{
|
||||||
|
case CSR_TIME:
|
||||||
|
return cpu->sim_ticks_done;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cpu->csr[csr];
|
||||||
|
}
|
||||||
|
|
||||||
|
void csr_write(struct RV32_CPU* cpu, uint32_t csr, uint32_t value)
|
||||||
|
{
|
||||||
|
cpu->csr[csr] = value;
|
||||||
|
}
|
@ -1,9 +1,17 @@
|
|||||||
#ifndef CSR_H
|
#ifndef CSR_H
|
||||||
#define CSR_H
|
#define CSR_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
/* ZICSR : Control and Status Registers */
|
/* ZICSR : Control and Status Registers */
|
||||||
#define CSR_COUNT 0x2000
|
#define CSR_COUNT 0x2000
|
||||||
|
|
||||||
|
/* Unprivileged CSR */
|
||||||
|
#define CSR_CYCLE 0xC00
|
||||||
|
#define CSR_TIME 0xC01
|
||||||
|
#define CSR_CYCLEH 0xC80
|
||||||
|
#define CSR_TIMEH 0xC81
|
||||||
|
|
||||||
/* Supervisor-level CSR */
|
/* Supervisor-level CSR */
|
||||||
/* Supervisor Trap setup CSR */
|
/* Supervisor Trap setup CSR */
|
||||||
#define CSR_SSTATUS 0x100
|
#define CSR_SSTATUS 0x100
|
||||||
|
@ -507,6 +507,7 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction)
|
|||||||
}
|
}
|
||||||
case OPCODE_SYSTEM:
|
case OPCODE_SYSTEM:
|
||||||
{
|
{
|
||||||
|
uint32_t csr = instruction->immediate;
|
||||||
switch(instruction->func3)
|
switch(instruction->func3)
|
||||||
{
|
{
|
||||||
case FUNC3_ECALL_EBREAK:
|
case FUNC3_ECALL_EBREAK:
|
||||||
@ -549,35 +550,39 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction)
|
|||||||
break;
|
break;
|
||||||
case FUNC3_CSRRW:
|
case FUNC3_CSRRW:
|
||||||
// CSR atomic Read/Write
|
// CSR atomic Read/Write
|
||||||
uint32_t csrrw_old_value = cpu->csr[instruction->immediate];
|
uint32_t csrrw_old_value = 0;
|
||||||
cpu->csr[instruction->immediate] = cpu->regs.x[instruction->rs1];
|
if(instruction->rd)
|
||||||
|
csrrw_old_value = csr_read(cpu, csr);
|
||||||
|
csr_write(cpu, csr, cpu->regs.x[instruction->rs1]);
|
||||||
cpu->regs.x[instruction->rd] = csrrw_old_value;
|
cpu->regs.x[instruction->rd] = csrrw_old_value;
|
||||||
break;
|
break;
|
||||||
case FUNC3_CSRRS:
|
case FUNC3_CSRRS:
|
||||||
// CSR atomic Read and Set bits
|
// CSR atomic Read and Set bits
|
||||||
cpu->regs.x[instruction->rd] = cpu->csr[instruction->immediate];
|
cpu->regs.x[instruction->rd] = csr_read(cpu, csr);
|
||||||
cpu->csr[instruction->immediate] |= cpu->regs.x[instruction->rs1];
|
csr_write(cpu, csr, cpu->regs.x[instruction->rd] | cpu->regs.x[instruction->rs1]);
|
||||||
break;
|
break;
|
||||||
case FUNC3_CSRRC:
|
case FUNC3_CSRRC:
|
||||||
// CSR atomic Read and Clear bits
|
// CSR atomic Read and Clear bits
|
||||||
cpu->regs.x[instruction->rd] = cpu->csr[instruction->immediate];
|
cpu->regs.x[instruction->rd] = csr_read(cpu, csr);
|
||||||
cpu->csr[instruction->immediate] &= (~cpu->regs.x[instruction->rs1]);
|
csr_write(cpu, csr, cpu->regs.x[instruction->rd] & (~cpu->regs.x[instruction->rs1]));
|
||||||
break;
|
break;
|
||||||
case FUNC3_CSRRWI:
|
case FUNC3_CSRRWI:
|
||||||
// CSR atomic Read/Write Immediate (immediate in rs1)
|
// CSR atomic Read/Write Immediate (immediate in rs1)
|
||||||
uint32_t csrrwi_old_value = cpu->csr[instruction->immediate];
|
uint32_t csrrwi_old_value = 0;
|
||||||
cpu->csr[instruction->immediate] = instruction->rs1;
|
if(instruction->rd)
|
||||||
|
csrrwi_old_value = csr_read(cpu, csr);
|
||||||
|
csr_write(cpu, csr, instruction->rs1);
|
||||||
cpu->regs.x[instruction->rd] = csrrwi_old_value;
|
cpu->regs.x[instruction->rd] = csrrwi_old_value;
|
||||||
break;
|
break;
|
||||||
case FUNC3_CSRRSI:
|
case FUNC3_CSRRSI:
|
||||||
// CSR atomic Read and Set bits immediate
|
// CSR atomic Read and Set bits immediate
|
||||||
cpu->regs.x[instruction->rd] = cpu->csr[instruction->immediate];
|
cpu->regs.x[instruction->rd] = csr_read(cpu, csr);
|
||||||
cpu->csr[instruction->immediate] |= instruction->rs1;
|
csr_write(cpu, csr, cpu->regs.x[instruction->rd] | instruction->rs1);
|
||||||
break;
|
break;
|
||||||
case FUNC3_CSRRCI:
|
case FUNC3_CSRRCI:
|
||||||
// CSR atomic Read and Clear bits Immediate (immediate in rs1)
|
// CSR atomic Read and Clear bits Immediate (immediate in rs1)
|
||||||
cpu->regs.x[instruction->rd] = cpu->csr[instruction->immediate];
|
cpu->regs.x[instruction->rd] = csr_read(cpu, csr);
|
||||||
cpu->csr[instruction->immediate] &= (~((uint32_t) instruction->rs1));
|
csr_write(cpu, csr, cpu->regs.x[instruction->rd] & (~((uint32_t) instruction->rs1)));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "FATAL: Unknown func3 0x%x for SYSTEM instruction while executing\n", instruction->func3);
|
fprintf(stderr, "FATAL: Unknown func3 0x%x for SYSTEM instruction while executing\n", instruction->func3);
|
||||||
|
@ -207,6 +207,9 @@ typedef struct RV32_CPU
|
|||||||
pthread_cond_t sim_condition;
|
pthread_cond_t sim_condition;
|
||||||
} rv32_cpu_t;
|
} rv32_cpu_t;
|
||||||
|
|
||||||
|
uint32_t csr_read(struct RV32_CPU* cpu, uint32_t csr);
|
||||||
|
void csr_write(struct RV32_CPU* cpu, uint32_t csr, uint32_t value);
|
||||||
|
|
||||||
extern rv32_cpu_t* cpu0;
|
extern rv32_cpu_t* cpu0;
|
||||||
extern pthread_mutex_t cpu0_mutex;
|
extern pthread_mutex_t cpu0_mutex;
|
||||||
void cpu_init();
|
void cpu_init();
|
||||||
|
Loading…
Reference in New Issue
Block a user