From 239c9f83d8d94a6f1fb5a2c25d98c4773ffca1da Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Tue, 16 Nov 2010 00:22:18 +0000 Subject: [PATCH] newHostVM: (Restored booting) - * Added some bounds checking to debug builds for VTLB mappings. * Fixed a VU mapping bug that caused boot crashing * Fixed some startup, shutdown, and reset resource management. git-svn-id: http://pcsx2.googlecode.com/svn/branches/newHostVM@4021 96395faa-99c1-11dd-bbfe-3dabce05a288 --- common/include/Utilities/PageFaultSource.h | 6 +- pcsx2/CMakeLists.txt | 1 - pcsx2/IopMem.cpp | 4 +- pcsx2/Linux/pcsx2.cbp | 1 - pcsx2/Memory.cpp | 2 +- pcsx2/System.cpp | 26 ++++--- pcsx2/System.h | 16 ++--- pcsx2/System/SysCoreThread.cpp | 2 +- pcsx2/VUmicroMem.cpp | 8 +-- pcsx2/vtlb.cpp | 79 ++++++++++++---------- pcsx2/vtlb.h | 16 ++--- pcsx2/x86/microVU_Misc.inl | 2 +- 12 files changed, 88 insertions(+), 75 deletions(-) diff --git a/common/include/Utilities/PageFaultSource.h b/common/include/Utilities/PageFaultSource.h index ce16f63aa6..07ea665d06 100644 --- a/common/include/Utilities/PageFaultSource.h +++ b/common/include/Utilities/PageFaultSource.h @@ -57,7 +57,6 @@ public: pxFailRel( "Don't call me, damnit. Use DispatchException instead." ); } -protected: virtual void OnPageFaultEvent( const PageFaultInfo& evtinfo, bool& handled ) {} }; @@ -93,7 +92,7 @@ public: protected: virtual void OnPageFaultEvent( const PageFaultInfo& info, bool& handled ) { - OnPageFaultEvent( info, handled ); + Owner->OnPageFaultEvent( info, handled ); } }; @@ -230,9 +229,10 @@ public: using _parent::operator[]; -protected: void OnPageFaultEvent( const PageFaultInfo& info, bool& handled ); +protected: + // This function is called from OnPageFaultEvent after the address has been translated // and confirmed to apply to this reserved area in question. OnPageFaultEvent contains // a try/catch exception handler, which ensures "reasonable" error response behavior if diff --git a/pcsx2/CMakeLists.txt b/pcsx2/CMakeLists.txt index fac53faafc..82957bf97c 100644 --- a/pcsx2/CMakeLists.txt +++ b/pcsx2/CMakeLists.txt @@ -383,7 +383,6 @@ set(pcsx2IPUHeaders # Linux sources set(pcsx2LinuxSources - Linux/LnxHostSys.cpp Linux/LnxKeyCodes.cpp) # Linux headers diff --git a/pcsx2/IopMem.cpp b/pcsx2/IopMem.cpp index 00b619378a..be31cf2b4b 100644 --- a/pcsx2/IopMem.cpp +++ b/pcsx2/IopMem.cpp @@ -99,9 +99,9 @@ void iopMemoryReserve::Reset() //for (i=0; i<0x0008; i++) psxMemWLUT[i + 0xbfc0] = (uptr)&psR[i << 16]; } -void iopMemoryReserve::Shutdown() +void iopMemoryReserve::Decommit() { - _parent::Shutdown(); + _parent::Decommit(); safe_aligned_free(psxMemWLUT); psxMemRLUT = NULL; diff --git a/pcsx2/Linux/pcsx2.cbp b/pcsx2/Linux/pcsx2.cbp index 0de2bb31c6..d3855a71c4 100644 --- a/pcsx2/Linux/pcsx2.cbp +++ b/pcsx2/Linux/pcsx2.cbp @@ -317,7 +317,6 @@ - diff --git a/pcsx2/Memory.cpp b/pcsx2/Memory.cpp index 415ca979f7..0b0965873c 100644 --- a/pcsx2/Memory.cpp +++ b/pcsx2/Memory.cpp @@ -579,7 +579,7 @@ void memClearPageAddr(u32 vaddr) class mmap_PageFaultHandler : public EventListener_PageFault { -protected: +public: void OnPageFaultEvent( const PageFaultInfo& info, bool& handled ); }; diff --git a/pcsx2/System.cpp b/pcsx2/System.cpp index b922787d20..400fb27738 100644 --- a/pcsx2/System.cpp +++ b/pcsx2/System.cpp @@ -339,7 +339,6 @@ SysMainMemory::SysMainMemory() SysMainMemory::~SysMainMemory() throw() { - ShutdownAll(); ReleaseAll(); } @@ -356,6 +355,7 @@ void SysMainMemory::ReserveAll() void SysMainMemory::CommitAll() { + vtlb_Core_Alloc(); if (m_ee.IsCommitted() && m_iop.IsCommitted() && m_vu.IsCommitted()) return; DevCon.WriteLn( "PS2vm: Allocating host memory for all virtual systems..." ); @@ -377,22 +377,30 @@ void SysMainMemory::ResetAll() m_vu.Reset(); } -void SysMainMemory::ShutdownAll() +void SysMainMemory::DecommitAll() { - Console.WriteLn( "PS2vm: Shutting down host memory for all virtual systems..." ); + if (!m_ee.IsCommitted() && !m_iop.IsCommitted() && !m_vu.IsCommitted()) return; - m_ee.Shutdown(); - m_iop.Shutdown(); - m_vu.Shutdown(); + Console.WriteLn( "PS2vm: Decommitting host memory for all virtual systems..." ); + + m_ee.Decommit(); + m_iop.Decommit(); + m_vu.Decommit(); + + vtlb_Core_Free(); } void SysMainMemory::ReleaseAll() { + DecommitAll(); + Console.WriteLn( "PS2vm: Releasing host memory maps for all virtual systems..." ); - m_ee.Shutdown(); - m_iop.Shutdown(); - m_vu.Shutdown(); + vtlb_Core_Free(); // Just to be sure... (calling order could result in it getting missed during Decommit). + + m_ee.Decommit(); + m_iop.Decommit(); + m_vu.Decommit(); safe_delete(Source_PageFault); } diff --git a/pcsx2/System.h b/pcsx2/System.h index 00a92f88da..dd34f0f117 100644 --- a/pcsx2/System.h +++ b/pcsx2/System.h @@ -47,25 +47,25 @@ namespace HostMemoryMap static const uptr sVU1rec = _256mb - (_8mb*2); // PS2 main memory, SPR, and ROMs - static const uptr EEmem = 0x30000000; + static const uptr EEmem = 0x20000000; // IOP main memory and ROMs - static const uptr IOPmem = 0x34000000; + static const uptr IOPmem = 0x24000000; // VU0 and VU1 memory. - static const uptr VUmem = 0x38000000; + static const uptr VUmem = 0x28000000; // EE recompiler code cache area (64mb) - static const uptr EErec = 0x40000000; + static const uptr EErec = 0x30000000; // IOP recompiler code cache area (16 or 32mb) - static const uptr IOPrec = 0x44000000; + static const uptr IOPrec = 0x34000000; // microVU1 recompiler code cache area (32 or 64mb) - static const uptr mVU0rec = 0x48000000; + static const uptr mVU0rec = 0x38000000; // microVU0 recompiler code cache area (64mb) - static const uptr mVU1rec = 0x50000000; + static const uptr mVU1rec = 0x40000000; } // -------------------------------------------------------------------------------------- @@ -86,7 +86,7 @@ public: virtual void ReserveAll(); virtual void CommitAll(); virtual void ResetAll(); - virtual void ShutdownAll(); + virtual void DecommitAll(); virtual void ReleaseAll(); }; diff --git a/pcsx2/System/SysCoreThread.cpp b/pcsx2/System/SysCoreThread.cpp index 4c28750d44..d52b89866c 100644 --- a/pcsx2/System/SysCoreThread.cpp +++ b/pcsx2/System/SysCoreThread.cpp @@ -124,7 +124,7 @@ void SysCoreThread::ResetQuick() void SysCoreThread::Reset() { ResetQuick(); - GetVmMemory().ShutdownAll(); + GetVmMemory().DecommitAll(); SysClearExecutionCache(); } diff --git a/pcsx2/VUmicroMem.cpp b/pcsx2/VUmicroMem.cpp index 5eea6ec73c..70c2f9643a 100644 --- a/pcsx2/VUmicroMem.cpp +++ b/pcsx2/VUmicroMem.cpp @@ -33,10 +33,10 @@ void vuMemoryReserve::Reserve() //_parent::Reserve(EmuConfig.HostMemMap.VUmem); u8* curpos = m_reserve.GetPtr(); - VU0.Micro = curpos; curpos += 0x1000; - VU0.Mem = curpos; curpos += 0x4000; - VU1.Micro = curpos; curpos += 0x4000; - VU1.Mem = curpos; + VU0.Micro = curpos; curpos += VU0_PROGSIZE; + VU0.Mem = curpos; curpos += VU0_MEMSIZE; + VU1.Micro = curpos; curpos += VU1_PROGSIZE; + VU1.Mem = curpos; curpos += VU1_MEMSIZE; } void vuMemoryReserve::Release() diff --git a/pcsx2/vtlb.cpp b/pcsx2/vtlb.cpp index fb4fd2f37a..a0df4ba944 100644 --- a/pcsx2/vtlb.cpp +++ b/pcsx2/vtlb.cpp @@ -148,9 +148,9 @@ void __fastcall vtlb_memWrite(u32 addr, DataType data) switch( DataSize ) { - case 8: return ((vtlbMemW8FP*)vtlbdata.RWFT[0][1][hand])(paddr, (u8)data); - case 16: return ((vtlbMemW16FP*)vtlbdata.RWFT[1][1][hand])(paddr, (u16)data); - case 32: return ((vtlbMemW32FP*)vtlbdata.RWFT[2][1][hand])(paddr, (u32)data); + case 8: return ((vtlbMemW8FP*)vtlbdata.RWFT[0][1][hand])(paddr, (u8)data); + case 16: return ((vtlbMemW16FP*)vtlbdata.RWFT[1][1][hand])(paddr, (u16)data); + case 32: return ((vtlbMemW32FP*)vtlbdata.RWFT[2][1][hand])(paddr, (u32)data); jNO_DEFAULT; } @@ -378,24 +378,25 @@ __ri vtlbHandler vtlb_RegisterHandler( vtlbMemR8FP* r8,vtlbMemR16FP* r16,vtlbMem // function. // // The memory region start and size parameters must be pagesize aligned. -void vtlb_MapHandler(vtlbHandler handler,u32 start,u32 size) +void vtlb_MapHandler(vtlbHandler handler, u32 start, u32 size) { verify(0==(start&VTLB_PAGE_MASK)); verify(0==(size&VTLB_PAGE_MASK) && size>0); - s32 value=handler|0x80000000; - while(size>0) + s32 value = handler | 0x80000000; + u32 end = start + (size - VTLB_PAGE_SIZE); + pxAssume( (end>>VTLB_PAGE_BITS) < ArraySize(vtlbdata.pmap) ); + + while (start <= end) { - vtlbdata.pmap[start>>VTLB_PAGE_BITS]=value; - - start+=VTLB_PAGE_SIZE; - size-=VTLB_PAGE_SIZE; + vtlbdata.pmap[start>>VTLB_PAGE_BITS] = value; + start += VTLB_PAGE_SIZE; } } -void vtlb_MapBlock(void* base,u32 start,u32 size,u32 blocksize) +void vtlb_MapBlock(void* base, u32 start, u32 size, u32 blocksize) { - s32 baseint=(s32)base; + s32 baseint = (s32)base; verify(0==(start&VTLB_PAGE_MASK)); verify(0==(size&VTLB_PAGE_MASK) && size>0); @@ -404,19 +405,21 @@ void vtlb_MapBlock(void* base,u32 start,u32 size,u32 blocksize) verify(0==(blocksize&VTLB_PAGE_MASK) && blocksize>0); verify(0==(size%blocksize)); - while(size>0) + u32 end = start + (size - VTLB_PAGE_SIZE); + pxAssume( (end>>VTLB_PAGE_BITS) < ArraySize(vtlbdata.pmap) ); + + while (start <= end) { - u32 blocksz=blocksize; - s32 ptr=baseint; + u32 loopsz = blocksize; + s32 ptr = baseint; - while(blocksz>0) + while (loopsz > 0) { - vtlbdata.pmap[start>>VTLB_PAGE_BITS]=ptr; + vtlbdata.pmap[start>>VTLB_PAGE_BITS] = ptr; - start+=VTLB_PAGE_SIZE; - ptr+=VTLB_PAGE_SIZE; - blocksz-=VTLB_PAGE_SIZE; - size-=VTLB_PAGE_SIZE; + start += VTLB_PAGE_SIZE; + ptr += VTLB_PAGE_SIZE; + loopsz -= VTLB_PAGE_SIZE; } } } @@ -427,13 +430,15 @@ void vtlb_Mirror(u32 new_region,u32 start,u32 size) verify(0==(start&VTLB_PAGE_MASK)); verify(0==(size&VTLB_PAGE_MASK) && size>0); - while(size>0) - { - vtlbdata.pmap[start>>VTLB_PAGE_BITS]=vtlbdata.pmap[new_region>>VTLB_PAGE_BITS]; + u32 end = start + (size-VTLB_PAGE_SIZE); + pxAssume( (end>>VTLB_PAGE_BITS) < ArraySize(vtlbdata.pmap) ); - start+=VTLB_PAGE_SIZE; - new_region+=VTLB_PAGE_SIZE; - size-=VTLB_PAGE_SIZE; + while(start <= end) + { + vtlbdata.pmap[start>>VTLB_PAGE_BITS] = vtlbdata.pmap[new_region>>VTLB_PAGE_BITS]; + + start += VTLB_PAGE_SIZE; + new_region += VTLB_PAGE_SIZE; } } @@ -470,6 +475,7 @@ void vtlb_VMap(u32 vaddr,u32 paddr,u32 sz) if (pme<0) pme|=paddr;// top bit is set anyway ... } + vtlbdata.vmap[vaddr>>VTLB_PAGE_BITS]=pme-vaddr; vaddr+=VTLB_PAGE_SIZE; paddr+=VTLB_PAGE_SIZE; @@ -568,11 +574,14 @@ void vtlb_Term() // default is used. void vtlb_Core_Alloc() { - vtlbdata.vmap = (s32*)_aligned_malloc( VTLB_VMAP_ITEMS * sizeof(*vtlbdata.vmap), 16 ); if (!vtlbdata.vmap) - throw Exception::OutOfMemory( L"VTLB Virtual Address Translation LUT" ) - .SetDiagMsg(pxsFmt("(%u megs)", VTLB_VMAP_ITEMS * sizeof(*vtlbdata.vmap) / _1mb) - ); + { + vtlbdata.vmap = (s32*)_aligned_malloc( VTLB_VMAP_ITEMS * sizeof(*vtlbdata.vmap), 16 ); + if (!vtlbdata.vmap) + throw Exception::OutOfMemory( L"VTLB Virtual Address Translation LUT" ) + .SetDiagMsg(pxsFmt("(%u megs)", VTLB_VMAP_ITEMS * sizeof(*vtlbdata.vmap) / _1mb) + ); + } } void vtlb_Core_Free() @@ -596,7 +605,7 @@ void VtlbMemoryReserve::SetBaseAddr( uptr newaddr ) void VtlbMemoryReserve::Reserve( sptr hostptr ) { - m_reserve.Reserve(); + m_reserve.ReserveAt( hostptr ); if (!m_reserve.IsOk()) throw Exception::OutOfMemory( m_reserve.GetName() ); } @@ -610,13 +619,11 @@ void VtlbMemoryReserve::Commit() void VtlbMemoryReserve::Reset() { - if (!m_reserve.Commit()) - throw Exception::OutOfMemory( m_reserve.GetName() ); - + Commit(); memzero_sse_a(m_reserve.GetPtr(), m_reserve.GetCommittedBytes()); } -void VtlbMemoryReserve::Shutdown() +void VtlbMemoryReserve::Decommit() { m_reserve.Reset(); } diff --git a/pcsx2/vtlb.h b/pcsx2/vtlb.h index 934988d60b..d840643c18 100644 --- a/pcsx2/vtlb.h +++ b/pcsx2/vtlb.h @@ -107,7 +107,7 @@ public: virtual void Commit(); virtual void Reset(); - virtual void Shutdown(); + virtual void Decommit(); virtual void SetBaseAddr( uptr newaddr ); bool IsCommitted() const; @@ -149,7 +149,7 @@ public: void Reserve(); void Release(); void Reset(); - void Shutdown(); + void Decommit(); }; // -------------------------------------------------------------------------------------- @@ -178,8 +178,8 @@ namespace vtlb_private static const uint VTLB_PAGE_MASK = 4095; static const uint VTLB_PAGE_SIZE = 4096; - static const uint VTLB_PMAP_ITEMS = _256mb / VTLB_PAGE_SIZE; - static const uint VTLB_PMAP_SZ = _256mb; + static const uint VTLB_PMAP_SZ = _1mb * 512; + static const uint VTLB_PMAP_ITEMS = VTLB_PMAP_SZ / VTLB_PAGE_SIZE; static const uint VTLB_VMAP_ITEMS = _4gb / VTLB_PAGE_SIZE; struct MapData @@ -193,10 +193,10 @@ namespace vtlb_private s32* vmap; //4MB (allocated by vtlb_init) - u8* reserve_base; //base of the memory array - - u8* alloc_base; //base of the memory array - int alloc_current; //current base + MapData() + { + vmap = NULL; + } }; extern __aligned(64) MapData vtlbdata; diff --git a/pcsx2/x86/microVU_Misc.inl b/pcsx2/x86/microVU_Misc.inl index 285de1d901..1906e47725 100644 --- a/pcsx2/x86/microVU_Misc.inl +++ b/pcsx2/x86/microVU_Misc.inl @@ -251,7 +251,7 @@ __fi void mVUaddrFix(mV, const x32& gprReg) else { if (IsDevBuild && !isCOP2) mVUbackupRegs(mVU, true); xTEST(gprReg, 0x400); - xForwardJNZ8 jmpA; // if addr & 0x4000, reads VU1's VF regs and VI regs + xForwardJNZ8 jmpA; // if addr & 0x4000, reads VU1's VF regs and VI regs xAND(gprReg, 0xff); // if !(addr & 0x4000), wrap around xForwardJump8 jmpB; jmpA.SetTarget();