2009-09-08 12:08:10 +00:00
/* PCSX2 - PS2 Emulator for PCs
2010-05-03 14:08:02 +00:00
* Copyright ( C ) 2002 - 2010 PCSX2 Dev Team
2010-04-25 00:31:27 +00:00
*
2009-09-08 12:08:10 +00:00
* PCSX2 is free software : you can redistribute it and / or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found -
* ation , either version 3 of the License , or ( at your option ) any later version .
2009-02-09 21:15:56 +00:00
*
2009-09-08 12:08:10 +00:00
* PCSX2 is distributed in the hope that it will be useful , but WITHOUT ANY WARRANTY ;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE . See the GNU General Public License for more details .
2009-04-28 05:56:22 +00:00
*
2009-09-08 12:08:10 +00:00
* You should have received a copy of the GNU General Public License along with PCSX2 .
* If not , see < http : //www.gnu.org/licenses/>.
2009-02-09 21:15:56 +00:00
*/
/*
RAM
- - -
0x00100000 - 0x01ffffff this is the physical address for the ram . its cached there
2010-04-25 00:31:27 +00:00
0x20100000 - 0x21ffffff uncached
2009-08-06 12:00:06 +00:00
0x30100000 - 0x31ffffff uncached & accelerated
2009-02-09 21:15:56 +00:00
0xa0000000 - 0xa1ffffff MIRROR might . . . ? ? ?
2009-04-28 05:56:22 +00:00
0x80000000 - 0x81ffffff MIRROR might . . . ? ? ? ?
2009-02-09 21:15:56 +00:00
scratch pad
- - - - - - - - - -
0x70000000 - 0x70003fff scratch pad
BIOS
- - - -
0x1FC00000 - 0x1FFFFFFF un - cached
0x9FC00000 - 0x9FFFFFFF cached
0xBFC00000 - 0xBFFFFFFF un - cached
*/
# include "PrecompiledHeader.h"
2009-04-27 02:04:31 +00:00
# include <wx/file.h>
2009-02-09 21:15:56 +00:00
2010-08-31 05:22:26 +00:00
# include "IopCommon.h"
2009-02-09 21:15:56 +00:00
# include "GS.h"
2011-08-12 02:31:49 +00:00
# include "VUmicro.h"
# include "MTVU.h"
2010-08-31 05:22:26 +00:00
# include "ps2/HwInternal.h"
2009-11-14 12:02:56 +00:00
# include "ps2/BiosTools.h"
2009-02-09 21:15:56 +00:00
2010-10-27 19:18:46 +00:00
# include "Utilities/PageFaultSource.h"
2009-02-09 21:15:56 +00:00
# ifdef ENABLECACHE
# include "Cache.h"
# endif
int MemMode = 0 ; // 0 is Kernel Mode, 1 is Supervisor Mode, 2 is User Mode
void memSetKernelMode ( ) {
//Do something here
MemMode = 0 ;
}
void memSetSupervisorMode ( ) {
}
void memSetUserMode ( ) {
}
u16 ba0R16 ( u32 mem )
{
2009-03-27 06:34:51 +00:00
//MEM_LOG("ba00000 Memory read16 address %x", mem);
2009-02-09 21:15:56 +00:00
if ( mem = = 0x1a000006 ) {
static int ba6 ;
ba6 + + ;
if ( ba6 = = 3 ) ba6 = 0 ;
return ba6 ;
}
return 0 ;
}
# define CHECK_MEM(mem) //MyMemCheck(mem)
void MyMemCheck ( u32 mem )
{
if ( mem = = 0x1c02f2a0 )
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
Console . WriteLn ( " yo; (mem == 0x1c02f2a0) in MyMemCheck... " ) ;
2009-02-09 21:15:56 +00:00
}
/////////////////////////////
2009-04-28 05:56:22 +00:00
// REGULAR MEM START
2009-02-09 21:15:56 +00:00
/////////////////////////////
2010-07-31 22:42:24 +00:00
static vtlbHandler
null_handler ,
2010-04-22 00:11:53 +00:00
2010-07-31 22:42:24 +00:00
tlb_fallback_0 ,
tlb_fallback_2 ,
tlb_fallback_3 ,
tlb_fallback_4 ,
tlb_fallback_5 ,
tlb_fallback_6 ,
tlb_fallback_7 ,
tlb_fallback_8 ,
2009-02-09 21:15:56 +00:00
2010-07-31 22:42:24 +00:00
vu0_micro_mem ,
vu1_micro_mem ,
2011-08-12 02:31:49 +00:00
vu1_data_mem ,
2009-02-09 21:15:56 +00:00
2010-07-31 22:42:24 +00:00
hw_by_page [ 0x10 ] = { - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 } ,
2009-02-09 21:15:56 +00:00
2010-07-31 22:42:24 +00:00
gs_page_0 ,
gs_page_1 ,
iopHw_by_page_01 ,
iopHw_by_page_03 ,
iopHw_by_page_08 ;
2009-05-04 19:04:21 +00:00
2009-02-09 21:15:56 +00:00
void memMapVUmicro ( )
{
2010-07-31 22:42:24 +00:00
// VU0/VU1 micro mem (instructions)
2009-10-19 15:56:18 +00:00
// (Like IOP memory, these are generally only used by the EE Bios kernel during
2010-07-31 22:42:24 +00:00
// boot-up. Applications/games are "supposed" to use the thread-safe VIF instead;
// or must ensure all VIF/GIF transfers are finished and all VUmicro execution stopped
// prior to accessing VU memory directly).
// The VU0 mapping actually repeats 4 times across the mapped range, but we don't bother
// to manually mirror it here because the indirect memory handler for it (see vuMicroRead*
// functions below) automatically mask and wrap the address for us.
vtlb_MapHandler ( vu0_micro_mem , 0x11000000 , 0x00004000 ) ;
vtlb_MapHandler ( vu1_micro_mem , 0x11008000 , 0x00004000 ) ;
// VU0/VU1 memory (data)
// VU0 is 4k, mirrored 4 times across a 16k area.
2009-02-09 21:15:56 +00:00
vtlb_MapBlock ( VU0 . Mem , 0x11004000 , 0x00004000 , 0x1000 ) ;
2011-08-12 02:31:49 +00:00
// Note: In order for the below conditional to work correctly
// support needs to be coded to reset the memMappings when MTVU is
// turned off/on. For now we just always use the vu data handlers...
if ( 1 | | THREAD_VU1 ) vtlb_MapHandler ( vu1_data_mem , 0x1100c000 , 0x00004000 ) ;
else vtlb_MapBlock ( VU1 . Mem , 0x1100c000 , 0x00004000 ) ;
2009-02-09 21:15:56 +00:00
}
void memMapPhy ( )
{
2009-10-19 15:56:18 +00:00
// Main memory
2010-10-22 16:23:52 +00:00
vtlb_MapBlock ( eeMem - > Main , 0x00000000 , Ps2MemSize : : MainRam ) ; //mirrored on first 256 mb ?
2010-04-22 00:11:53 +00:00
// High memory, uninstalled on the configuration we emulate
2010-10-22 16:23:52 +00:00
vtlb_MapHandler ( null_handler , Ps2MemSize : : MainRam , 0x10000000 - Ps2MemSize : : MainRam ) ;
2009-10-19 15:56:18 +00:00
// Various ROMs (all read-only)
2010-08-16 15:57:01 +00:00
vtlb_MapBlock ( eeMem - > ROM , 0x1fc00000 , Ps2MemSize : : Rom ) ;
vtlb_MapBlock ( eeMem - > ROM1 , 0x1e000000 , Ps2MemSize : : Rom1 ) ;
vtlb_MapBlock ( eeMem - > ROM2 , 0x1e400000 , Ps2MemSize : : Rom2 ) ;
vtlb_MapBlock ( eeMem - > EROM , 0x1e040000 , Ps2MemSize : : ERom ) ;
2009-10-19 15:56:18 +00:00
// IOP memory
// (used by the EE Bios Kernel during initial hardware initialization, Apps/Games
// are "supposed" to use the thread-safe SIF instead.)
2010-09-23 19:44:55 +00:00
vtlb_MapBlock ( iopMem - > Main , 0x1c000000 , 0x00800000 ) ;
2009-02-09 21:15:56 +00:00
2009-10-19 15:56:18 +00:00
// Generic Handlers; These fallback to mem* stuff...
2010-11-16 04:53:52 +00:00
vtlb_MapHandler ( tlb_fallback_7 , 0x14000000 , _64kb ) ;
vtlb_MapHandler ( tlb_fallback_4 , 0x18000000 , _64kb ) ;
vtlb_MapHandler ( tlb_fallback_5 , 0x1a000000 , _64kb ) ;
vtlb_MapHandler ( tlb_fallback_6 , 0x12000000 , _64kb ) ;
vtlb_MapHandler ( tlb_fallback_8 , 0x1f000000 , _64kb ) ;
vtlb_MapHandler ( tlb_fallback_3 , 0x1f400000 , _64kb ) ;
vtlb_MapHandler ( tlb_fallback_2 , 0x1f800000 , _64kb ) ;
vtlb_MapHandler ( tlb_fallback_8 , 0x1f900000 , _64kb ) ;
2009-02-09 21:15:56 +00:00
2009-10-19 15:56:18 +00:00
// Hardware Register Handlers : specialized/optimized per-page handling of HW register accesses
// (note that hw_by_page handles are assigned in memReset prior to calling this function)
2010-08-31 05:22:26 +00:00
for ( uint i = 0 ; i < 16 ; + + i )
vtlb_MapHandler ( hw_by_page [ i ] , 0x10000000 + ( 0x01000 * i ) , 0x01000 ) ;
2009-02-09 21:15:56 +00:00
vtlb_MapHandler ( gs_page_0 , 0x12000000 , 0x01000 ) ;
vtlb_MapHandler ( gs_page_1 , 0x12001000 , 0x01000 ) ;
2009-10-19 15:56:18 +00:00
// "Secret" IOP HW mappings - Used by EE Bios Kernel during boot and generally
// left untouched after that, as per EE/IOP thread safety rules.
2010-04-25 00:31:27 +00:00
2010-01-13 02:43:35 +00:00
vtlb_MapHandler ( iopHw_by_page_01 , 0x1f801000 , 0x01000 ) ;
vtlb_MapHandler ( iopHw_by_page_03 , 0x1f803000 , 0x01000 ) ;
vtlb_MapHandler ( iopHw_by_page_08 , 0x1f808000 , 0x01000 ) ;
2009-05-04 19:04:21 +00:00
2009-02-09 21:15:56 +00:00
}
//Why is this required ?
void memMapKernelMem ( )
{
//lower 512 mb: direct map
//vtlb_VMap(0x00000000,0x00000000,0x20000000);
//0x8* mirror
2010-11-16 04:53:52 +00:00
vtlb_VMap ( 0x80000000 , 0x00000000 , _1mb * 512 ) ;
2009-02-09 21:15:56 +00:00
//0xa* mirror
2010-11-16 04:53:52 +00:00
vtlb_VMap ( 0xA0000000 , 0x00000000 , _1mb * 512 ) ;
2009-02-09 21:15:56 +00:00
}
//what do do with these ?
2009-04-28 05:56:22 +00:00
void memMapSupervisorMem ( )
2009-02-09 21:15:56 +00:00
{
}
2009-04-28 05:56:22 +00:00
void memMapUserMem ( )
2009-02-09 21:15:56 +00:00
{
}
2010-04-22 00:11:53 +00:00
static mem8_t __fastcall nullRead8 ( u32 mem ) {
MEM_LOG ( " Read uninstalled memory at address %08x " , mem ) ;
return 0 ;
}
static mem16_t __fastcall nullRead16 ( u32 mem ) {
MEM_LOG ( " Read uninstalled memory at address %08x " , mem ) ;
return 0 ;
}
static mem32_t __fastcall nullRead32 ( u32 mem ) {
MEM_LOG ( " Read uninstalled memory at address %08x " , mem ) ;
return 0 ;
}
static void __fastcall nullRead64 ( u32 mem , mem64_t * out ) {
MEM_LOG ( " Read uninstalled memory at address %08x " , mem ) ;
* out = 0 ;
}
static void __fastcall nullRead128 ( u32 mem , mem128_t * out ) {
MEM_LOG ( " Read uninstalled memory at address %08x " , mem ) ;
2010-08-09 15:42:13 +00:00
ZeroQWC ( out ) ;
2010-04-22 00:11:53 +00:00
}
static void __fastcall nullWrite8 ( u32 mem , mem8_t value )
{
MEM_LOG ( " Write uninstalled memory at address %08x " , mem ) ;
}
static void __fastcall nullWrite16 ( u32 mem , mem16_t value )
{
MEM_LOG ( " Write uninstalled memory at address %08x " , mem ) ;
}
static void __fastcall nullWrite32 ( u32 mem , mem32_t value )
{
MEM_LOG ( " Write uninstalled memory at address %08x " , mem ) ;
}
static void __fastcall nullWrite64 ( u32 mem , const mem64_t * value )
{
MEM_LOG ( " Write uninstalled memory at address %08x " , mem ) ;
}
static void __fastcall nullWrite128 ( u32 mem , const mem128_t * value )
{
MEM_LOG ( " Write uninstalled memory at address %08x " , mem ) ;
}
2009-02-09 21:15:56 +00:00
template < int p >
2010-07-31 22:42:24 +00:00
static mem8_t __fastcall _ext_memRead8 ( u32 mem )
2009-02-09 21:15:56 +00:00
{
2009-04-28 05:56:22 +00:00
switch ( p )
2009-02-09 21:15:56 +00:00
{
case 3 : // psh4
return psxHw4Read8 ( mem ) ;
case 6 : // gsm
return gsRead8 ( mem ) ;
case 7 : // dev9
{
mem8_t retval = DEV9read8 ( mem & ~ 0xa4000000 ) ;
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
Console . WriteLn ( " DEV9 read8 %8.8lx: %2.2lx " , mem & ~ 0xa4000000 , retval ) ;
2009-02-09 21:15:56 +00:00
return retval ;
}
}
2009-03-27 06:34:51 +00:00
MEM_LOG ( " Unknown Memory Read8 from address %8.8x " , mem ) ;
2009-02-09 21:15:56 +00:00
cpuTlbMissR ( mem , cpuRegs . branch ) ;
return 0 ;
}
template < int p >
2010-07-31 22:42:24 +00:00
static mem16_t __fastcall _ext_memRead16 ( u32 mem )
2009-02-09 21:15:56 +00:00
{
switch ( p )
{
case 4 : // b80
2009-03-27 06:34:51 +00:00
MEM_LOG ( " b800000 Memory read16 address %x " , mem ) ;
2009-02-09 21:15:56 +00:00
return 0 ;
case 5 : // ba0
return ba0R16 ( mem ) ;
case 6 : // gsm
return gsRead16 ( mem ) ;
case 7 : // dev9
{
mem16_t retval = DEV9read16 ( mem & ~ 0xa4000000 ) ;
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
Console . WriteLn ( " DEV9 read16 %8.8lx: %4.4lx " , mem & ~ 0xa4000000 , retval ) ;
2009-02-09 21:15:56 +00:00
return retval ;
}
case 8 : // spu2
return SPU2read ( mem ) ;
}
2009-03-27 06:34:51 +00:00
MEM_LOG ( " Unknown Memory read16 from address %8.8x " , mem ) ;
2009-02-09 21:15:56 +00:00
cpuTlbMissR ( mem , cpuRegs . branch ) ;
return 0 ;
}
template < int p >
2010-07-31 22:42:24 +00:00
static mem32_t __fastcall _ext_memRead32 ( u32 mem )
2009-02-09 21:15:56 +00:00
{
switch ( p )
{
case 6 : // gsm
return gsRead32 ( mem ) ;
case 7 : // dev9
{
mem32_t retval = DEV9read32 ( mem & ~ 0xa4000000 ) ;
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
Console . WriteLn ( " DEV9 read32 %8.8lx: %8.8lx " , mem & ~ 0xa4000000 , retval ) ;
2009-02-09 21:15:56 +00:00
return retval ;
}
}
2009-03-27 06:34:51 +00:00
MEM_LOG ( " Unknown Memory read32 from address %8.8x (Status=%8.8x) " , mem , cpuRegs . CP0 . n . Status . val ) ;
2009-02-09 21:15:56 +00:00
cpuTlbMissR ( mem , cpuRegs . branch ) ;
return 0 ;
}
template < int p >
2010-07-31 22:42:24 +00:00
static void __fastcall _ext_memRead64 ( u32 mem , mem64_t * out )
2009-02-09 21:15:56 +00:00
{
switch ( p )
{
case 6 : // gsm
* out = gsRead64 ( mem ) ; return ;
}
2009-03-27 06:34:51 +00:00
MEM_LOG ( " Unknown Memory read64 from address %8.8x " , mem ) ;
2009-02-09 21:15:56 +00:00
cpuTlbMissR ( mem , cpuRegs . branch ) ;
}
template < int p >
2010-07-31 22:42:24 +00:00
static void __fastcall _ext_memRead128 ( u32 mem , mem128_t * out )
2009-02-09 21:15:56 +00:00
{
switch ( p )
{
//case 1: // hwm
// hwRead128(mem & ~0xa0000000, out); return;
case 6 : // gsm
2010-08-09 15:42:13 +00:00
CopyQWC ( out , PS2GS_BASE ( mem ) ) ;
return ;
2009-02-09 21:15:56 +00:00
}
2009-03-27 06:34:51 +00:00
MEM_LOG ( " Unknown Memory read128 from address %8.8x " , mem ) ;
2009-02-09 21:15:56 +00:00
cpuTlbMissR ( mem , cpuRegs . branch ) ;
}
template < int p >
2010-07-31 22:42:24 +00:00
static void __fastcall _ext_memWrite8 ( u32 mem , mem8_t value )
2009-02-09 21:15:56 +00:00
{
switch ( p ) {
case 3 : // psh4
psxHw4Write8 ( mem , value ) ; return ;
case 6 : // gsm
gsWrite8 ( mem , value ) ; return ;
case 7 : // dev9
DEV9write8 ( mem & ~ 0xa4000000 , value ) ;
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
Console . WriteLn ( " DEV9 write8 %8.8lx: %2.2lx " , mem & ~ 0xa4000000 , value ) ;
2009-02-09 21:15:56 +00:00
return ;
}
2009-03-27 06:34:51 +00:00
MEM_LOG ( " Unknown Memory write8 to address %x with data %2.2x " , mem , value ) ;
2009-02-09 21:15:56 +00:00
cpuTlbMissW ( mem , cpuRegs . branch ) ;
}
2010-07-31 22:42:24 +00:00
2009-02-09 21:15:56 +00:00
template < int p >
2010-07-31 22:42:24 +00:00
static void __fastcall _ext_memWrite16 ( u32 mem , mem16_t value )
2009-02-09 21:15:56 +00:00
{
switch ( p ) {
case 5 : // ba0
2009-03-27 06:34:51 +00:00
MEM_LOG ( " ba00000 Memory write16 to address %x with data %x " , mem , value ) ;
2009-02-09 21:15:56 +00:00
return ;
case 6 : // gsm
gsWrite16 ( mem , value ) ; return ;
case 7 : // dev9
DEV9write16 ( mem & ~ 0xa4000000 , value ) ;
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
Console . WriteLn ( " DEV9 write16 %8.8lx: %4.4lx " , mem & ~ 0xa4000000 , value ) ;
2009-02-09 21:15:56 +00:00
return ;
case 8 : // spu2
SPU2write ( mem , value ) ; return ;
}
2009-03-27 06:34:51 +00:00
MEM_LOG ( " Unknown Memory write16 to address %x with data %4.4x " , mem , value ) ;
2009-02-09 21:15:56 +00:00
cpuTlbMissW ( mem , cpuRegs . branch ) ;
}
2009-02-28 20:55:53 +00:00
2009-02-09 21:15:56 +00:00
template < int p >
2010-07-31 22:42:24 +00:00
static void __fastcall _ext_memWrite32 ( u32 mem , mem32_t value )
2009-02-09 21:15:56 +00:00
{
switch ( p ) {
case 6 : // gsm
gsWrite32 ( mem , value ) ; return ;
case 7 : // dev9
DEV9write32 ( mem & ~ 0xa4000000 , value ) ;
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
Console . WriteLn ( " DEV9 write32 %8.8lx: %8.8lx " , mem & ~ 0xa4000000 , value ) ;
2009-02-09 21:15:56 +00:00
return ;
}
2009-03-27 06:34:51 +00:00
MEM_LOG ( " Unknown Memory write32 to address %x with data %8.8x " , mem , value ) ;
2009-02-09 21:15:56 +00:00
cpuTlbMissW ( mem , cpuRegs . branch ) ;
}
2009-02-28 20:55:53 +00:00
2009-02-09 21:15:56 +00:00
template < int p >
2010-07-31 22:42:24 +00:00
static void __fastcall _ext_memWrite64 ( u32 mem , const mem64_t * value )
2009-02-09 21:15:56 +00:00
{
/*switch (p) {
//case 1: // hwm
// hwWrite64(mem & ~0xa0000000, *value);
// return;
//case 6: // gsm
// gsWrite64(mem & ~0xa0000000, *value); return;
} */
2009-03-27 06:34:51 +00:00
MEM_LOG ( " Unknown Memory write64 to address %x with data %8.8x_%8.8x " , mem , ( u32 ) ( * value > > 32 ) , ( u32 ) * value ) ;
2009-02-09 21:15:56 +00:00
cpuTlbMissW ( mem , cpuRegs . branch ) ;
}
2009-02-28 20:55:53 +00:00
2009-02-09 21:15:56 +00:00
template < int p >
2010-07-31 22:42:24 +00:00
static void __fastcall _ext_memWrite128 ( u32 mem , const mem128_t * value )
2009-02-09 21:15:56 +00:00
{
/*switch (p) {
//case 1: // hwm
// hwWrite128(mem & ~0xa0000000, value);
// return;
//case 6: // gsm
// mem &= ~0xa0000000;
// gsWrite64(mem, value[0]);
// gsWrite64(mem+8, value[1]); return;
} */
2009-03-27 06:34:51 +00:00
MEM_LOG ( " Unknown Memory write128 to address %x with data %8.8x_%8.8x_%8.8x_%8.8x " , mem , ( ( u32 * ) value ) [ 3 ] , ( ( u32 * ) value ) [ 2 ] , ( ( u32 * ) value ) [ 1 ] , ( ( u32 * ) value ) [ 0 ] ) ;
2009-02-09 21:15:56 +00:00
cpuTlbMissW ( mem , cpuRegs . branch ) ;
}
# define vtlb_RegisterHandlerTempl1(nam,t) vtlb_RegisterHandler(nam##Read8<t>,nam##Read16<t>,nam##Read32<t>,nam##Read64<t>,nam##Read128<t>, \
nam # # Write8 < t > , nam # # Write16 < t > , nam # # Write32 < t > , nam # # Write64 < t > , nam # # Write128 < t > )
typedef void __fastcall ClearFunc_t ( u32 addr , u32 qwc ) ;
2011-08-12 02:31:49 +00:00
template < int vunum > static __fi void ClearVuFunc ( u32 addr , u32 size ) {
if ( vunum ) CpuVU1 - > Clear ( addr , size ) ;
else CpuVU0 - > Clear ( addr , size ) ;
2009-02-09 21:15:56 +00:00
}
2011-08-12 02:31:49 +00:00
// VU Micro Memory Reads...
template < int vunum > static mem8_t __fc vuMicroRead8 ( u32 addr ) {
VURegs * vu = vunum ? & VU1 : & VU0 ;
addr & = vunum ? 0x3fff : 0xfff ;
2013-02-22 16:30:59 +00:00
2011-08-12 02:31:49 +00:00
if ( vunum & & THREAD_VU1 ) vu1Thread . WaitVU ( ) ;
2009-02-09 21:15:56 +00:00
return vu - > Micro [ addr ] ;
}
2011-08-12 02:31:49 +00:00
template < int vunum > static mem16_t __fc vuMicroRead16 ( u32 addr ) {
VURegs * vu = vunum ? & VU1 : & VU0 ;
addr & = vunum ? 0x3fff : 0xfff ;
2013-02-22 16:30:59 +00:00
2011-08-12 02:31:49 +00:00
if ( vunum & & THREAD_VU1 ) vu1Thread . WaitVU ( ) ;
2009-02-09 21:15:56 +00:00
return * ( u16 * ) & vu - > Micro [ addr ] ;
}
2011-08-12 02:31:49 +00:00
template < int vunum > static mem32_t __fc vuMicroRead32 ( u32 addr ) {
VURegs * vu = vunum ? & VU1 : & VU0 ;
addr & = vunum ? 0x3fff : 0xfff ;
2013-02-22 16:30:59 +00:00
2011-08-12 02:31:49 +00:00
if ( vunum & & THREAD_VU1 ) vu1Thread . WaitVU ( ) ;
2009-02-09 21:15:56 +00:00
return * ( u32 * ) & vu - > Micro [ addr ] ;
}
2011-08-12 02:31:49 +00:00
template < int vunum > static void __fc vuMicroRead64 ( u32 addr , mem64_t * data ) {
VURegs * vu = vunum ? & VU1 : & VU0 ;
addr & = vunum ? 0x3fff : 0xfff ;
2013-02-22 16:30:59 +00:00
2011-08-12 02:31:49 +00:00
if ( vunum & & THREAD_VU1 ) vu1Thread . WaitVU ( ) ;
2009-02-09 21:15:56 +00:00
* data = * ( u64 * ) & vu - > Micro [ addr ] ;
}
2011-08-12 02:31:49 +00:00
template < int vunum > static void __fc vuMicroRead128 ( u32 addr , mem128_t * data ) {
VURegs * vu = vunum ? & VU1 : & VU0 ;
addr & = vunum ? 0x3fff : 0xfff ;
if ( vunum & & THREAD_VU1 ) vu1Thread . WaitVU ( ) ;
2013-02-22 16:30:59 +00:00
2010-08-09 15:42:13 +00:00
CopyQWC ( data , & vu - > Micro [ addr ] ) ;
2009-02-09 21:15:56 +00:00
}
2009-04-14 01:26:57 +00:00
// Profiled VU writes: Happen very infrequently, with exception of BIOS initialization (at most twice per
// frame in-game, and usually none at all after BIOS), so cpu clears aren't much of a big deal.
2011-08-12 02:31:49 +00:00
template < int vunum > static void __fc vuMicroWrite8 ( u32 addr , mem8_t data ) {
VURegs * vu = vunum ? & VU1 : & VU0 ;
addr & = vunum ? 0x3fff : 0xfff ;
2013-02-22 16:30:59 +00:00
2011-08-12 02:31:49 +00:00
if ( vunum & & THREAD_VU1 ) {
vu1Thread . WriteMicroMem ( addr , & data , sizeof ( u8 ) ) ;
return ;
}
if ( vu - > Micro [ addr ] ! = data ) { // Clear before writing new data
ClearVuFunc < vunum > ( addr , 8 ) ; //(clearing 8 bytes because an instruction is 8 bytes) (cottonvibes)
vu - > Micro [ addr ] = data ;
2009-02-09 21:15:56 +00:00
}
}
2011-08-12 02:31:49 +00:00
template < int vunum > static void __fc vuMicroWrite16 ( u32 addr , mem16_t data ) {
VURegs * vu = vunum ? & VU1 : & VU0 ;
addr & = vunum ? 0x3fff : 0xfff ;
2013-02-22 16:30:59 +00:00
2011-08-12 02:31:49 +00:00
if ( vunum & & THREAD_VU1 ) {
vu1Thread . WriteMicroMem ( addr , & data , sizeof ( u16 ) ) ;
return ;
}
if ( * ( u16 * ) & vu - > Micro [ addr ] ! = data ) {
ClearVuFunc < vunum > ( addr , 8 ) ;
* ( u16 * ) & vu - > Micro [ addr ] = data ;
2009-02-09 21:15:56 +00:00
}
}
2011-08-12 02:31:49 +00:00
template < int vunum > static void __fc vuMicroWrite32 ( u32 addr , mem32_t data ) {
VURegs * vu = vunum ? & VU1 : & VU0 ;
addr & = vunum ? 0x3fff : 0xfff ;
2013-02-22 16:30:59 +00:00
2011-08-12 02:31:49 +00:00
if ( vunum & & THREAD_VU1 ) {
vu1Thread . WriteMicroMem ( addr , & data , sizeof ( u32 ) ) ;
return ;
}
if ( * ( u32 * ) & vu - > Micro [ addr ] ! = data ) {
ClearVuFunc < vunum > ( addr , 8 ) ;
* ( u32 * ) & vu - > Micro [ addr ] = data ;
2009-02-09 21:15:56 +00:00
}
}
2011-08-12 02:31:49 +00:00
template < int vunum > static void __fc vuMicroWrite64 ( u32 addr , const mem64_t * data ) {
VURegs * vu = vunum ? & VU1 : & VU0 ;
addr & = vunum ? 0x3fff : 0xfff ;
2013-02-24 14:37:30 +00:00
2011-08-12 02:31:49 +00:00
if ( vunum & & THREAD_VU1 ) {
2013-02-24 20:29:51 +00:00
vu1Thread . WriteMicroMem ( addr , ( void * ) data , sizeof ( u64 ) ) ;
2011-08-12 02:31:49 +00:00
return ;
}
2013-02-22 16:30:59 +00:00
2013-02-24 20:29:51 +00:00
if ( * ( u64 * ) & vu - > Micro [ addr ] ! = data [ 0 ] ) {
2011-08-12 02:31:49 +00:00
ClearVuFunc < vunum > ( addr , 8 ) ;
2013-02-24 20:29:51 +00:00
* ( u64 * ) & vu - > Micro [ addr ] = data [ 0 ] ;
2011-08-12 02:31:49 +00:00
}
}
template < int vunum > static void __fc vuMicroWrite128 ( u32 addr , const mem128_t * data ) {
VURegs * vu = vunum ? & VU1 : & VU0 ;
addr & = vunum ? 0x3fff : 0xfff ;
2013-02-22 16:30:59 +00:00
2011-08-12 02:31:49 +00:00
if ( vunum & & THREAD_VU1 ) {
2013-02-24 14:37:30 +00:00
vu1Thread . WriteMicroMem ( addr , ( void * ) data , sizeof ( u128 ) ) ;
2011-08-12 02:31:49 +00:00
return ;
}
2013-02-24 20:29:51 +00:00
if ( ( u128 & ) vu - > Micro [ addr ] ! = * data ) {
2011-08-12 02:31:49 +00:00
ClearVuFunc < vunum > ( addr , 16 ) ;
2013-02-24 14:37:30 +00:00
CopyQWC ( & vu - > Micro [ addr ] , data ) ;
2009-02-09 21:15:56 +00:00
}
}
2011-08-12 02:31:49 +00:00
// VU Data Memory Reads...
template < int vunum > static mem8_t __fc vuDataRead8 ( u32 addr ) {
VURegs * vu = vunum ? & VU1 : & VU0 ;
addr & = vunum ? 0x3fff : 0xfff ;
if ( vunum & & THREAD_VU1 ) vu1Thread . WaitVU ( ) ;
return vu - > Mem [ addr ] ;
}
template < int vunum > static mem16_t __fc vuDataRead16 ( u32 addr ) {
VURegs * vu = vunum ? & VU1 : & VU0 ;
addr & = vunum ? 0x3fff : 0xfff ;
if ( vunum & & THREAD_VU1 ) vu1Thread . WaitVU ( ) ;
return * ( u16 * ) & vu - > Mem [ addr ] ;
}
template < int vunum > static mem32_t __fc vuDataRead32 ( u32 addr ) {
VURegs * vu = vunum ? & VU1 : & VU0 ;
addr & = vunum ? 0x3fff : 0xfff ;
if ( vunum & & THREAD_VU1 ) vu1Thread . WaitVU ( ) ;
return * ( u32 * ) & vu - > Mem [ addr ] ;
}
template < int vunum > static void __fc vuDataRead64 ( u32 addr , mem64_t * data ) {
VURegs * vu = vunum ? & VU1 : & VU0 ;
addr & = vunum ? 0x3fff : 0xfff ;
if ( vunum & & THREAD_VU1 ) vu1Thread . WaitVU ( ) ;
* data = * ( u64 * ) & vu - > Mem [ addr ] ;
}
template < int vunum > static void __fc vuDataRead128 ( u32 addr , mem128_t * data ) {
VURegs * vu = vunum ? & VU1 : & VU0 ;
addr & = vunum ? 0x3fff : 0xfff ;
if ( vunum & & THREAD_VU1 ) vu1Thread . WaitVU ( ) ;
CopyQWC ( data , & vu - > Mem [ addr ] ) ;
}
// VU Data Memory Writes...
template < int vunum > static void __fc vuDataWrite8 ( u32 addr , mem8_t data ) {
VURegs * vu = vunum ? & VU1 : & VU0 ;
addr & = vunum ? 0x3fff : 0xfff ;
if ( vunum & & THREAD_VU1 ) {
vu1Thread . WriteDataMem ( addr , & data , sizeof ( u8 ) ) ;
return ;
2009-02-09 21:15:56 +00:00
}
2011-08-12 02:31:49 +00:00
vu - > Mem [ addr ] = data ;
}
template < int vunum > static void __fc vuDataWrite16 ( u32 addr , mem16_t data ) {
VURegs * vu = vunum ? & VU1 : & VU0 ;
addr & = vunum ? 0x3fff : 0xfff ;
if ( vunum & & THREAD_VU1 ) {
vu1Thread . WriteDataMem ( addr , & data , sizeof ( u16 ) ) ;
return ;
}
* ( u16 * ) & vu - > Mem [ addr ] = data ;
}
template < int vunum > static void __fc vuDataWrite32 ( u32 addr , mem32_t data ) {
VURegs * vu = vunum ? & VU1 : & VU0 ;
addr & = vunum ? 0x3fff : 0xfff ;
if ( vunum & & THREAD_VU1 ) {
vu1Thread . WriteDataMem ( addr , & data , sizeof ( u32 ) ) ;
return ;
}
* ( u32 * ) & vu - > Mem [ addr ] = data ;
}
template < int vunum > static void __fc vuDataWrite64 ( u32 addr , const mem64_t * data ) {
VURegs * vu = vunum ? & VU1 : & VU0 ;
addr & = vunum ? 0x3fff : 0xfff ;
if ( vunum & & THREAD_VU1 ) {
vu1Thread . WriteDataMem ( addr , ( void * ) data , sizeof ( u64 ) ) ;
return ;
}
* ( u64 * ) & vu - > Mem [ addr ] = data [ 0 ] ;
}
template < int vunum > static void __fc vuDataWrite128 ( u32 addr , const mem128_t * data ) {
VURegs * vu = vunum ? & VU1 : & VU0 ;
addr & = vunum ? 0x3fff : 0xfff ;
if ( vunum & & THREAD_VU1 ) {
vu1Thread . WriteDataMem ( addr , ( void * ) data , sizeof ( u128 ) ) ;
return ;
}
CopyQWC ( & vu - > Mem [ addr ] , data ) ;
2009-02-09 21:15:56 +00:00
}
2011-08-12 02:31:49 +00:00
2009-04-28 05:56:22 +00:00
void memSetPageAddr ( u32 vaddr , u32 paddr )
2009-02-09 21:15:56 +00:00
{
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
//Console.WriteLn("memSetPageAddr: %8.8x -> %8.8x", vaddr, paddr);
2009-02-09 21:15:56 +00:00
vtlb_VMap ( vaddr , paddr , 0x1000 ) ;
}
2009-04-28 05:56:22 +00:00
void memClearPageAddr ( u32 vaddr )
2009-02-09 21:15:56 +00:00
{
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
//Console.WriteLn("memClearPageAddr: %8.8x", vaddr);
2009-02-09 21:15:56 +00:00
vtlb_VMapUnmap ( vaddr , 0x1000 ) ; // -> whut ?
# ifdef FULLTLB
2009-07-30 23:50:39 +00:00
// memLUTRK[vaddr >> 12] = 0;
// memLUTWK[vaddr >> 12] = 0;
2009-02-09 21:15:56 +00:00
# endif
}
///////////////////////////////////////////////////////////////////////////
// PS2 Memory Init / Reset / Shutdown
2010-01-23 17:13:03 +00:00
class mmap_PageFaultHandler : public EventListener_PageFault
2010-01-22 15:22:01 +00:00
{
2010-11-16 00:22:18 +00:00
public :
2010-01-22 15:22:01 +00:00
void OnPageFaultEvent ( const PageFaultInfo & info , bool & handled ) ;
} ;
2010-10-22 19:47:02 +00:00
static mmap_PageFaultHandler * mmap_faultHandler = NULL ;
2009-10-23 20:24:59 +00:00
2010-08-16 15:57:01 +00:00
EEVM_MemoryAllocMess * eeMem = NULL ;
2010-08-27 03:21:16 +00:00
__pagealigned u8 eeHw [ Ps2MemSize : : Hardware ] ;
2009-02-09 21:15:56 +00:00
2009-10-09 15:17:53 +00:00
void memBindConditionalHandlers ( )
{
if ( hw_by_page [ 0xf ] = = - 1 ) return ;
2010-08-31 09:31:47 +00:00
if ( EmuConfig . Speedhacks . IntcStat )
{
vtlbMemR16FP * page0F16 ( hwRead16_page_0F_INTC_HACK ) ;
vtlbMemR32FP * page0F32 ( hwRead32_page_0F_INTC_HACK ) ;
//vtlbMemR64FP* page0F64(hwRead64_generic_INTC_HACK);
vtlb_ReassignHandler ( hw_by_page [ 0xf ] ,
hwRead8 < 0x0f > , page0F16 , page0F32 , hwRead64 < 0x0f > , hwRead128 < 0x0f > ,
hwWrite8 < 0x0f > , hwWrite16 < 0x0f > , hwWrite32 < 0x0f > , hwWrite64 < 0x0f > , hwWrite128 < 0x0f >
) ;
}
else
{
vtlbMemR16FP * page0F16 ( hwRead16 < 0x0f > ) ;
vtlbMemR32FP * page0F32 ( hwRead32 < 0x0f > ) ;
//vtlbMemR64FP* page0F64(hwRead64<0x0f>);
vtlb_ReassignHandler ( hw_by_page [ 0xf ] ,
hwRead8 < 0x0f > , page0F16 , page0F32 , hwRead64 < 0x0f > , hwRead128 < 0x0f > ,
hwWrite8 < 0x0f > , hwWrite16 < 0x0f > , hwWrite32 < 0x0f > , hwWrite64 < 0x0f > , hwWrite128 < 0x0f >
) ;
}
2009-10-09 15:17:53 +00:00
}
2010-11-15 14:05:02 +00:00
// --------------------------------------------------------------------------------------
// eeMemoryReserve (implementations)
// --------------------------------------------------------------------------------------
eeMemoryReserve : : eeMemoryReserve ( )
: _parent ( L " EE Main Memory " , sizeof ( * eeMem ) )
{
}
void eeMemoryReserve : : Reserve ( )
{
_parent : : Reserve ( HostMemoryMap : : EEmem ) ;
//_parent::Reserve(EmuConfig.HostMap.IOP);
2010-11-16 04:53:52 +00:00
}
void eeMemoryReserve : : Commit ( )
{
_parent : : Commit ( ) ;
2010-11-15 14:05:02 +00:00
eeMem = ( EEVM_MemoryAllocMess * ) m_reserve . GetPtr ( ) ;
}
2009-02-09 21:15:56 +00:00
// Resets memory mappings, unmaps TLBs, reloads bios roms, etc.
2010-11-15 14:05:02 +00:00
void eeMemoryReserve : : Reset ( )
2009-02-09 21:15:56 +00:00
{
2011-08-12 02:31:49 +00:00
if ( ! mmap_faultHandler ) {
pxAssert ( Source_PageFault ) ;
2010-11-15 14:05:02 +00:00
mmap_faultHandler = new mmap_PageFaultHandler ( ) ;
}
_parent : : Reset ( ) ;
2009-02-09 21:15:56 +00:00
// Note!! Ideally the vtlb should only be initialized once, and then subsequent
// resets of the system hardware would only clear vtlb mappings, but since the
// rest of the emu is not really set up to support a "soft" reset of that sort
// we opt for the hard/safe version.
2010-11-15 14:05:02 +00:00
pxAssume ( eeMem ) ;
2010-09-23 19:44:55 +00:00
2009-02-09 21:15:56 +00:00
# ifdef ENABLECACHE
memset ( pCache , 0 , sizeof ( _cacheS ) * 64 ) ;
# endif
vtlb_Init ( ) ;
2010-04-22 00:11:53 +00:00
null_handler = vtlb_RegisterHandler ( nullRead8 , nullRead16 , nullRead32 , nullRead64 , nullRead128 ,
nullWrite8 , nullWrite16 , nullWrite32 , nullWrite64 , nullWrite128 ) ;
2009-05-04 19:04:21 +00:00
tlb_fallback_0 = vtlb_RegisterHandlerTempl1 ( _ext_mem , 0 ) ;
tlb_fallback_3 = vtlb_RegisterHandlerTempl1 ( _ext_mem , 3 ) ;
tlb_fallback_4 = vtlb_RegisterHandlerTempl1 ( _ext_mem , 4 ) ;
tlb_fallback_5 = vtlb_RegisterHandlerTempl1 ( _ext_mem , 5 ) ;
tlb_fallback_7 = vtlb_RegisterHandlerTempl1 ( _ext_mem , 7 ) ;
tlb_fallback_8 = vtlb_RegisterHandlerTempl1 ( _ext_mem , 8 ) ;
2009-02-09 21:15:56 +00:00
// Dynarec versions of VUs
2010-07-31 22:42:24 +00:00
vu0_micro_mem = vtlb_RegisterHandlerTempl1 ( vuMicro , 0 ) ;
vu1_micro_mem = vtlb_RegisterHandlerTempl1 ( vuMicro , 1 ) ;
2011-08-12 02:31:49 +00:00
vu1_data_mem = ( 1 | | THREAD_VU1 ) ? vtlb_RegisterHandlerTempl1 ( vuData , 1 ) : NULL ;
2009-05-04 19:04:21 +00:00
//////////////////////////////////////////////////////////////////////////////////////////
// IOP's "secret" Hardware Register mapping, accessible from the EE (and meant for use
// by debugging or BIOS only). The IOP's hw regs are divided into three main pages in
// the 0x1f80 segment, and then another oddball page for CDVD in the 0x1f40 segment.
//
using namespace IopMemory ;
tlb_fallback_2 = vtlb_RegisterHandler (
iopHwRead8_generic , iopHwRead16_generic , iopHwRead32_generic , _ext_memRead64 < 2 > , _ext_memRead128 < 2 > ,
iopHwWrite8_generic , iopHwWrite16_generic , iopHwWrite32_generic , _ext_memWrite64 < 2 > , _ext_memWrite128 < 2 >
) ;
iopHw_by_page_01 = vtlb_RegisterHandler (
iopHwRead8_Page1 , iopHwRead16_Page1 , iopHwRead32_Page1 , _ext_memRead64 < 2 > , _ext_memRead128 < 2 > ,
iopHwWrite8_Page1 , iopHwWrite16_Page1 , iopHwWrite32_Page1 , _ext_memWrite64 < 2 > , _ext_memWrite128 < 2 >
) ;
iopHw_by_page_03 = vtlb_RegisterHandler (
iopHwRead8_Page3 , iopHwRead16_Page3 , iopHwRead32_Page3 , _ext_memRead64 < 2 > , _ext_memRead128 < 2 > ,
iopHwWrite8_Page3 , iopHwWrite16_Page3 , iopHwWrite32_Page3 , _ext_memWrite64 < 2 > , _ext_memWrite128 < 2 >
) ;
iopHw_by_page_08 = vtlb_RegisterHandler (
iopHwRead8_Page8 , iopHwRead16_Page8 , iopHwRead32_Page8 , _ext_memRead64 < 2 > , _ext_memRead128 < 2 > ,
iopHwWrite8_Page8 , iopHwWrite16_Page8 , iopHwWrite32_Page8 , _ext_memWrite64 < 2 > , _ext_memWrite128 < 2 >
) ;
2009-02-09 21:15:56 +00:00
// psHw Optimized Mappings
// The HW Registers have been split into pages to improve optimization.
2010-08-31 05:22:26 +00:00
# define hwHandlerTmpl(page) \
hwRead8 < page > , hwRead16 < page > , hwRead32 < page > , hwRead64 < page > , hwRead128 < page > , \
hwWrite8 < page > , hwWrite16 < page > , hwWrite32 < page > , hwWrite64 < page > , hwWrite128 < page >
hw_by_page [ 0x0 ] = vtlb_RegisterHandler ( hwHandlerTmpl ( 0x00 ) ) ;
hw_by_page [ 0x1 ] = vtlb_RegisterHandler ( hwHandlerTmpl ( 0x01 ) ) ;
hw_by_page [ 0x2 ] = vtlb_RegisterHandler ( hwHandlerTmpl ( 0x02 ) ) ;
hw_by_page [ 0x3 ] = vtlb_RegisterHandler ( hwHandlerTmpl ( 0x03 ) ) ;
hw_by_page [ 0x4 ] = vtlb_RegisterHandler ( hwHandlerTmpl ( 0x04 ) ) ;
hw_by_page [ 0x5 ] = vtlb_RegisterHandler ( hwHandlerTmpl ( 0x05 ) ) ;
hw_by_page [ 0x6 ] = vtlb_RegisterHandler ( hwHandlerTmpl ( 0x06 ) ) ;
hw_by_page [ 0x7 ] = vtlb_RegisterHandler ( hwHandlerTmpl ( 0x07 ) ) ;
hw_by_page [ 0x8 ] = vtlb_RegisterHandler ( hwHandlerTmpl ( 0x08 ) ) ;
hw_by_page [ 0x9 ] = vtlb_RegisterHandler ( hwHandlerTmpl ( 0x09 ) ) ;
hw_by_page [ 0xa ] = vtlb_RegisterHandler ( hwHandlerTmpl ( 0x0a ) ) ;
hw_by_page [ 0xb ] = vtlb_RegisterHandler ( hwHandlerTmpl ( 0x0b ) ) ;
hw_by_page [ 0xc ] = vtlb_RegisterHandler ( hwHandlerTmpl ( 0x0c ) ) ;
hw_by_page [ 0xd ] = vtlb_RegisterHandler ( hwHandlerTmpl ( 0x0d ) ) ;
hw_by_page [ 0xe ] = vtlb_RegisterHandler ( hwHandlerTmpl ( 0x0e ) ) ;
hw_by_page [ 0xf ] = vtlb_NewHandler ( ) ; // redefined later based on speedhacking prefs
2009-10-09 15:17:53 +00:00
memBindConditionalHandlers ( ) ;
2009-02-09 21:15:56 +00:00
//////////////////////////////////////////////////////////////////////
// GS Optimized Mappings
tlb_fallback_6 = vtlb_RegisterHandler (
_ext_memRead8 < 6 > , _ext_memRead16 < 6 > , _ext_memRead32 < 6 > , _ext_memRead64 < 6 > , _ext_memRead128 < 6 > ,
_ext_memWrite8 < 6 > , _ext_memWrite16 < 6 > , _ext_memWrite32 < 6 > , gsWrite64_generic , gsWrite128_generic
) ;
gs_page_0 = vtlb_RegisterHandler (
_ext_memRead8 < 6 > , _ext_memRead16 < 6 > , _ext_memRead32 < 6 > , _ext_memRead64 < 6 > , _ext_memRead128 < 6 > ,
_ext_memWrite8 < 6 > , _ext_memWrite16 < 6 > , _ext_memWrite32 < 6 > , gsWrite64_page_00 , gsWrite128_page_00
) ;
gs_page_1 = vtlb_RegisterHandler (
_ext_memRead8 < 6 > , _ext_memRead16 < 6 > , _ext_memRead32 < 6 > , _ext_memRead64 < 6 > , _ext_memRead128 < 6 > ,
_ext_memWrite8 < 6 > , _ext_memWrite16 < 6 > , _ext_memWrite32 < 6 > , gsWrite64_page_01 , gsWrite128_page_01
) ;
//vtlb_Reset();
// reset memLUT (?)
//vtlb_VMap(0x00000000,0x00000000,0x20000000);
//vtlb_VMapUnmap(0x20000000,0x60000000);
memMapPhy ( ) ;
memMapVUmicro ( ) ;
memMapKernelMem ( ) ;
memMapSupervisorMem ( ) ;
memMapUserMem ( ) ;
memSetKernelMode ( ) ;
vtlb_VMap ( 0x00000000 , 0x00000000 , 0x20000000 ) ;
vtlb_VMapUnmap ( 0x20000000 , 0x60000000 ) ;
2009-08-16 06:26:40 +00:00
LoadBIOS ( ) ;
2009-02-09 21:15:56 +00:00
}
2010-11-16 04:53:52 +00:00
void eeMemoryReserve : : Decommit ( )
{
_parent : : Decommit ( ) ;
eeMem = NULL ;
}
2010-11-15 14:05:02 +00:00
void eeMemoryReserve : : Release ( )
{
safe_delete ( mmap_faultHandler ) ;
_parent : : Release ( ) ;
eeMem = NULL ;
vtlb_Term ( ) ;
}
// ===========================================================================================
// Memory Protection and Block Checking, vtlb Style!
// ===========================================================================================
2009-05-17 03:57:18 +00:00
// For the first time code is recompiled (executed), the PS2 ram page for that code is
// protected using Virtual Memory (mprotect). If the game modifies its own code then this
// protection causes an *exception* to be raised (signal in Linux), which is handled by
// unprotecting the page and switching the recompiled block to "manual" protection.
//
// Manual protection uses a simple brute-force memcmp of the recompiled code to the code
// currently in RAM for *each time* the block is executed. Fool-proof, but slow, which
// is why we default to using the exception-based protection scheme described above.
//
// Why manual blocks? Because many games contain code and data in the same 4k page, so
// we *cannot* automatically recompile and reprotect pages, lest we end up recompiling and
// reprotecting them constantly (Which would be very slow). As a counter, the R5900 side
// of the block checking code does try to periodically re-protect blocks [going from manual
// back to protected], so that blocks which underwent a single invalidation don't need to
// incur a permanent performance penalty.
//
// Page Granularity:
// Fortunately for us MIPS and x86 use the same page granularity for TLB and memory
// protection, so we can use a 1:1 correspondence when protecting pages. Page granularity
// is 4096 (4k), which is why you'll see a lot of 0xfff's, >><< 12's, and 0x1000's in the
// code below.
//
enum vtlb_ProtectionMode
{
ProtMode_None = 0 , // page is 'unaccounted' -- neither protected nor unprotected
ProtMode_Write , // page is under write protection (exception handler)
ProtMode_Manual // page is under manual protection (self-checked at execution)
} ;
struct vtlb_PageProtectionInfo
{
2010-10-22 16:23:52 +00:00
// Ram De-mapping -- used to convert fully translated/mapped offsets (which reside with
// in the eeMem->Main block) back into their originating ps2 physical ram address.
// Values are assigned when pages are marked for protection. since pages are automatically
// cleared and reset when TLB-remapped, stale values in this table (due to on-the-fly TLB
// changes) will be re-assigned the next time the page is accessed.
2009-05-17 03:57:18 +00:00
u32 ReverseRamMap ;
vtlb_ProtectionMode Mode ;
} ;
2010-10-22 16:23:52 +00:00
static __aligned16 vtlb_PageProtectionInfo m_PageProtectInfo [ Ps2MemSize : : MainRam > > 12 ] ;
2009-05-17 03:57:18 +00:00
// returns:
// -1 - unchecked block (resides in ROM, thus is integrity is constant)
// 0 - page is using Write protection
// 1 - page is using manual protection (recompiler must include execution-time
// self-checking of block integrity)
//
int mmap_GetRamPageInfo ( u32 paddr )
{
2011-07-24 13:02:50 +00:00
pxAssert ( eeMem ) ;
2010-11-16 04:53:52 +00:00
2009-05-17 03:57:18 +00:00
paddr & = ~ 0xfff ;
uptr ptr = ( uptr ) PSM ( paddr ) ;
2010-08-16 15:57:01 +00:00
uptr rampage = ptr - ( uptr ) eeMem - > Main ;
2009-05-17 03:57:18 +00:00
2010-10-22 16:23:52 +00:00
if ( rampage > = Ps2MemSize : : MainRam )
2009-02-09 21:15:56 +00:00
return - 1 ; //not in ram, no tracking done ...
2009-05-17 03:57:18 +00:00
rampage > > = 12 ;
return ( m_PageProtectInfo [ rampage ] . Mode = = ProtMode_Manual ) ? 1 : 0 ;
2009-02-09 21:15:56 +00:00
}
2010-10-22 16:23:52 +00:00
// paddr - physically mapped PS2 address
2009-05-17 03:57:18 +00:00
void mmap_MarkCountedRamPage ( u32 paddr )
2009-02-09 21:15:56 +00:00
{
2011-07-24 13:02:50 +00:00
pxAssert ( eeMem ) ;
2010-11-16 04:53:52 +00:00
2009-05-17 03:57:18 +00:00
paddr & = ~ 0xfff ;
2009-03-01 03:30:19 +00:00
2009-05-17 03:57:18 +00:00
uptr ptr = ( uptr ) PSM ( paddr ) ;
2010-08-16 15:57:01 +00:00
int rampage = ( ptr - ( uptr ) eeMem - > Main ) > > 12 ;
2009-02-09 21:15:56 +00:00
2010-10-22 16:23:52 +00:00
// Important: Update the ReverseRamMap here because TLB changes could alter the paddr
// mapping into eeMem->Main.
2009-05-17 03:57:18 +00:00
m_PageProtectInfo [ rampage ] . ReverseRamMap = paddr ;
2009-02-09 21:15:56 +00:00
2009-05-17 03:57:18 +00:00
if ( m_PageProtectInfo [ rampage ] . Mode = = ProtMode_Write )
return ; // skip town if we're already protected.
2010-08-06 05:46:09 +00:00
eeRecPerfLog . Write ( ( m_PageProtectInfo [ rampage ] . Mode = = ProtMode_Manual ) ?
" Re-protecting page @ 0x%05x " : " Protected page @ 0x%05x " ,
2009-10-29 13:32:40 +00:00
paddr > > 12
) ;
2009-05-17 03:57:18 +00:00
m_PageProtectInfo [ rampage ] . Mode = ProtMode_Write ;
2010-10-22 16:23:52 +00:00
HostSys : : MemProtect ( & eeMem - > Main [ rampage < < 12 ] , __pagesize , PageAccess_ReadOnly ( ) ) ;
2009-02-09 21:15:56 +00:00
}
2009-10-23 20:24:59 +00:00
// offset - offset of address relative to psM.
2010-08-06 05:46:09 +00:00
// All recompiled blocks belonging to the page are cleared, and any new blocks recompiled
// from code residing in this page will use manual protection.
2010-08-09 04:10:38 +00:00
static __fi void mmap_ClearCpuBlock ( uint offset )
2009-02-09 21:15:56 +00:00
{
2011-07-24 13:02:50 +00:00
pxAssert ( eeMem ) ;
2010-11-16 04:53:52 +00:00
2009-05-17 03:57:18 +00:00
int rampage = offset > > 12 ;
2009-04-28 05:56:22 +00:00
2009-05-17 03:57:18 +00:00
// Assertion: This function should never be run on a block that's already under
// manual protection. Indicates a logic error in the recompiler or protection code.
2009-10-23 20:24:59 +00:00
pxAssertMsg ( m_PageProtectInfo [ rampage ] . Mode ! = ProtMode_Manual ,
" Attempted to clear a block that is already under manual protection. " ) ;
2009-05-17 03:57:18 +00:00
2010-10-22 16:23:52 +00:00
HostSys : : MemProtect ( & eeMem - > Main [ rampage < < 12 ] , __pagesize , PageAccess_ReadWrite ( ) ) ;
2009-05-17 03:57:18 +00:00
m_PageProtectInfo [ rampage ] . Mode = ProtMode_Manual ;
Cpu - > Clear ( m_PageProtectInfo [ rampage ] . ReverseRamMap , 0x400 ) ;
}
2010-01-22 15:22:01 +00:00
void mmap_PageFaultHandler : : OnPageFaultEvent ( const PageFaultInfo & info , bool & handled )
2009-10-23 20:24:59 +00:00
{
2011-07-24 13:02:50 +00:00
pxAssert ( eeMem ) ;
2010-11-16 04:53:52 +00:00
2009-10-23 20:24:59 +00:00
// get bad virtual address
2010-08-16 15:57:01 +00:00
uptr offset = info . addr - ( uptr ) eeMem - > Main ;
2010-10-22 16:23:52 +00:00
if ( offset > = Ps2MemSize : : MainRam ) return ;
2009-10-23 20:24:59 +00:00
mmap_ClearCpuBlock ( offset ) ;
2010-01-22 15:22:01 +00:00
handled = true ;
2009-10-23 20:24:59 +00:00
}
2009-05-17 03:57:18 +00:00
// Clears all block tracking statuses, manual protection flags, and write protection.
2009-10-23 20:24:59 +00:00
// This does not clear any recompiler blocks. It is assumed (and necessary) for the caller
2009-05-17 03:57:18 +00:00
// to ensure the EErec is also reset in conjunction with calling this function.
2010-08-06 05:46:09 +00:00
// (this function is called by default from the eerecReset).
2009-05-17 03:57:18 +00:00
void mmap_ResetBlockTracking ( )
{
2010-08-06 05:46:09 +00:00
//DbgCon.WriteLn( "vtlb/mmap: Block Tracking reset..." );
2009-09-23 12:53:32 +00:00
memzero ( m_PageProtectInfo ) ;
2010-11-16 04:53:52 +00:00
if ( eeMem ) HostSys : : MemProtect ( eeMem - > Main , Ps2MemSize : : MainRam , PageAccess_ReadWrite ( ) ) ;
2009-04-28 05:56:22 +00:00
}