mirror of https://github.com/PCSX2/pcsx2.git
pcsx2:tlb: extend goemon gamefix
Add GoemonUnloadTlb function that invalidate TLB cache. Currently the function is only used on the interpreter. It fixes TLB error after a reload of data. Next step: porting to the recompiler
This commit is contained in:
parent
8d8aa87457
commit
2cfbc6e5ef
|
@ -254,6 +254,11 @@ void J()
|
|||
|
||||
void JAL()
|
||||
{
|
||||
// 0x3563b8 is the start address of the function that invalidate entry in TLB cache
|
||||
if (EmuConfig.Gamefixes.GoemonTlbHack) {
|
||||
if (_JumpTarget_ == 0x3563b8)
|
||||
GoemonUnloadTlb(cpuRegs.GPR.n.a0.UL[0]);
|
||||
}
|
||||
_SetLink(31);
|
||||
doBranch(_JumpTarget_);
|
||||
}
|
||||
|
@ -456,8 +461,9 @@ void BGEZALL() // Branch if Rs >= 0 and link
|
|||
void JR()
|
||||
{
|
||||
// 0x33ad48 is the return address of the function that populate the TLB cache
|
||||
if (cpuRegs.GPR.r[_Rs_].UL[0] == 0x33ad48 && EmuConfig.Gamefixes.GoemonTlbHack) {
|
||||
GoemonPreloadTlb();
|
||||
if (EmuConfig.Gamefixes.GoemonTlbHack) {
|
||||
if (cpuRegs.GPR.r[_Rs_].UL[0] == 0x33ad48)
|
||||
GoemonPreloadTlb();
|
||||
}
|
||||
doBranch(cpuRegs.GPR.r[_Rs_].UL[0]);
|
||||
}
|
||||
|
|
|
@ -430,6 +430,7 @@ extern void cpuTlbMissW(u32 addr, u32 bd);
|
|||
extern void cpuTestHwInts();
|
||||
extern void cpuClearInt(uint n);
|
||||
extern void __fastcall GoemonPreloadTlb();
|
||||
extern void __fastcall GoemonUnloadTlb(u32 key);
|
||||
|
||||
extern void cpuSetNextEvent( u32 startCycle, s32 delta );
|
||||
extern void cpuSetNextEventDelta( s32 delta );
|
||||
|
|
|
@ -339,7 +339,7 @@ static void GoemonTlbMissDebug()
|
|||
|
||||
for (u32 i = 0; i < 150; i++) {
|
||||
if (tlb[i].valid == 0x1 && tlb[i].low_add != tlb[i].high_add)
|
||||
DevCon.WriteLn("Entry %d is valid. From V:0x%8.8x to V:0x%8.8x (P:0x%8.8x)", i, tlb[i].low_add, tlb[i].high_add, tlb[i].physical_add);
|
||||
DevCon.WriteLn("GoemonTlbMissDebug: Entry %d is valid. Key %x. From V:0x%8.8x to V:0x%8.8x (P:0x%8.8x)", i, tlb[i].key, tlb[i].low_add, tlb[i].high_add, tlb[i].physical_add);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -356,7 +356,7 @@ void __fastcall GoemonPreloadTlb()
|
|||
u32 paddr = tlb[i].physical_add;
|
||||
|
||||
if ((uptr)vtlbdata.vmap[vaddr>>VTLB_PAGE_BITS] == POINTER_SIGN_BIT) {
|
||||
DevCon.WriteLn("Preload TLB[%d]: From V:0x%8.8x to P:0x%8.8x (%d pages)", i, vaddr, paddr, size >> VTLB_PAGE_BITS);
|
||||
DevCon.WriteLn("GoemonPreloadTlb: Entry %d. Key %x. From V:0x%8.8x to P:0x%8.8x (%d pages)", i, tlb[i].key, vaddr, paddr, size >> VTLB_PAGE_BITS);
|
||||
vtlb_VMap( vaddr , paddr, size);
|
||||
vtlb_VMap(0x20000000|vaddr , paddr, size);
|
||||
}
|
||||
|
@ -364,6 +364,33 @@ void __fastcall GoemonPreloadTlb()
|
|||
}
|
||||
}
|
||||
|
||||
void __fastcall GoemonUnloadTlb(u32 key)
|
||||
{
|
||||
// 0x3d5580 is the address of the TLB cache table
|
||||
GoemonTlb* tlb = (GoemonTlb*)&eeMem->Main[0x3d5580];
|
||||
for (u32 i = 0; i < 150; i++) {
|
||||
if (tlb[i].key == key) {
|
||||
if (tlb[i].valid == 0x1) {
|
||||
DevCon.WriteLn("GoemonUnloadTlb: Entry %d. Key %x. From V:0x%8.8x to V:0x%8.8x (P:0x%8.8x)", i, tlb[i].key, tlb[i].low_add, tlb[i].high_add, tlb[i].physical_add);
|
||||
u32 size = tlb[i].high_add - tlb[i].low_add;
|
||||
u32 vaddr = tlb[i].low_add;
|
||||
|
||||
vtlb_VMapUnmap( vaddr , size);
|
||||
vtlb_VMapUnmap(0x20000000|vaddr , size);
|
||||
|
||||
// Unmap the tlb in game cache table
|
||||
// Note: Game copy FEFEFEFE for others data
|
||||
tlb[i].valid = 0;
|
||||
tlb[i].key = 0xFEFEFEFE;
|
||||
tlb[i].low_add = 0xFEFEFEFE;
|
||||
tlb[i].high_add = 0xFEFEFEFE;
|
||||
} else {
|
||||
DevCon.Error("GoemonUnloadTlb: Entry is not valid");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generates a tlbMiss Exception
|
||||
static __ri void vtlb_Miss(u32 addr,u32 mode)
|
||||
{
|
||||
|
|
|
@ -225,6 +225,6 @@ struct GoemonTlb {
|
|||
u32 physical_add;
|
||||
u32 unk3; // likely the size
|
||||
u32 high_add;
|
||||
u32 unk4;
|
||||
u32 key; // uniq number attached to an allocation
|
||||
u32 unk5;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue