Added memory access type for mmu
This commit is contained in:
parent
5bb973e8da
commit
dcdebcd8e4
@ -682,7 +682,7 @@ __attribute__((noreturn)) void cpu_loop(rv32_cpu_t* cpu)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
// Aquire CPU and memory mutex
|
||||
// Aquire CPU mutex
|
||||
pthread_mutex_lock(&cpu0_mutex);
|
||||
|
||||
// No simulation ticks left : wakeup people waiting on sim end
|
||||
@ -692,8 +692,6 @@ __attribute__((noreturn)) 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);
|
||||
|
||||
// Fetch
|
||||
raw_instruction_t raw_instruction;
|
||||
if(cpu->pc > memory_size - 4)
|
||||
@ -701,7 +699,7 @@ __attribute__((noreturn)) void cpu_loop(rv32_cpu_t* cpu)
|
||||
fprintf(stderr, "Error: instruction fetch: pc is out of addressable memory\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
raw_instruction.data = mem_read32(cpu->pc);
|
||||
raw_instruction.data = mem_fetch(cpu->pc);
|
||||
|
||||
// Decode
|
||||
instruction_t instruction;
|
||||
@ -726,8 +724,7 @@ __attribute__((noreturn)) void cpu_loop(rv32_cpu_t* cpu)
|
||||
if(cpu->sim_ticks_left != (-1))
|
||||
cpu->sim_ticks_left--;
|
||||
|
||||
// Let go of cpu and memory mutex
|
||||
// pthread_mutex_unlock(&memory_mutex);
|
||||
// Let go of cpu mutex
|
||||
pthread_mutex_unlock(&cpu0_mutex);
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ void mem_register_mmio(uint32_t address, uint32_t reg_size, uint32_t reg_count,
|
||||
|
||||
void mem_write8(uint32_t address, uint8_t value)
|
||||
{
|
||||
address = mmu_resolve(cpu0, address);
|
||||
address = mmu_resolve(cpu0, WRITE, address);
|
||||
|
||||
// Look wether we are on an MMIO region
|
||||
struct MMIO_ENTRY* io = mmio;
|
||||
@ -71,7 +71,7 @@ void mem_write8(uint32_t address, uint8_t value)
|
||||
|
||||
void mem_write16(uint32_t address, uint16_t value)
|
||||
{
|
||||
address = mmu_resolve(cpu0, address);
|
||||
address = mmu_resolve(cpu0, WRITE, address);
|
||||
|
||||
// Look wether we are on an MMIO region
|
||||
struct MMIO_ENTRY* io = mmio;
|
||||
@ -102,7 +102,7 @@ void mem_write16(uint32_t address, uint16_t value)
|
||||
|
||||
void mem_write32(uint32_t address, uint32_t value)
|
||||
{
|
||||
address = mmu_resolve(cpu0, address);
|
||||
address = mmu_resolve(cpu0, WRITE, address);
|
||||
|
||||
// Look wether we are on an MMIO region
|
||||
struct MMIO_ENTRY* io = mmio;
|
||||
@ -133,7 +133,7 @@ void mem_write32(uint32_t address, uint32_t value)
|
||||
|
||||
uint8_t mem_read8(uint32_t address)
|
||||
{
|
||||
address = mmu_resolve(cpu0, address);
|
||||
address = mmu_resolve(cpu0, READ, address);
|
||||
|
||||
// Look wether we are on an MMIO region
|
||||
struct MMIO_ENTRY* io = mmio;
|
||||
@ -164,7 +164,7 @@ uint8_t mem_read8(uint32_t address)
|
||||
|
||||
uint16_t mem_read16(uint32_t address)
|
||||
{
|
||||
address = mmu_resolve(cpu0, address);
|
||||
address = mmu_resolve(cpu0, READ, address);
|
||||
|
||||
// Look wether we are on an MMIO region
|
||||
struct MMIO_ENTRY* io = mmio;
|
||||
@ -195,7 +195,7 @@ uint16_t mem_read16(uint32_t address)
|
||||
|
||||
uint32_t mem_read32(uint32_t address)
|
||||
{
|
||||
address = mmu_resolve(cpu0, address);
|
||||
address = mmu_resolve(cpu0, READ, address);
|
||||
|
||||
// Look wether we are on an MMIO region
|
||||
struct MMIO_ENTRY* io = mmio;
|
||||
@ -223,3 +223,26 @@ uint32_t mem_read32(uint32_t address)
|
||||
pthread_mutex_unlock(&memory_mutex);
|
||||
return tr;
|
||||
}
|
||||
|
||||
uint32_t mem_fetch(uint32_t address)
|
||||
{
|
||||
address = mmu_resolve(cpu0, INSTRUCTION_FETCH, address);
|
||||
|
||||
// Look wether we are on an MMIO region
|
||||
struct MMIO_ENTRY* io = mmio;
|
||||
while(io)
|
||||
{
|
||||
if(MMIO_INSIDE(io, address))
|
||||
{
|
||||
fprintf(stderr, "MEMORY: Trying to fetch an instruction inside an MMIO region !\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
io = io->next;
|
||||
}
|
||||
|
||||
// Proceed with memory read
|
||||
pthread_mutex_lock(&memory_mutex);
|
||||
uint32_t tr = *((uint32_t*) &memory[address]);
|
||||
pthread_mutex_unlock(&memory_mutex);
|
||||
return tr;
|
||||
}
|
||||
|
@ -14,5 +14,6 @@ void mem_write32(uint32_t address, uint32_t value);
|
||||
uint8_t mem_read8(uint32_t address);
|
||||
uint16_t mem_read16(uint32_t address);
|
||||
uint32_t mem_read32(uint32_t address);
|
||||
uint32_t mem_fetch(uint32_t address);
|
||||
|
||||
#endif
|
||||
|
@ -44,7 +44,24 @@ extern uint8_t* memory;
|
||||
#define VADDR_VPN_0 (0x003FF000)
|
||||
#define VADDR_PAGE_OFFSET (0x00000FFF)
|
||||
|
||||
uint32_t mmu_resolve(rv32_cpu_t* cpu, uint32_t vaddr)
|
||||
uint32_t mmu_scause_from_access(memory_access_type_t access_type)
|
||||
{
|
||||
switch(access_type)
|
||||
{
|
||||
case READ:
|
||||
return SCAUSE_LOAD_PAGE_FAULT;
|
||||
case WRITE:
|
||||
return SCAUSE_STORE_AMO_PAGE_FAULT;
|
||||
case INSTRUCTION_FETCH:
|
||||
return SCAUSE_INSTRUCTION_PAGE_FAULT;
|
||||
default:
|
||||
fprintf(stderr, "mmu_scause_from_access: invalid parameter\n");
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t mmu_resolve(rv32_cpu_t* cpu, memory_access_type_t access_type, uint32_t vaddr)
|
||||
{
|
||||
// TODO: Make sure we are in S-mode or U-mode
|
||||
|
||||
@ -64,8 +81,7 @@ uint32_t mmu_resolve(rv32_cpu_t* cpu, uint32_t vaddr)
|
||||
if(!(pte & PTE_V))
|
||||
{
|
||||
// Invalid PTE
|
||||
// TODO : Add a MEMORY_ACCESS_TYPE
|
||||
exception_trigger(cpu, SCAUSE_INSTRUCTION_PAGE_FAULT);
|
||||
exception_trigger(cpu, mmu_scause_from_access(access_type));
|
||||
}
|
||||
|
||||
if((pte & PTE_R) || (pte & PTE_W) || (pte & PTE_X))
|
||||
@ -93,7 +109,7 @@ uint32_t mmu_resolve(rv32_cpu_t* cpu, uint32_t vaddr)
|
||||
if(!(pte & PTE_V))
|
||||
{
|
||||
// Invalid PTE
|
||||
exception_trigger(cpu, SCAUSE_INSTRUCTION_PAGE_FAULT);
|
||||
exception_trigger(cpu, mmu_scause_from_access(access_type));
|
||||
}
|
||||
|
||||
// This must be a leaf PTE, as Sv32 only supports 2-level mappings
|
||||
|
@ -4,6 +4,13 @@
|
||||
#include <stdint.h>
|
||||
#include "cpu/rv32cpu.h"
|
||||
|
||||
uint32_t mmu_resolve(rv32_cpu_t* cpu, uint32_t vaddr);
|
||||
typedef enum MEMORY_ACCESS_TYPE
|
||||
{
|
||||
READ,
|
||||
WRITE,
|
||||
INSTRUCTION_FETCH
|
||||
} memory_access_type_t;
|
||||
|
||||
uint32_t mmu_resolve(rv32_cpu_t* cpu, memory_access_type_t access_type, uint32_t vaddr);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user