Added CSR_TIME support
This commit is contained in:
		
							
								
								
									
										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
 | 
			
		||||
#define CSR_H
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
/* ZICSR : Control and Status Registers */
 | 
			
		||||
#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 Trap setup CSR */
 | 
			
		||||
#define CSR_SSTATUS 0x100
 | 
			
		||||
 
 | 
			
		||||
@@ -507,6 +507,7 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction)
 | 
			
		||||
		}
 | 
			
		||||
		case OPCODE_SYSTEM:
 | 
			
		||||
		{
 | 
			
		||||
			uint32_t csr = instruction->immediate;
 | 
			
		||||
			switch(instruction->func3)
 | 
			
		||||
			{
 | 
			
		||||
				case FUNC3_ECALL_EBREAK:
 | 
			
		||||
@@ -549,35 +550,39 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction)
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_CSRRW:
 | 
			
		||||
					// CSR atomic Read/Write
 | 
			
		||||
					uint32_t csrrw_old_value = cpu->csr[instruction->immediate];
 | 
			
		||||
					cpu->csr[instruction->immediate] = cpu->regs.x[instruction->rs1];
 | 
			
		||||
					uint32_t csrrw_old_value = 0;
 | 
			
		||||
					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;
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_CSRRS:
 | 
			
		||||
					// CSR atomic Read and Set bits
 | 
			
		||||
					cpu->regs.x[instruction->rd] = cpu->csr[instruction->immediate];
 | 
			
		||||
					cpu->csr[instruction->immediate] |= cpu->regs.x[instruction->rs1];
 | 
			
		||||
					cpu->regs.x[instruction->rd] = csr_read(cpu, csr);
 | 
			
		||||
					csr_write(cpu, csr, cpu->regs.x[instruction->rd] | cpu->regs.x[instruction->rs1]);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_CSRRC:
 | 
			
		||||
					// CSR atomic Read and Clear bits
 | 
			
		||||
					cpu->regs.x[instruction->rd] = cpu->csr[instruction->immediate];
 | 
			
		||||
					cpu->csr[instruction->immediate] &= (~cpu->regs.x[instruction->rs1]);
 | 
			
		||||
					cpu->regs.x[instruction->rd] = csr_read(cpu, csr);
 | 
			
		||||
					csr_write(cpu, csr, cpu->regs.x[instruction->rd] & (~cpu->regs.x[instruction->rs1]));
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_CSRRWI:
 | 
			
		||||
					// CSR atomic Read/Write Immediate (immediate in rs1)
 | 
			
		||||
					uint32_t csrrwi_old_value = cpu->csr[instruction->immediate];
 | 
			
		||||
					cpu->csr[instruction->immediate] = instruction->rs1;
 | 
			
		||||
					uint32_t csrrwi_old_value = 0;
 | 
			
		||||
					if(instruction->rd)
 | 
			
		||||
						csrrwi_old_value = csr_read(cpu, csr);
 | 
			
		||||
					csr_write(cpu, csr, instruction->rs1);
 | 
			
		||||
					cpu->regs.x[instruction->rd] = csrrwi_old_value;
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_CSRRSI:
 | 
			
		||||
					// CSR atomic Read and Set bits immediate
 | 
			
		||||
					cpu->regs.x[instruction->rd] = cpu->csr[instruction->immediate];
 | 
			
		||||
					cpu->csr[instruction->immediate] |= instruction->rs1;
 | 
			
		||||
					cpu->regs.x[instruction->rd] = csr_read(cpu, csr);
 | 
			
		||||
					csr_write(cpu, csr, cpu->regs.x[instruction->rd] | instruction->rs1);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_CSRRCI:
 | 
			
		||||
					// CSR atomic Read and Clear bits Immediate (immediate in rs1)
 | 
			
		||||
					cpu->regs.x[instruction->rd] = cpu->csr[instruction->immediate];
 | 
			
		||||
					cpu->csr[instruction->immediate] &= (~((uint32_t) instruction->rs1));
 | 
			
		||||
					cpu->regs.x[instruction->rd] = csr_read(cpu, csr);
 | 
			
		||||
					csr_write(cpu, csr, cpu->regs.x[instruction->rd] & (~((uint32_t) instruction->rs1)));
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					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;
 | 
			
		||||
} 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 pthread_mutex_t cpu0_mutex;
 | 
			
		||||
void cpu_init();
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user