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);
|
||||
if(verbose) Console.WriteLn(L"(GameDB) %s Gamefix: " + key, enableIt ? L"Enabled" : L"Disabled" );
|
||||
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));
|
||||
}
|
||||
|
||||
__fi u32 vtlb_V2P(u32 vaddr)
|
||||
{
|
||||
u32 paddr = vtlbdata.ppmap[vaddr>>VTLB_PAGE_BITS];
|
||||
paddr |= vaddr & VTLB_PAGE_MASK;
|
||||
return paddr;
|
||||
}
|
||||
|
||||
//virtual mappings
|
||||
//TODO: Add invalid paddr checks
|
||||
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;
|
||||
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;
|
||||
paddr += VTLB_PAGE_SIZE;
|
||||
size -= VTLB_PAGE_SIZE;
|
||||
|
@ -630,6 +641,7 @@ void vtlb_VMapBuffer(u32 vaddr,void* buffer,u32 size)
|
|||
size -= VTLB_PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
void vtlb_VMapUnmap(u32 vaddr,u32 size)
|
||||
{
|
||||
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
|
||||
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();
|
||||
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()
|
||||
{
|
||||
safe_aligned_free( vtlbdata.vmap );
|
||||
safe_aligned_free( vtlbdata.ppmap );
|
||||
}
|
||||
|
||||
static wxString GetHostVmErrorMsg()
|
||||
|
|
|
@ -39,6 +39,7 @@ typedef u32 vtlbHandler;
|
|||
|
||||
extern void vtlb_Core_Alloc();
|
||||
extern void vtlb_Core_Free();
|
||||
extern void vtlb_Alloc_Ppmap();
|
||||
extern void vtlb_Init();
|
||||
extern void vtlb_Reset();
|
||||
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_GetPhyPtr(u32 paddr);
|
||||
//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
|
||||
extern void vtlb_VMap(u32 vaddr,u32 paddr,u32 sz);
|
||||
|
@ -194,9 +197,11 @@ namespace vtlb_private
|
|||
// third indexer -- 128 possible handlers!
|
||||
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()
|
||||
{
|
||||
|
|
|
@ -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