tlbrefill: Initial upload

This commit is contained in:
Ty Lamontagne
2023-01-27 01:34:52 -05:00
parent 8892e26cf2
commit 0deef03c3d
5 changed files with 138 additions and 0 deletions

25
tlbrefill/Makefile Executable file
View File

@@ -0,0 +1,25 @@
EE_BIN= tlbrefill.elf
EE_OBJS = tlbrefill.o tlbrefillhandler.o
EE_CFLAGS = -Wall -O3
all: $(EE_BIN)
clean:
rm -f $(EE_OBJS) $(EE_BIN)
run: $(EE_BIN)
ps2client execee host:$(EE_BIN)
wsl: $(EE_BIN)
$(PCSX2) -elf "$(shell wslpath -w $(shell pwd))/$(EE_BIN)"
emu: $(EE_BIN)
$(PCSX2) -elf "$(shell pwd)/$(EE_BIN)"
reset:
ps2client reset
ps2client netdump
include $(PS2SDK)/samples/Makefile.pref
include $(PS2SDK)/samples/Makefile.eeglobal

27
tlbrefill/README.md Executable file
View File

@@ -0,0 +1,27 @@
# TLBREFILL
## Description
Creates a TLB store refill handler and causes a miss. Logging the EPC and BadVAddr COP0 registers.
In the future, it might be better to log the entire COP0 register states.
## PCSX2 Behaviour
The recompiler does not call the refill handlers and will continue emulation until a TLB exception messages threshold was met.
The interpreter will call the proper refill handler.
## Related PR(s) or Issue(s)
n/a
## Expected Results
```
TLB Refill handler test running
TLB handler test completed
Expected EPC: +-0x119ad0
Returned EPC: 0x119ad0
Expected BadVAddr: 0x123
Returned BadVAddr: 0x123
TLB Refill handler test completed
```

62
tlbrefill/tlbrefill.c Executable file
View File

@@ -0,0 +1,62 @@
#include <debug.h>
#include <kernel.h>
#include <stdio.h>
#include <sio.h>
// Network based logging does not work for me
// So I'll provide both network and ee-sio logs
void dbgmsg(const char* fmt, ...)
{
char buf[256];
va_list ap;
va_start(ap, fmt);
vsnprintf(buf, 256, fmt, ap);
vprintf(buf,ap);
va_end(ap);
sio_puts(buf);
}
void tlbRefillHandler();
void* tlbRefillEPC = 0;
void* tlbRefillBadVAddr = 0;
__attribute__ ((__noinline__))
void * get_pc () { return __builtin_return_address(0); }
int main(void)
{
dbgmsg("TLB Refill handler test running\n");
// Disable interrupts, don't risk having our handler called unintentionally
DIntr();
// Replace the existing TLB refill handler
// (3) -> Store
// (2) -> Load
void* prevVTLBRefillHandler = GetExceptionHandler(3);
SetVTLBRefillHandler(3, (void*)tlbRefillHandler);
// Cause a TLB store miss
asm("nop":::"memory");
volatile u8* badAddress = (volatile u8*)0x123;
void* exceptionPC = get_pc() + 8;
*badAddress = ~1;
asm("nop":::"memory");
// Restore the previous TLB refill handler
SetVTLBRefillHandler(3, prevVTLBRefillHandler);
EIntr();
dbgmsg(
"TLB handler test completed\n"
" Expected EPC: +-%p\n"
" Returned EPC: %p\n"
" Expected BadVAddr: %p\n"
" Returned BadVAddr: %p\n",
exceptionPC, tlbRefillEPC,
(void*)badAddress, tlbRefillBadVAddr
);
dbgmsg("TLB Refill handler test completed\n");
SleepThread();
}

BIN
tlbrefill/tlbrefill.elf Executable file

Binary file not shown.

24
tlbrefill/tlbrefillhandler.S Executable file
View File

@@ -0,0 +1,24 @@
.text
.set noreorder
.global tlbRefillHandler
.global tlbRefillEPC
.global tlbRefillBadVAddr
.ent tlbRefillHandler
tlbRefillHandler:
mfc0 $k0, $8 # Fetch BadVAddr
sync.p
sw $k0, tlbRefillBadVAddr
mfc0 $k0, $14 # Fetch EPC
sync.p
sw $k0, tlbRefillEPC
addi $k0, $k0, 4 # Skip to the instruction after our bad store
mtc0 $k0, $14 # Set EPC
sync.p
eret # Exit this handler
nop
.end tlbRefillHandler