mirror of https://github.com/PCSX2/pcsx2.git
pcsx2: tlb: add a new lut (Virtual PS2 to Physical PS2)
note: automatic gamefixes are done after done after the init that why code was splitted. note2: The LUT is 4MB and only used for only 1 game. So I only allocate it when the gamefix is enabled
This commit is contained in:
parent
2e8f56fc86
commit
9452444a9f
|
@ -277,6 +277,10 @@ static int loadGameSettings(Pcsx2Config& dest, const Game_Data& game, bool verbo
|
||||||
dest.Gamefixes.Set(id, enableIt);
|
dest.Gamefixes.Set(id, enableIt);
|
||||||
if(verbose) Console.WriteLn(L"(GameDB) %s Gamefix: " + key, enableIt ? L"Enabled" : L"Disabled" );
|
if(verbose) Console.WriteLn(L"(GameDB) %s Gamefix: " + key, enableIt ? L"Enabled" : L"Disabled" );
|
||||||
gf++;
|
gf++;
|
||||||
|
|
||||||
|
// The LUT is only used for 1 game so we allocate it only when the gamefix is enabled (save 4MB)
|
||||||
|
if (id == Fix_GoemonTlbMiss && enableIt)
|
||||||
|
vtlb_Alloc_Ppmap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -583,6 +583,13 @@ __fi void* vtlb_GetPhyPtr(u32 paddr)
|
||||||
return reinterpret_cast<void*>(vtlbdata.pmap[paddr>>VTLB_PAGE_BITS]+(paddr&VTLB_PAGE_MASK));
|
return reinterpret_cast<void*>(vtlbdata.pmap[paddr>>VTLB_PAGE_BITS]+(paddr&VTLB_PAGE_MASK));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__fi u32 vtlb_V2P(u32 vaddr)
|
||||||
|
{
|
||||||
|
u32 paddr = vtlbdata.ppmap[vaddr>>VTLB_PAGE_BITS];
|
||||||
|
paddr |= vaddr & VTLB_PAGE_MASK;
|
||||||
|
return paddr;
|
||||||
|
}
|
||||||
|
|
||||||
//virtual mappings
|
//virtual mappings
|
||||||
//TODO: Add invalid paddr checks
|
//TODO: Add invalid paddr checks
|
||||||
void vtlb_VMap(u32 vaddr,u32 paddr,u32 size)
|
void vtlb_VMap(u32 vaddr,u32 paddr,u32 size)
|
||||||
|
@ -610,6 +617,10 @@ void vtlb_VMap(u32 vaddr,u32 paddr,u32 size)
|
||||||
}
|
}
|
||||||
|
|
||||||
vtlbdata.vmap[vaddr>>VTLB_PAGE_BITS] = pme-vaddr;
|
vtlbdata.vmap[vaddr>>VTLB_PAGE_BITS] = pme-vaddr;
|
||||||
|
if (vtlbdata.ppmap)
|
||||||
|
if (!(vaddr & 0x80000000)) // those address are already physical don't change them
|
||||||
|
vtlbdata.ppmap[vaddr>>VTLB_PAGE_BITS] = paddr & ~VTLB_PAGE_MASK;
|
||||||
|
|
||||||
vaddr += VTLB_PAGE_SIZE;
|
vaddr += VTLB_PAGE_SIZE;
|
||||||
paddr += VTLB_PAGE_SIZE;
|
paddr += VTLB_PAGE_SIZE;
|
||||||
size -= VTLB_PAGE_SIZE;
|
size -= VTLB_PAGE_SIZE;
|
||||||
|
@ -630,6 +641,7 @@ void vtlb_VMapBuffer(u32 vaddr,void* buffer,u32 size)
|
||||||
size -= VTLB_PAGE_SIZE;
|
size -= VTLB_PAGE_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vtlb_VMapUnmap(u32 vaddr,u32 size)
|
void vtlb_VMapUnmap(u32 vaddr,u32 size)
|
||||||
{
|
{
|
||||||
verify(0==(vaddr&VTLB_PAGE_MASK));
|
verify(0==(vaddr&VTLB_PAGE_MASK));
|
||||||
|
@ -688,6 +700,10 @@ void vtlb_Init()
|
||||||
//yeah i know, its stupid .. but this code has to be here for now ;p
|
//yeah i know, its stupid .. but this code has to be here for now ;p
|
||||||
vtlb_VMapUnmap((VTLB_VMAP_ITEMS-1)*VTLB_PAGE_SIZE,VTLB_PAGE_SIZE);
|
vtlb_VMapUnmap((VTLB_VMAP_ITEMS-1)*VTLB_PAGE_SIZE,VTLB_PAGE_SIZE);
|
||||||
|
|
||||||
|
// The LUT is only used for 1 game so we allocate it only when the gamefix is enabled (save 4MB)
|
||||||
|
if (EmuConfig.Gamefixes.GoemonTlbHack)
|
||||||
|
vtlb_Alloc_Ppmap();
|
||||||
|
|
||||||
extern void vtlb_dynarec_init();
|
extern void vtlb_dynarec_init();
|
||||||
vtlb_dynarec_init();
|
vtlb_dynarec_init();
|
||||||
}
|
}
|
||||||
|
@ -720,9 +736,26 @@ void vtlb_Core_Alloc()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The LUT is only used for 1 game so we allocate it only when the gamefix is enabled (save 4MB)
|
||||||
|
// However automatic gamefix is done after the standard init so a new init function was done.
|
||||||
|
void vtlb_Alloc_Ppmap()
|
||||||
|
{
|
||||||
|
if (vtlbdata.ppmap) return;
|
||||||
|
|
||||||
|
vtlbdata.ppmap = (u32*)_aligned_malloc( VTLB_VMAP_ITEMS * sizeof(*vtlbdata.ppmap), 16 );
|
||||||
|
if (!vtlbdata.ppmap)
|
||||||
|
throw Exception::OutOfMemory( L"VTLB PS2 Virtual Address Translation LUT" )
|
||||||
|
.SetDiagMsg(pxsFmt("(%u megs)", VTLB_VMAP_ITEMS * sizeof(*vtlbdata.ppmap) / _1mb));
|
||||||
|
|
||||||
|
// By default a 1:1 virtual to physical mapping
|
||||||
|
for (u32 i = 0; i < VTLB_VMAP_ITEMS; i++)
|
||||||
|
vtlbdata.ppmap[i] = i<<VTLB_PAGE_BITS;
|
||||||
|
}
|
||||||
|
|
||||||
void vtlb_Core_Free()
|
void vtlb_Core_Free()
|
||||||
{
|
{
|
||||||
safe_aligned_free( vtlbdata.vmap );
|
safe_aligned_free( vtlbdata.vmap );
|
||||||
|
safe_aligned_free( vtlbdata.ppmap );
|
||||||
}
|
}
|
||||||
|
|
||||||
static wxString GetHostVmErrorMsg()
|
static wxString GetHostVmErrorMsg()
|
||||||
|
|
|
@ -39,6 +39,7 @@ typedef u32 vtlbHandler;
|
||||||
|
|
||||||
extern void vtlb_Core_Alloc();
|
extern void vtlb_Core_Alloc();
|
||||||
extern void vtlb_Core_Free();
|
extern void vtlb_Core_Free();
|
||||||
|
extern void vtlb_Alloc_Ppmap();
|
||||||
extern void vtlb_Init();
|
extern void vtlb_Init();
|
||||||
extern void vtlb_Reset();
|
extern void vtlb_Reset();
|
||||||
extern void vtlb_Term();
|
extern void vtlb_Term();
|
||||||
|
@ -61,6 +62,8 @@ extern void vtlb_MapHandler(vtlbHandler handler,u32 start,u32 size);
|
||||||
extern void vtlb_MapBlock(void* base,u32 start,u32 size,u32 blocksize=0);
|
extern void vtlb_MapBlock(void* base,u32 start,u32 size,u32 blocksize=0);
|
||||||
extern void* vtlb_GetPhyPtr(u32 paddr);
|
extern void* vtlb_GetPhyPtr(u32 paddr);
|
||||||
//extern void vtlb_Mirror(u32 new_region,u32 start,u32 size); // -> not working yet :(
|
//extern void vtlb_Mirror(u32 new_region,u32 start,u32 size); // -> not working yet :(
|
||||||
|
extern u32 vtlb_V2P(u32 vaddr);
|
||||||
|
extern void vtlb_DynV2P();
|
||||||
|
|
||||||
//virtual mappings
|
//virtual mappings
|
||||||
extern void vtlb_VMap(u32 vaddr,u32 paddr,u32 sz);
|
extern void vtlb_VMap(u32 vaddr,u32 paddr,u32 sz);
|
||||||
|
@ -194,9 +197,11 @@ namespace vtlb_private
|
||||||
// third indexer -- 128 possible handlers!
|
// third indexer -- 128 possible handlers!
|
||||||
void* RWFT[5][2][VTLB_HANDLER_ITEMS];
|
void* RWFT[5][2][VTLB_HANDLER_ITEMS];
|
||||||
|
|
||||||
s32 pmap[VTLB_PMAP_ITEMS]; //512KB
|
s32 pmap[VTLB_PMAP_ITEMS]; //512KB // PS2 physical to x86 physical
|
||||||
|
|
||||||
s32* vmap; //4MB (allocated by vtlb_init)
|
s32* vmap; //4MB (allocated by vtlb_init) // PS2 virtual to x86 physical
|
||||||
|
|
||||||
|
u32* ppmap; //4MB (allocated by vtlb_init) // PS2 virtual to PS2 physical
|
||||||
|
|
||||||
MapData()
|
MapData()
|
||||||
{
|
{
|
||||||
|
|
|
@ -557,3 +557,18 @@ void vtlb_DynGenWrite_Const( u32 bits, u32 addr_const )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Extra Implementations
|
||||||
|
|
||||||
|
// ecx - virtual address
|
||||||
|
// Returns physical address in eax.
|
||||||
|
void vtlb_DynV2P()
|
||||||
|
{
|
||||||
|
xMOV(eax, ecx);
|
||||||
|
xAND(ecx, VTLB_PAGE_MASK); // vaddr & VTLB_PAGE_MASK
|
||||||
|
|
||||||
|
xSHR(eax, VTLB_PAGE_BITS);
|
||||||
|
xMOV(eax, ptr[(eax*4) + vtlbdata.ppmap]); //vtlbdata.ppmap[vaddr>>VTLB_PAGE_BITS];
|
||||||
|
|
||||||
|
xOR(eax, ecx);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue