Memory interface is now MMIO-capable
This commit is contained in:
@@ -4,7 +4,6 @@
|
||||
#include "devices/sbi/sbi.h"
|
||||
|
||||
#include "memory/memory.h"
|
||||
#include "memory/mmu/mmu.h"
|
||||
#include "vriscv.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -210,27 +209,27 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction)
|
||||
{
|
||||
case FUNC3_LB:
|
||||
// Load Byte (8-bits)
|
||||
cpu->regs.x[instruction->rd] = memory[mmu_translate(address)];
|
||||
cpu->regs.x[instruction->rd] = mem_read8(address);
|
||||
// Sign extend from 8 bits to 32 bits
|
||||
cpu->regs.x[instruction->rd] |= (cpu->regs.x[instruction->rd] & 0x80 ? 0xFFFFFF00 : 0);
|
||||
break;
|
||||
case FUNC3_LH:
|
||||
// Load Halfword (16-bits)
|
||||
cpu->regs.x[instruction->rd] = *((uint16_t*) &memory[mmu_translate(address)]);
|
||||
cpu->regs.x[instruction->rd] = mem_read16(address);
|
||||
// Sign extend from 16 bits to 32 bits
|
||||
cpu->regs.x[instruction->rd] |= (cpu->regs.x[instruction->rd] & 0x8000 ? 0xFFFF0000 : 0);
|
||||
break;
|
||||
case FUNC3_LW:
|
||||
// Load Word (32-bits)
|
||||
cpu->regs.x[instruction->rd] = *((uint32_t*) &memory[mmu_translate(address)]);
|
||||
cpu->regs.x[instruction->rd] = mem_read32(address);
|
||||
break;
|
||||
case FUNC3_LBU:
|
||||
// Load Byte Unsigned (8-bits)
|
||||
cpu->regs.x[instruction->rd] = memory[mmu_translate(address)];
|
||||
cpu->regs.x[instruction->rd] = mem_read8(address);
|
||||
break;
|
||||
case FUNC3_LHU:
|
||||
// Load Halfword Unsigned (16-bits)
|
||||
cpu->regs.x[instruction->rd] = *((uint16_t*) &memory[mmu_translate(address)]);
|
||||
cpu->regs.x[instruction->rd] = mem_read16(address);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "FATAL: Unknown func3 0x%x for load instruction, could not execute\n", instruction->func3);
|
||||
@@ -250,15 +249,15 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction)
|
||||
{
|
||||
case FUNC3_SB:
|
||||
// Store Byte (8-bits)
|
||||
memory[mmu_translate(address)] = cpu->regs.x[instruction->rs2] & 0xFF;
|
||||
mem_write8(address, cpu->regs.x[instruction->rs2] & 0xFF);
|
||||
break;
|
||||
case FUNC3_SH:
|
||||
// Store Halfword (16-bits)
|
||||
*((uint16_t*) &memory[mmu_translate(address)]) = cpu->regs.x[instruction->rs2] & 0xFFFF;
|
||||
mem_write16(address, cpu->regs.x[instruction->rs2] & 0xFFFF);
|
||||
break;
|
||||
case FUNC3_SW:
|
||||
// Store Word (32-bits)
|
||||
*((uint32_t*) &memory[mmu_translate(address)]) = cpu->regs.x[instruction->rs2];
|
||||
mem_write32(address, cpu->regs.x[instruction->rs2]);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "FATAL: Unknown func3 0x%x for store instruction, could not execute\n", instruction->func3);
|
||||
@@ -588,77 +587,76 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction)
|
||||
|
||||
// FUNC7 contains 2 flag bits in lower part ; ignore them, we look for func7_5
|
||||
uint32_t address = cpu->regs.x[instruction->rs1];
|
||||
uint32_t* ptr = ((uint32_t*) &memory[mmu_translate(address)]);
|
||||
switch(instruction->func7 >> 2)
|
||||
{
|
||||
case FUNC75_LRW:
|
||||
// Load-Reserved Word
|
||||
cpu->regs.x[instruction->rd] = *ptr;
|
||||
cpu->regs.x[instruction->rd] = mem_read32(address);
|
||||
// TODO register reservation set that subsumes the bytes in word
|
||||
fprintf(stderr, "LR.W\n");
|
||||
break;
|
||||
case FUNC75_SCW:
|
||||
// Store-Conditional Word
|
||||
// TODO succeed only if the reservation is still valid and the reservation set contains the bytes written
|
||||
*ptr = cpu->regs.x[instruction->rs2];
|
||||
mem_write32(address, cpu->regs.x[instruction->rs2]);
|
||||
cpu->regs.x[instruction->rd] = 0; // TODO write 1 in rd on failure
|
||||
fprintf(stderr, "SC.W\n");
|
||||
break;
|
||||
case FUNC75_AMOSWAPW:
|
||||
// Atomic Memory Operation SWAP Word
|
||||
cpu->regs.x[instruction->rd] = *ptr;
|
||||
cpu->regs.x[instruction->rd] = mem_read32(address);
|
||||
// Put in RS1 addr the value of RS2
|
||||
*ptr = cpu->regs.x[instruction->rs2];
|
||||
mem_write32(address, cpu->regs.x[instruction->rs2]);
|
||||
// Put in RS2 the value of RS1 addr (which is in RD)
|
||||
cpu->regs.x[instruction->rs2] = cpu->regs.x[instruction->rd];
|
||||
break;
|
||||
case FUNC75_AMOADDW:
|
||||
// Atomic Memory Operation ADD Word
|
||||
cpu->regs.x[instruction->rd] = *ptr;
|
||||
cpu->regs.x[instruction->rd] = mem_read32(address);
|
||||
// Add rs1 addr and value of rs2
|
||||
*ptr = cpu->regs.x[instruction->rd] + cpu->regs.x[instruction->rs2];
|
||||
mem_write32(address, cpu->regs.x[instruction->rd] + cpu->regs.x[instruction->rs2]);
|
||||
break;
|
||||
case FUNC75_AMOXORW:
|
||||
// Atomic Memory Operation XOR Word
|
||||
cpu->regs.x[instruction->rd] = *ptr;
|
||||
cpu->regs.x[instruction->rd] = mem_read32(address);
|
||||
// Xor rs1 addr and value of rs2
|
||||
*ptr = cpu->regs.x[instruction->rd] ^ cpu->regs.x[instruction->rs2];
|
||||
mem_write32(address, cpu->regs.x[instruction->rd] ^ cpu->regs.x[instruction->rs2]);
|
||||
break;
|
||||
case FUNC75_AMOANDW:
|
||||
// Atomic Memory Operation AND Word
|
||||
cpu->regs.x[instruction->rd] = *ptr;
|
||||
cpu->regs.x[instruction->rd] = mem_read32(address);
|
||||
// AND rs1 addr and value of rs2
|
||||
*ptr = cpu->regs.x[instruction->rd] & cpu->regs.x[instruction->rs2];
|
||||
mem_write32(address, cpu->regs.x[instruction->rd] & cpu->regs.x[instruction->rs2]);
|
||||
break;
|
||||
case FUNC75_AMOORW:
|
||||
// Atomic Memory Operation OR Word
|
||||
cpu->regs.x[instruction->rd] = *ptr;
|
||||
cpu->regs.x[instruction->rd] = mem_read32(address);
|
||||
// Or rs1 addr and value of rs2
|
||||
*ptr = cpu->regs.x[instruction->rd] | cpu->regs.x[instruction->rs2];
|
||||
mem_write32(address, cpu->regs.x[instruction->rd] | cpu->regs.x[instruction->rs2]);
|
||||
break;
|
||||
case FUNC75_AMOMINW:
|
||||
// Atomic Memory Operation MIN Word
|
||||
cpu->regs.x[instruction->rd] = *ptr;
|
||||
cpu->regs.x[instruction->rd] = mem_read32(address);
|
||||
// Min rs1 addr and value of rs2
|
||||
*ptr = ((int32_t) cpu->regs.x[instruction->rd]) < ((int32_t) cpu->regs.x[instruction->rs2]) ? cpu->regs.x[instruction->rd] : cpu->regs.x[instruction->rs2];
|
||||
mem_write32(address, ((int32_t) cpu->regs.x[instruction->rd]) < ((int32_t) cpu->regs.x[instruction->rs2]) ? cpu->regs.x[instruction->rd] : cpu->regs.x[instruction->rs2]);
|
||||
break;
|
||||
case FUNC75_AMOMAXW:
|
||||
// Atomic Memory Operation MAX Word
|
||||
cpu->regs.x[instruction->rd] = *ptr;
|
||||
cpu->regs.x[instruction->rd] = mem_read32(address);
|
||||
// Max rs1 addr and value of rs2
|
||||
*ptr = ((int32_t) cpu->regs.x[instruction->rd]) > ((int32_t) cpu->regs.x[instruction->rs2]) ? cpu->regs.x[instruction->rd] : cpu->regs.x[instruction->rs2];
|
||||
mem_write32(address, ((int32_t) cpu->regs.x[instruction->rd]) > ((int32_t) cpu->regs.x[instruction->rs2]) ? cpu->regs.x[instruction->rd] : cpu->regs.x[instruction->rs2]);
|
||||
break;
|
||||
case FUNC75_AMOMINUW:
|
||||
// Atomic Memory Operation MIN Unsigned Word
|
||||
cpu->regs.x[instruction->rd] = *ptr;
|
||||
cpu->regs.x[instruction->rd] = mem_read32(address);
|
||||
// Min rs1 addr and value of rs2
|
||||
*ptr = cpu->regs.x[instruction->rd] < cpu->regs.x[instruction->rs2] ? cpu->regs.x[instruction->rd] : cpu->regs.x[instruction->rs2];
|
||||
mem_write32(address, cpu->regs.x[instruction->rd] < cpu->regs.x[instruction->rs2] ? cpu->regs.x[instruction->rd] : cpu->regs.x[instruction->rs2]);
|
||||
break;
|
||||
case FUNC75_AMOMAXUW:
|
||||
// Atomic Memory Operation MAX Unsigned Word
|
||||
cpu->regs.x[instruction->rd] = *ptr;
|
||||
cpu->regs.x[instruction->rd] = mem_read32(address);
|
||||
// Max rs1 addr and value of rs2
|
||||
*ptr = cpu->regs.x[instruction->rd] > cpu->regs.x[instruction->rs2] ? cpu->regs.x[instruction->rd] : cpu->regs.x[instruction->rs2];
|
||||
mem_write32(address, cpu->regs.x[instruction->rd] > cpu->regs.x[instruction->rs2] ? cpu->regs.x[instruction->rd] : cpu->regs.x[instruction->rs2]);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "FATAL: Unknown func7 0x%x for ATOMIC/0x2 instruction, could not execute\n", instruction->func7);
|
||||
@@ -688,7 +686,7 @@ void cpu_loop(rv32_cpu_t* cpu)
|
||||
while(!cpu->sim_ticks_left)
|
||||
pthread_cond_wait(&cpu0->sim_condition, &cpu0_mutex);
|
||||
|
||||
pthread_mutex_lock(&memory_mutex);
|
||||
// pthread_mutex_lock(&memory_mutex);
|
||||
|
||||
// Fetch
|
||||
raw_instruction_t raw_instruction;
|
||||
@@ -723,7 +721,7 @@ void cpu_loop(rv32_cpu_t* cpu)
|
||||
cpu->sim_ticks_left--;
|
||||
|
||||
// Let go of cpu and memory mutex
|
||||
pthread_mutex_unlock(&memory_mutex);
|
||||
// pthread_mutex_unlock(&memory_mutex);
|
||||
pthread_mutex_unlock(&cpu0_mutex);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user