/[pcsx2_0.9.7]/trunk/pcsx2/vtlb.cpp
ViewVC logotype

Diff of /trunk/pcsx2/vtlb.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

--- trunk/pcsx2/vtlb.cpp	2010/12/23 11:48:33	279
+++ trunk/pcsx2/vtlb.cpp	2010/12/23 12:02:12	280
@@ -33,9 +33,10 @@
 #include "Common.h"
 #include "vtlb.h"
 #include "COP0.h"
-
 #include "R5900Exceptions.h"
 
+#include "Utilities/MemsetFast.inl"
+
 using namespace R5900;
 using namespace vtlb_private;
 
@@ -46,7 +47,7 @@
 	__aligned(64) MapData vtlbdata;
 }
 
-static vtlbHandler vtlbHandlerCount=0;
+static vtlbHandler vtlbHandlerCount = 0;
 
 static vtlbHandler DefaultPhyHandler;
 static vtlbHandler UnmappedVirtHandler0;
@@ -78,9 +79,9 @@
 
 	switch( DataSize )
 	{
-	case 8: return ((vtlbMemR8FP*)vtlbdata.RWFT[0][0][hand])(paddr);
-	case 16: return ((vtlbMemR16FP*)vtlbdata.RWFT[1][0][hand])(paddr);
-	case 32: return ((vtlbMemR32FP*)vtlbdata.RWFT[2][0][hand])(paddr);
+		case 8: return ((vtlbMemR8FP*)vtlbdata.RWFT[0][0][hand])(paddr);
+		case 16: return ((vtlbMemR16FP*)vtlbdata.RWFT[1][0][hand])(paddr);
+		case 32: return ((vtlbMemR32FP*)vtlbdata.RWFT[2][0][hand])(paddr);
 
 		jNO_DEFAULT;
 	}
@@ -147,9 +148,9 @@
 
 		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;
 		}
@@ -255,65 +256,55 @@
 
 static mem8_t __fastcall vtlbDefaultPhyRead8(u32 addr)
 {
-	Console.Error("vtlbDefaultPhyRead8: 0x%08X", addr);
-	pxFailDev("(VTLB) Attempted read from an unmapped physical address.");
+	pxFailDev(pxsFmt("(VTLB) Attempted read8 from unmapped physical address @ 0x%08X.", addr));
 	return 0;
 }
 
 static mem16_t __fastcall vtlbDefaultPhyRead16(u32 addr)
 {
-	Console.Error("vtlbDefaultPhyRead16: 0x%08X", addr);
-	pxFailDev("(VTLB) Attempted read from an unmapped physical address.");
+	pxFailDev(pxsFmt("(VTLB) Attempted read16 from unmapped physical address @ 0x%08X.", addr));
 	return 0;
 }
 
 static mem32_t __fastcall vtlbDefaultPhyRead32(u32 addr)
 {
-	Console.Error("vtlbDefaultPhyRead32: 0x%08X", addr);
-	pxFailDev("(VTLB) Attempted read from an unmapped physical address.");
+	pxFailDev(pxsFmt("(VTLB) Attempted read32 from unmapped physical address @ 0x%08X.", addr));
 	return 0;
 }
 
 static void __fastcall vtlbDefaultPhyRead64(u32 addr, mem64_t* dest)
 {
-	Console.Error("vtlbDefaultPhyRead64: 0x%08X", addr);
-	pxFailDev("(VTLB) Attempted read from an unmapped physical address.");
+	pxFailDev(pxsFmt("(VTLB) Attempted read64 from unmapped physical address @ 0x%08X.", addr));
 }
 
 static void __fastcall vtlbDefaultPhyRead128(u32 addr, mem128_t* dest)
 {
-	Console.Error("vtlbDefaultPhyRead128: 0x%08X", addr);
-	pxFailDev("(VTLB) Attempted read from an unmapped physical address.");
+	pxFailDev(pxsFmt("(VTLB) Attempted read128 from unmapped physical address @ 0x%08X.", addr));
 }
 
 static void __fastcall vtlbDefaultPhyWrite8(u32 addr, mem8_t data)
 {
-	Console.Error("vtlbDefaultPhyWrite8: 0x%08X",addr);
-	pxFailDev("(VTLB) Attempted write to an unmapped physical address.");
+	pxFailDev(pxsFmt("(VTLB) Attempted write8 to unmapped physical address @ 0x%08X.", addr));
 }
 
 static void __fastcall vtlbDefaultPhyWrite16(u32 addr, mem16_t data)
 {
-	Console.Error("vtlbDefaultPhyWrite16: 0x%08X",addr);
-	pxFailDev("(VTLB) Attempted write to an unmapped physical address.");
+	pxFailDev(pxsFmt("(VTLB) Attempted write16 to unmapped physical address @ 0x%08X.", addr));
 }
 
 static void __fastcall vtlbDefaultPhyWrite32(u32 addr, mem32_t data)
 {
-	Console.Error("vtlbDefaultPhyWrite32: 0x%08X",addr);
-	pxFailDev("(VTLB) Attempted write to an unmapped physical address.");
+	pxFailDev(pxsFmt("(VTLB) Attempted write32 to unmapped physical address @ 0x%08X.", addr));
 }
 
 static void __fastcall vtlbDefaultPhyWrite64(u32 addr,const mem64_t* data)
 {
-	Console.Error("vtlbDefaultPhyWrite64: 0x%08X",addr);
-	pxFailDev("(VTLB) Attempted write to an unmapped physical address.");
+	pxFailDev(pxsFmt("(VTLB) Attempted write64 to unmapped physical address @ 0x%08X.", addr));
 }
 
 static void __fastcall vtlbDefaultPhyWrite128(u32 addr,const mem128_t* data)
 {
-	Console.Error("vtlbDefaultPhyWrite128: 0x%08X",addr);
-	pxFailDev("(VTLB) Attempted write to an unmapped physical address.");
+	pxFailDev(pxsFmt("(VTLB) Attempted write128 to unmapped physical address @ 0x%08X.", addr));
 }
 #undef _tmpl
 
@@ -333,6 +324,8 @@
 							   vtlbMemR8FP* r8,vtlbMemR16FP* r16,vtlbMemR32FP* r32,vtlbMemR64FP* r64,vtlbMemR128FP* r128,
 							   vtlbMemW8FP* w8,vtlbMemW16FP* w16,vtlbMemW32FP* w32,vtlbMemW64FP* w64,vtlbMemW128FP* w128 )
 {
+	pxAssume(rv < VTLB_HANDLER_ITEMS);
+
 	vtlbdata.RWFT[0][0][rv] = (void*)((r8!=0)   ? r8	: vtlbDefaultPhyRead8);
 	vtlbdata.RWFT[1][0][rv] = (void*)((r16!=0)  ? r16	: vtlbDefaultPhyRead16);
 	vtlbdata.RWFT[2][0][rv] = (void*)((r32!=0)  ? r32	: vtlbDefaultPhyRead32);
@@ -348,7 +341,7 @@
 
 vtlbHandler vtlb_NewHandler()
 {
-	pxAssertDev( vtlbHandlerCount < 127, "VTLB allowed handler count exceeded!" );
+	pxAssertDev( vtlbHandlerCount < VTLB_HANDLER_ITEMS, "VTLB handler count overflow!" );
 	return vtlbHandlerCount++;
 }
 
@@ -362,7 +355,7 @@
 // Returns a handle for the newly created handler  See vtlb_MapHandler for use of the return value.
 //
 __ri vtlbHandler vtlb_RegisterHandler(	vtlbMemR8FP* r8,vtlbMemR16FP* r16,vtlbMemR32FP* r32,vtlbMemR64FP* r64,vtlbMemR128FP* r128,
-									vtlbMemW8FP* w8,vtlbMemW16FP* w16,vtlbMemW32FP* w32,vtlbMemW64FP* w64,vtlbMemW128FP* w128)
+										vtlbMemW8FP* w8,vtlbMemW16FP* w16,vtlbMemW32FP* w32,vtlbMemW64FP* w64,vtlbMemW128FP* w128)
 {
 	vtlbHandler rv = vtlb_NewHandler();
 	vtlb_ReassignHandler( rv, r8, r16, r32, r64, r128, w8, w16, w32, w64, w128 );
@@ -377,45 +370,47 @@
 // 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)
-	{
-		vtlbdata.pmap[start>>VTLB_PAGE_BITS]=value;
+	s32 value = handler | 0x80000000;
+	u32 end = start + (size - VTLB_PAGE_SIZE);
+	pxAssume( (end>>VTLB_PAGE_BITS) < ArraySize(vtlbdata.pmap) );
 
-		start+=VTLB_PAGE_SIZE;
-		size-=VTLB_PAGE_SIZE;
+	while (start <= end)
+	{
+		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;
-
 	verify(0==(start&VTLB_PAGE_MASK));
 	verify(0==(size&VTLB_PAGE_MASK) && size>0);
-	if (blocksize==0)
-		blocksize=size;
+	if (!blocksize)
+		blocksize = size;
 	verify(0==(blocksize&VTLB_PAGE_MASK) && blocksize>0);
 	verify(0==(size%blocksize));
 
-	while(size>0)
+	s32 baseint = (s32)base;
+	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;
 		}
 	}
 }
@@ -426,13 +421,15 @@
 	verify(0==(start&VTLB_PAGE_MASK));
 	verify(0==(size&VTLB_PAGE_MASK) && size>0);
 
-	while(size>0)
+	u32 end = start + (size-VTLB_PAGE_SIZE);
+	pxAssume( (end>>VTLB_PAGE_BITS) < ArraySize(vtlbdata.pmap) );
+
+	while(start <= end)
 	{
-		vtlbdata.pmap[start>>VTLB_PAGE_BITS]=vtlbdata.pmap[new_region>>VTLB_PAGE_BITS];
+		vtlbdata.pmap[start>>VTLB_PAGE_BITS] = vtlbdata.pmap[new_region>>VTLB_PAGE_BITS];
 
-		start+=VTLB_PAGE_SIZE;
-		new_region+=VTLB_PAGE_SIZE;
-		size-=VTLB_PAGE_SIZE;
+		start		+= VTLB_PAGE_SIZE;
+		new_region	+= VTLB_PAGE_SIZE;
 	}
 }
 
@@ -446,66 +443,70 @@
 
 //virtual mappings
 //TODO: Add invalid paddr checks
-void vtlb_VMap(u32 vaddr,u32 paddr,u32 sz)
+void vtlb_VMap(u32 vaddr,u32 paddr,u32 size)
 {
 	verify(0==(vaddr&VTLB_PAGE_MASK));
 	verify(0==(paddr&VTLB_PAGE_MASK));
-	verify(0==(sz&VTLB_PAGE_MASK) && sz>0);
+	verify(0==(size&VTLB_PAGE_MASK) && size>0);
 
-	while(sz>0)
+	while (size > 0)
 	{
 		s32 pme;
-		if (paddr>=VTLB_PMAP_SZ)
+		if (paddr >= VTLB_PMAP_SZ)
 		{
-			pme=UnmappedPhyHandler0;
-			if (paddr&0x80000000)
-				pme=UnmappedPhyHandler1;
-			pme|=0x80000000;
-			pme|=paddr;// top bit is set anyway ...
+			pme = UnmappedPhyHandler0;
+			if (paddr & 0x80000000)
+				pme = UnmappedPhyHandler1;
+			pme |= 0x80000000;
+			pme |= paddr;// top bit is set anyway ...
 		}
 		else
 		{
-			pme=vtlbdata.pmap[paddr>>VTLB_PAGE_BITS];
+			pme = vtlbdata.pmap[paddr>>VTLB_PAGE_BITS];
 			if (pme<0)
-				pme|=paddr;// top bit is set anyway ...
+				pme |= paddr;// top bit is set anyway ...
 		}
-		vtlbdata.vmap[vaddr>>VTLB_PAGE_BITS]=pme-vaddr;
-		vaddr+=VTLB_PAGE_SIZE;
-		paddr+=VTLB_PAGE_SIZE;
-		sz-=VTLB_PAGE_SIZE;
+
+		vtlbdata.vmap[vaddr>>VTLB_PAGE_BITS] = pme-vaddr;
+		vaddr += VTLB_PAGE_SIZE;
+		paddr += VTLB_PAGE_SIZE;
+		size -= VTLB_PAGE_SIZE;
 	}
 }
 
-void vtlb_VMapBuffer(u32 vaddr,void* buffer,u32 sz)
+void vtlb_VMapBuffer(u32 vaddr,void* buffer,u32 size)
 {
 	verify(0==(vaddr&VTLB_PAGE_MASK));
-	verify(0==(sz&VTLB_PAGE_MASK) && sz>0);
-	u32 bu8=(u32)buffer;
-	while(sz>0)
+	verify(0==(size&VTLB_PAGE_MASK) && size>0);
+
+	u32 bu8 = (u32)buffer;
+	while (size > 0)
 	{
-		vtlbdata.vmap[vaddr>>VTLB_PAGE_BITS]=bu8-vaddr;
-		vaddr+=VTLB_PAGE_SIZE;
-		bu8+=VTLB_PAGE_SIZE;
-		sz-=VTLB_PAGE_SIZE;
+		vtlbdata.vmap[vaddr>>VTLB_PAGE_BITS] = bu8-vaddr;
+		vaddr += VTLB_PAGE_SIZE;
+		bu8 += VTLB_PAGE_SIZE;
+		size -= VTLB_PAGE_SIZE;
 	}
 }
-void vtlb_VMapUnmap(u32 vaddr,u32 sz)
+void vtlb_VMapUnmap(u32 vaddr,u32 size)
 {
 	verify(0==(vaddr&VTLB_PAGE_MASK));
-	verify(0==(sz&VTLB_PAGE_MASK) && sz>0);
+	verify(0==(size&VTLB_PAGE_MASK) && size>0);
 
-	while(sz>0)
+	while (size > 0)
 	{
-		u32 handl=UnmappedVirtHandler0;
-		if (vaddr&0x80000000)
+		u32 handl = UnmappedVirtHandler0;
+		if (vaddr & 0x80000000)
 		{
-			handl=UnmappedVirtHandler1;
+			handl = UnmappedVirtHandler1;
 		}
-		handl|=vaddr; // top bit is set anyway ...
-		handl|=0x80000000;
-		vtlbdata.vmap[vaddr>>VTLB_PAGE_BITS]=handl-vaddr;
-		vaddr+=VTLB_PAGE_SIZE;
-		sz-=VTLB_PAGE_SIZE;
+
+		handl |= vaddr; // top bit is set anyway ...
+		handl |= 0x80000000;
+
+		vtlbdata.vmap[vaddr>>VTLB_PAGE_BITS] = handl-vaddr;
+		vaddr += VTLB_PAGE_SIZE;
+		size -= VTLB_PAGE_SIZE;
 	}
 }
 
@@ -562,60 +563,86 @@
 }
 
 // Reserves the vtlb core allocation used by various emulation components!
-//
+// [TODO] basemem - request allocating memory at the specified virtual location, which can allow
+//    for easier debugging and/or 3rd party cheat programs.  If 0, the operating system
+//    default is used.
 void vtlb_Core_Alloc()
 {
-	if( vtlbdata.alloc_base != NULL ) return;
-
-	vtlbdata.alloc_current = 0;
-
-#ifdef __LINUX__
-	vtlbdata.alloc_base = SysMmapEx( 0x16000000, VTLB_ALLOC_SIZE, 0x80000000, "Vtlb" );
-#else
-	// Win32 just needs this, since malloc always maps below 2GB.
-	vtlbdata.alloc_base = (u8*)_aligned_malloc( VTLB_ALLOC_SIZE, 4096 );
-	if( vtlbdata.alloc_base == NULL )
-		throw Exception::OutOfMemory( pxsFmt(L"PS2 mappable system ram (%u megs)", VTLB_ALLOC_SIZE / _1mb) );
-#endif
+	if (!vtlbdata.vmap)
+	{
+		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_Shutdown()
+void vtlb_Core_Free()
 {
-	if( vtlbdata.alloc_base == NULL ) return;
-
-#ifdef __LINUX__
-	SafeSysMunmap( vtlbdata.alloc_base, VTLB_ALLOC_SIZE );
-#else
-	// Make sure and unprotect memory first, since CrtDebug will try to write to it.
-	HostSys::MemProtect( vtlbdata.alloc_base, VTLB_ALLOC_SIZE, Protect_ReadWrite );
-	safe_aligned_free( vtlbdata.alloc_base );
-#endif
+	safe_aligned_free( vtlbdata.vmap );
+}
 
+static wxString GetHostVmErrorMsg()
+{
+	return pxE("!Notice:HostVmReserve",
+		L"Your system is too low on virtual resources for PCSX2 to run.  This can be "
+		L"caused by having a small or disabled swapfile, or by other programs that are "
+		L"hogging resources."
+	);
+}
+// --------------------------------------------------------------------------------------
+//  VtlbMemoryReserve  (implementations)
+// --------------------------------------------------------------------------------------
+VtlbMemoryReserve::VtlbMemoryReserve( const wxString& name, size_t size )
+	: m_reserve( name, size )
+{
+	m_reserve.SetPageAccessOnCommit( PageAccess_ReadWrite() );
 }
 
-// This function allocates memory block with are compatible with the Vtlb's requirements
-// for memory locations.  The Vtlb requires the topmost bit (Sign bit) of the memory
-// pointer to be cleared.  Some operating systems and/or implementations of malloc do that,
-// but others do not.  So use this instead to allocate the memory correctly for your
-// platform.
-//
-u8* vtlb_malloc( uint size, uint align )
+void VtlbMemoryReserve::SetBaseAddr( uptr newaddr )
 {
-	vtlbdata.alloc_current += align-1;
-	vtlbdata.alloc_current &= ~(align-1);
+	m_reserve.SetBaseAddr( newaddr );
+}
 
-	int rv = vtlbdata.alloc_current;
-	vtlbdata.alloc_current += size;
+void VtlbMemoryReserve::Reserve( sptr hostptr )
+{
+	if (!m_reserve.ReserveAt( hostptr ))
+	{
+		throw Exception::OutOfMemory( m_reserve.GetName() )
+			.SetDiagMsg(L"Vtlb memory could not be reserved.")
+			.SetUserMsg(GetHostVmErrorMsg());
+	}
+}
 
-	pxAssertDev( vtlbdata.alloc_current < VTLB_ALLOC_SIZE, "(vtlb_malloc) memory overflow! Please increase the size of VTLB_ALLOC_SIZE!" );
-	return &vtlbdata.alloc_base[rv];
+void VtlbMemoryReserve::Commit()
+{
+	if (IsCommitted()) return;
+	if (!m_reserve.Commit())
+	{
+		throw Exception::OutOfMemory( m_reserve.GetName() )
+			.SetDiagMsg(L"Vtlb memory could not be committed.")
+			.SetUserMsg(GetHostVmErrorMsg());
+	}
 }
 
-void vtlb_free( void* pmem, uint size )
+void VtlbMemoryReserve::Reset()
 {
-	vtlbdata.alloc_current -= size;
+	Commit();
+	memzero_sse_a(m_reserve.GetPtr(), m_reserve.GetCommittedBytes());
+}
 
-	pxAssertDev( vtlbdata.alloc_current >= 0, "(vtlb_free) mismatched calls to vtlb_malloc and free detected via memory underflow." );
+void VtlbMemoryReserve::Decommit()
+{
+	m_reserve.Reset();
+}
 
-	return;
+void VtlbMemoryReserve::Release()
+{
+	m_reserve.Release();
 }
+
+bool VtlbMemoryReserve::IsCommitted() const
+{
+	return !!m_reserve.GetCommittedPageCount();
+}
\ No newline at end of file

 

  ViewVC Help
Powered by ViewVC 1.1.22