|
|
@ -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; |
|
|
|
} |
|
|
|
} |
|
|
|