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
 | 
					#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();
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user