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