Compare commits
No commits in common. "b57739fe38b82b6f57914ca49ca61a616b390ec0" and "71f3fbc8b55005d4fc1b7ef92a5d86006445cc62" have entirely different histories.
b57739fe38
...
71f3fbc8b5
@ -50,7 +50,7 @@ void mem_write8(uint32_t address, uint8_t value)
|
|||||||
{
|
{
|
||||||
if(io->reg_size == 1)
|
if(io->reg_size == 1)
|
||||||
{
|
{
|
||||||
void (*fn_write)(uint32_t, uint8_t) = io->fn_write;
|
void (*fn_write)(uint32_t, uint8_t) = io->fn_write;
|
||||||
fn_write(address, value);
|
fn_write(address, value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -63,13 +63,6 @@ void mem_write8(uint32_t address, uint8_t value)
|
|||||||
io = io->next;
|
io = io->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we are inside of physical memory
|
|
||||||
if(address + 1 > memory_size)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "MEMORY: Invalid write of size 1 outside of physical memory at address 0x%x\n", address);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Proceed with memory write
|
// Proceed with memory write
|
||||||
pthread_mutex_lock(&memory_mutex);
|
pthread_mutex_lock(&memory_mutex);
|
||||||
memory[address] = value;
|
memory[address] = value;
|
||||||
@ -88,7 +81,7 @@ void mem_write16(uint32_t address, uint16_t value)
|
|||||||
{
|
{
|
||||||
if(io->reg_size == 2)
|
if(io->reg_size == 2)
|
||||||
{
|
{
|
||||||
void (*fn_write)(uint32_t, uint16_t) = io->fn_write;
|
void (*fn_write)(uint32_t, uint16_t) = io->fn_write;
|
||||||
fn_write(address, value);
|
fn_write(address, value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -101,13 +94,6 @@ void mem_write16(uint32_t address, uint16_t value)
|
|||||||
io = io->next;
|
io = io->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we are inside of physical memory
|
|
||||||
if(address + 2 > memory_size)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "MEMORY: Invalid write of size 2 outside of physical memory at address 0x%x\n", address);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Proceed with memory write
|
// Proceed with memory write
|
||||||
pthread_mutex_lock(&memory_mutex);
|
pthread_mutex_lock(&memory_mutex);
|
||||||
*((uint16_t*) &memory[address]) = value;
|
*((uint16_t*) &memory[address]) = value;
|
||||||
@ -126,7 +112,7 @@ void mem_write32(uint32_t address, uint32_t value)
|
|||||||
{
|
{
|
||||||
if(io->reg_size == 4)
|
if(io->reg_size == 4)
|
||||||
{
|
{
|
||||||
void (*fn_write)(uint32_t, uint32_t) = io->fn_write;
|
void (*fn_write)(uint32_t, uint32_t) = io->fn_write;
|
||||||
fn_write(address, value);
|
fn_write(address, value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -139,13 +125,6 @@ void mem_write32(uint32_t address, uint32_t value)
|
|||||||
io = io->next;
|
io = io->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we are inside of physical memory
|
|
||||||
if(address + 4 > memory_size)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "MEMORY: Invalid write of size 1 outside of physical memory at address 0x%x\n", address);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Proceed with memory write
|
// Proceed with memory write
|
||||||
pthread_mutex_lock(&memory_mutex);
|
pthread_mutex_lock(&memory_mutex);
|
||||||
*((uint32_t*) &memory[address]) = value;
|
*((uint32_t*) &memory[address]) = value;
|
||||||
@ -156,7 +135,7 @@ uint8_t mem_read8(uint32_t address)
|
|||||||
{
|
{
|
||||||
address = mmu_resolve(cpu0, READ, address);
|
address = mmu_resolve(cpu0, READ, address);
|
||||||
|
|
||||||
// Look wether we are on an MMIO region
|
// Look wether we are on an MMIO region
|
||||||
struct MMIO_ENTRY* io = mmio;
|
struct MMIO_ENTRY* io = mmio;
|
||||||
while(io)
|
while(io)
|
||||||
{
|
{
|
||||||
@ -164,7 +143,7 @@ uint8_t mem_read8(uint32_t address)
|
|||||||
{
|
{
|
||||||
if(io->reg_size == 1)
|
if(io->reg_size == 1)
|
||||||
{
|
{
|
||||||
uint8_t (*fn_read)(uint32_t) = io->fn_read;
|
uint8_t (*fn_read)(uint32_t) = io->fn_read;
|
||||||
return fn_read(address);
|
return fn_read(address);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -176,25 +155,18 @@ uint8_t mem_read8(uint32_t address)
|
|||||||
io = io->next;
|
io = io->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we are inside of physical memory
|
|
||||||
if(address + 1 > memory_size)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "MEMORY: Invalid read of size 1 outside of physical memory at address 0x%x\n", address);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Proceed with memory read
|
// Proceed with memory read
|
||||||
pthread_mutex_lock(&memory_mutex);
|
pthread_mutex_lock(&memory_mutex);
|
||||||
uint8_t tr = memory[address];
|
uint8_t tr = memory[address];
|
||||||
pthread_mutex_unlock(&memory_mutex);
|
pthread_mutex_unlock(&memory_mutex);
|
||||||
return tr;
|
return tr;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t mem_read16(uint32_t address)
|
uint16_t mem_read16(uint32_t address)
|
||||||
{
|
{
|
||||||
address = mmu_resolve(cpu0, READ, address);
|
address = mmu_resolve(cpu0, READ, address);
|
||||||
|
|
||||||
// Look wether we are on an MMIO region
|
// Look wether we are on an MMIO region
|
||||||
struct MMIO_ENTRY* io = mmio;
|
struct MMIO_ENTRY* io = mmio;
|
||||||
while(io)
|
while(io)
|
||||||
{
|
{
|
||||||
@ -202,7 +174,7 @@ uint16_t mem_read16(uint32_t address)
|
|||||||
{
|
{
|
||||||
if(io->reg_size == 2)
|
if(io->reg_size == 2)
|
||||||
{
|
{
|
||||||
uint16_t (*fn_read)(uint32_t) = io->fn_read;
|
uint16_t (*fn_read)(uint32_t) = io->fn_read;
|
||||||
return fn_read(address);
|
return fn_read(address);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -214,25 +186,18 @@ uint16_t mem_read16(uint32_t address)
|
|||||||
io = io->next;
|
io = io->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we are inside of physical memory
|
|
||||||
if(address + 2 > memory_size)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "MEMORY: Invalid read of size 2 outside of physical memory at address 0x%x\n", address);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Proceed with memory read
|
// Proceed with memory read
|
||||||
pthread_mutex_lock(&memory_mutex);
|
pthread_mutex_lock(&memory_mutex);
|
||||||
uint16_t tr = *((uint16_t*) &memory[address]);
|
uint16_t tr = *((uint16_t*) &memory[address]);
|
||||||
pthread_mutex_unlock(&memory_mutex);
|
pthread_mutex_unlock(&memory_mutex);
|
||||||
return tr;
|
return tr;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t mem_read32(uint32_t address)
|
uint32_t mem_read32(uint32_t address)
|
||||||
{
|
{
|
||||||
address = mmu_resolve(cpu0, READ, address);
|
address = mmu_resolve(cpu0, READ, address);
|
||||||
|
|
||||||
// Look wether we are on an MMIO region
|
// Look wether we are on an MMIO region
|
||||||
struct MMIO_ENTRY* io = mmio;
|
struct MMIO_ENTRY* io = mmio;
|
||||||
while(io)
|
while(io)
|
||||||
{
|
{
|
||||||
@ -240,7 +205,7 @@ uint32_t mem_read32(uint32_t address)
|
|||||||
{
|
{
|
||||||
if(io->reg_size == 4)
|
if(io->reg_size == 4)
|
||||||
{
|
{
|
||||||
uint32_t (*fn_read)(uint32_t) = io->fn_read;
|
uint32_t (*fn_read)(uint32_t) = io->fn_read;
|
||||||
return fn_read(address);
|
return fn_read(address);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -252,25 +217,18 @@ uint32_t mem_read32(uint32_t address)
|
|||||||
io = io->next;
|
io = io->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we are inside of physical memory
|
|
||||||
if(address + 4 > memory_size)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "MEMORY: Invalid read of size 4 outside of physical memory at address 0x%x\n", address);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Proceed with memory read
|
// Proceed with memory read
|
||||||
pthread_mutex_lock(&memory_mutex);
|
pthread_mutex_lock(&memory_mutex);
|
||||||
uint32_t tr = *((uint32_t*) &memory[address]);
|
uint32_t tr = *((uint32_t*) &memory[address]);
|
||||||
pthread_mutex_unlock(&memory_mutex);
|
pthread_mutex_unlock(&memory_mutex);
|
||||||
return tr;
|
return tr;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t mem_fetch(uint32_t address)
|
uint32_t mem_fetch(uint32_t address)
|
||||||
{
|
{
|
||||||
address = mmu_resolve(cpu0, INSTRUCTION_FETCH, address);
|
address = mmu_resolve(cpu0, INSTRUCTION_FETCH, address);
|
||||||
|
|
||||||
// Look wether we are on an MMIO region
|
// Look wether we are on an MMIO region
|
||||||
struct MMIO_ENTRY* io = mmio;
|
struct MMIO_ENTRY* io = mmio;
|
||||||
while(io)
|
while(io)
|
||||||
{
|
{
|
||||||
@ -282,16 +240,9 @@ uint32_t mem_fetch(uint32_t address)
|
|||||||
io = io->next;
|
io = io->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we are inside of physical memory
|
|
||||||
if(address + 4 > memory_size)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "MEMORY: Invalid fetch outside of physical memory at address 0x%x\n", address);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Proceed with memory read
|
// Proceed with memory read
|
||||||
pthread_mutex_lock(&memory_mutex);
|
pthread_mutex_lock(&memory_mutex);
|
||||||
uint32_t tr = *((uint32_t*) &memory[address]);
|
uint32_t tr = *((uint32_t*) &memory[address]);
|
||||||
pthread_mutex_unlock(&memory_mutex);
|
pthread_mutex_unlock(&memory_mutex);
|
||||||
return tr;
|
return tr;
|
||||||
}
|
}
|
||||||
|
@ -89,18 +89,6 @@ uint32_t mmu_resolve(rv32_cpu_t* cpu, memory_access_type_t access_type, uint32_t
|
|||||||
// Leaf PTE, we are ready to resolve the mapping
|
// Leaf PTE, we are ready to resolve the mapping
|
||||||
// This is a 4 MiB megapage
|
// This is a 4 MiB megapage
|
||||||
|
|
||||||
// For an execute, check if we are allowed to execute
|
|
||||||
if(access_type == INSTRUCTION_FETCH && !(pte & PTE_X))
|
|
||||||
exception_trigger(cpu, mmu_scause_from_access(access_type), vaddr);
|
|
||||||
|
|
||||||
// For a write, check if we are allowed to write
|
|
||||||
if(access_type == WRITE && !(pte & PTE_W))
|
|
||||||
exception_trigger(cpu, mmu_scause_from_access(access_type), vaddr);
|
|
||||||
|
|
||||||
// For a read, check if we are allowed to read
|
|
||||||
if(access_type == READ && !(pte & PTE_R))
|
|
||||||
exception_trigger(cpu, mmu_scause_from_access(access_type), vaddr);
|
|
||||||
|
|
||||||
// Physical Address: [PPN[1] = pte.PPN[1], PPN[0] = vaddr.VPN[0], offset]
|
// Physical Address: [PPN[1] = pte.PPN[1], PPN[0] = vaddr.VPN[0], offset]
|
||||||
uint32_t paddr = 0;
|
uint32_t paddr = 0;
|
||||||
paddr |= (PTE_PPN_1(pte) << 22);
|
paddr |= (PTE_PPN_1(pte) << 22);
|
||||||
@ -132,18 +120,6 @@ uint32_t mmu_resolve(rv32_cpu_t* cpu, memory_access_type_t access_type, uint32_t
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For an execute, check if we are allowed to execute
|
|
||||||
if(access_type == INSTRUCTION_FETCH && !(pte & PTE_X))
|
|
||||||
exception_trigger(cpu, mmu_scause_from_access(access_type), vaddr);
|
|
||||||
|
|
||||||
// For a write, check if we are allowed to write
|
|
||||||
if(access_type == WRITE && !(pte & PTE_W))
|
|
||||||
exception_trigger(cpu, mmu_scause_from_access(access_type), vaddr);
|
|
||||||
|
|
||||||
// For a read, check if we are allowed to read
|
|
||||||
if(access_type == READ && !(pte & PTE_R))
|
|
||||||
exception_trigger(cpu, mmu_scause_from_access(access_type), vaddr);
|
|
||||||
|
|
||||||
// Physical Address: [PPN[1] = pte.PPN[1], PPN[0] = pte.PPN[0], offset]
|
// Physical Address: [PPN[1] = pte.PPN[1], PPN[0] = pte.PPN[0], offset]
|
||||||
uint32_t paddr = 0;
|
uint32_t paddr = 0;
|
||||||
paddr |= (PTE_PPN_1(pte) << 22);
|
paddr |= (PTE_PPN_1(pte) << 22);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user