Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debugger: read_memory_32 initiates TLB_refill exception on reading invalid memory #680

Open
flagrama opened this issue Oct 7, 2019 · 0 comments

Comments

@flagrama
Copy link

commented Oct 7, 2019

The full offending code path is located at the end of this message.

If you use the debugger to read any memory that isn't "valid" the virtual_to_physical_address function forces a TLB_refill_exception to the emulator. As all of the "read_memory_*" functions use read_memory_32 they are all affected by this issue. I believe that the write_memory_* functions are also affected by this, however I have not tested it.

The debugger should never be causing exceptions to occur. Either the debugger needs to be special case opted out of the passing of the exception, or the debugger needs to use its own memory handler that simply reads the data.

uint32_t read_memory_32(struct device* dev, uint32_t addr)
{
uint32_t value;
if (r4300_read_aligned_word(&dev->r4300, addr, &value) == 0)
return M64P_MEM_INVALID;
return value;
}

int r4300_read_aligned_word(struct r4300_core* r4300, uint32_t address, uint32_t* value)
{
if ((address & UINT32_C(0xc0000000)) != UINT32_C(0x80000000)) {
address = virtual_to_physical_address(r4300, address, 0);
if (address == 0) {
return 0;
}
}
address &= UINT32_C(0x1ffffffc);
mem_read32(mem_get_handler(r4300->mem, address), address & ~UINT32_C(3), value);
return 1;
}

uint32_t virtual_to_physical_address(struct r4300_core* r4300, uint32_t address, int w)
{
const struct tlb* tlb = &r4300->cp0.tlb;
unsigned int addr = address >> 12;
#ifdef NEW_DYNAREC
if (r4300->emumode == EMUMODE_DYNAREC)
{
intptr_t map = r4300->new_dynarec_hot_state.memory_map[addr];
if ((tlb->LUT_w[addr]) && (w == 1))
{
assert(map == (((uintptr_t)r4300->rdram->dram + (uintptr_t)((tlb->LUT_w[addr] & 0xFFFFF000) - 0x80000000) - (address & 0xFFFFF000)) >> 2));
}
else if ((tlb->LUT_r[addr]) && (w == 0))
{
assert((map&~WRITE_PROTECT) == (((uintptr_t)r4300->rdram->dram + (uintptr_t)((tlb->LUT_r[addr] & 0xFFFFF000) - 0x80000000) - (address & 0xFFFFF000)) >> 2));
if (map & WRITE_PROTECT)
{
assert(tlb->LUT_w[addr] == 0);
}
}
else {
assert(map < 0);
}
}
#endif
if (w == 1)
{
if (tlb->LUT_w[addr])
return (tlb->LUT_w[addr] & UINT32_C(0xFFFFF000)) | (address & UINT32_C(0xFFF));
}
else
{
if (tlb->LUT_r[addr])
return (tlb->LUT_r[addr] & UINT32_C(0xFFFFF000)) | (address & UINT32_C(0xFFF));
}
//printf("tlb exception !!! @ %x, %x, add:%x\n", address, w, r4300->pc->addr);
//getchar();
TLB_refill_exception(r4300, address, w);
//return 0x80000000;
return 0x00000000;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant
You can’t perform that action at this time.