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

Diff of /trunk/pcsx2/Memory.cpp

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

revision 62 by william, Tue Sep 7 11:08:22 2010 UTC revision 280 by william, Thu Dec 23 12:02:12 2010 UTC
# Line 40  BIOS Line 40  BIOS
40  #include "IopCommon.h"  #include "IopCommon.h"
41  #include "VUmicro.h"  #include "VUmicro.h"
42  #include "GS.h"  #include "GS.h"
 #include "System/PageFaultSource.h"  
43    
44  #include "ps2/HwInternal.h"  #include "ps2/HwInternal.h"
45  #include "ps2/BiosTools.h"  #include "ps2/BiosTools.h"
46    
47    #include "Utilities/PageFaultSource.h"
48    
49  #ifdef ENABLECACHE  #ifdef ENABLECACHE
50  #include "Cache.h"  #include "Cache.h"
51  #endif  #endif
# Line 91  static vtlbHandler Line 92  static vtlbHandler
92          null_handler,          null_handler,
93    
94          tlb_fallback_0,          tlb_fallback_0,
         tlb_fallback_1,  
95          tlb_fallback_2,          tlb_fallback_2,
96          tlb_fallback_3,          tlb_fallback_3,
97          tlb_fallback_4,          tlb_fallback_4,
# Line 137  void memMapVUmicro() Line 137  void memMapVUmicro()
137  void memMapPhy()  void memMapPhy()
138  {  {
139          // Main memory          // Main memory
140          vtlb_MapBlock(eeMem->Main,      0x00000000,Ps2MemSize::Base);//mirrored on first 256 mb ?          vtlb_MapBlock(eeMem->Main,      0x00000000,Ps2MemSize::MainRam);//mirrored on first 256 mb ?
141          // High memory, uninstalled on the configuration we emulate          // High memory, uninstalled on the configuration we emulate
142          vtlb_MapHandler(null_handler, Ps2MemSize::Base, 0x10000000 - Ps2MemSize::Base);          vtlb_MapHandler(null_handler, Ps2MemSize::MainRam, 0x10000000 - Ps2MemSize::MainRam);
143    
144          // Various ROMs (all read-only)          // Various ROMs (all read-only)
145          vtlb_MapBlock(eeMem->ROM,       0x1fc00000,Ps2MemSize::Rom);          vtlb_MapBlock(eeMem->ROM,       0x1fc00000,Ps2MemSize::Rom);
# Line 150  void memMapPhy() Line 150  void memMapPhy()
150          // IOP memory          // IOP memory
151          // (used by the EE Bios Kernel during initial hardware initialization, Apps/Games          // (used by the EE Bios Kernel during initial hardware initialization, Apps/Games
152          //  are "supposed" to use the thread-safe SIF instead.)          //  are "supposed" to use the thread-safe SIF instead.)
153          vtlb_MapBlock(psxM,0x1c000000,0x00800000);          vtlb_MapBlock(iopMem->Main,0x1c000000,0x00800000);
154    
155          // Generic Handlers; These fallback to mem* stuff...          // Generic Handlers; These fallback to mem* stuff...
156          vtlb_MapHandler(tlb_fallback_7,0x14000000,0x10000);          vtlb_MapHandler(tlb_fallback_7,0x14000000, _64kb);
157          vtlb_MapHandler(tlb_fallback_4,0x18000000,0x10000);          vtlb_MapHandler(tlb_fallback_4,0x18000000, _64kb);
158          vtlb_MapHandler(tlb_fallback_5,0x1a000000,0x10000);          vtlb_MapHandler(tlb_fallback_5,0x1a000000, _64kb);
159          vtlb_MapHandler(tlb_fallback_6,0x12000000,0x10000);          vtlb_MapHandler(tlb_fallback_6,0x12000000, _64kb);
160          vtlb_MapHandler(tlb_fallback_8,0x1f000000,0x10000);          vtlb_MapHandler(tlb_fallback_8,0x1f000000, _64kb);
161          vtlb_MapHandler(tlb_fallback_3,0x1f400000,0x10000);          vtlb_MapHandler(tlb_fallback_3,0x1f400000, _64kb);
162          vtlb_MapHandler(tlb_fallback_2,0x1f800000,0x10000);          vtlb_MapHandler(tlb_fallback_2,0x1f800000, _64kb);
163          vtlb_MapHandler(tlb_fallback_8,0x1f900000,0x10000);          vtlb_MapHandler(tlb_fallback_8,0x1f900000, _64kb);
164    
165          // Hardware Register Handlers : specialized/optimized per-page handling of HW register accesses          // Hardware Register Handlers : specialized/optimized per-page handling of HW register accesses
166          // (note that hw_by_page handles are assigned in memReset prior to calling this function)          // (note that hw_by_page handles are assigned in memReset prior to calling this function)
# Line 186  void memMapKernelMem() Line 186  void memMapKernelMem()
186          //lower 512 mb: direct map          //lower 512 mb: direct map
187          //vtlb_VMap(0x00000000,0x00000000,0x20000000);          //vtlb_VMap(0x00000000,0x00000000,0x20000000);
188          //0x8* mirror          //0x8* mirror
189          vtlb_VMap(0x80000000,0x00000000,0x20000000);          vtlb_VMap(0x80000000, 0x00000000, _1mb*512);
190          //0xa* mirror          //0xa* mirror
191          vtlb_VMap(0xA0000000,0x00000000,0x20000000);          vtlb_VMap(0xA0000000, 0x00000000, _1mb*512);
192  }  }
193    
194  //what do do with these ?  //what do do with these ?
# Line 578  void memClearPageAddr(u32 vaddr) Line 578  void memClearPageAddr(u32 vaddr)
578    
579  class mmap_PageFaultHandler : public EventListener_PageFault  class mmap_PageFaultHandler : public EventListener_PageFault
580  {  {
581  protected:  public:
582          void OnPageFaultEvent( const PageFaultInfo& info, bool& handled );          void OnPageFaultEvent( const PageFaultInfo& info, bool& handled );
583  };  };
584    
585  static mmap_PageFaultHandler mmap_faultHandler;  static mmap_PageFaultHandler* mmap_faultHandler = NULL;
586    
587  EEVM_MemoryAllocMess* eeMem = NULL;  EEVM_MemoryAllocMess* eeMem = NULL;
   
588  __pagealigned u8 eeHw[Ps2MemSize::Hardware];  __pagealigned u8 eeHw[Ps2MemSize::Hardware];
589    
 void memAlloc()  
 {  
         if( eeMem == NULL )  
                 eeMem = (EEVM_MemoryAllocMess*)vtlb_malloc( sizeof(*eeMem), 4096 );  
   
         if( eeMem == NULL)  
                 throw Exception::OutOfMemory( L"memAlloc > failed to allocate PS2's base ram/rom/scratchpad." );  
   
         Source_PageFault.Add( mmap_faultHandler );  
 }  
   
 void memShutdown()  
 {  
         Source_PageFault.Remove( mmap_faultHandler );  
   
         vtlb_free( eeMem, sizeof(*eeMem) );  
         eeMem = NULL;  
         vtlb_Term();  
 }  
590    
591  void memBindConditionalHandlers()  void memBindConditionalHandlers()
592  {  {
# Line 636  void memBindConditionalHandlers() Line 616  void memBindConditionalHandlers()
616          }          }
617  }  }
618    
619    
620    // --------------------------------------------------------------------------------------
621    //  eeMemoryReserve  (implementations)
622    // --------------------------------------------------------------------------------------
623    eeMemoryReserve::eeMemoryReserve()
624            : _parent( L"EE Main Memory", sizeof(*eeMem) )
625    {
626    }
627    
628    void eeMemoryReserve::Reserve()
629    {
630            _parent::Reserve(HostMemoryMap::EEmem);
631            //_parent::Reserve(EmuConfig.HostMap.IOP);
632    }
633    
634    void eeMemoryReserve::Commit()
635    {
636            _parent::Commit();
637            eeMem = (EEVM_MemoryAllocMess*)m_reserve.GetPtr();
638    }
639    
640  // Resets memory mappings, unmaps TLBs, reloads bios roms, etc.  // Resets memory mappings, unmaps TLBs, reloads bios roms, etc.
641  void memReset()  void eeMemoryReserve::Reset()
642  {  {
643          // VTLB Protection Preparations.          if (!mmap_faultHandler)
644          //HostSys::MemProtect( m_psAllMem, m_allMemSize, Protect_ReadWrite );          {
645                    pxAssume(Source_PageFault);
646                    mmap_faultHandler = new mmap_PageFaultHandler();
647            }
648            
649            _parent::Reset();
650    
651          // Note!!  Ideally the vtlb should only be initialized once, and then subsequent          // Note!!  Ideally the vtlb should only be initialized once, and then subsequent
652          // resets of the system hardware would only clear vtlb mappings, but since the          // resets of the system hardware would only clear vtlb mappings, but since the
653          // rest of the emu is not really set up to support a "soft" reset of that sort          // rest of the emu is not really set up to support a "soft" reset of that sort
654          // we opt for the hard/safe version.          // we opt for the hard/safe version.
655    
656          memzero( *eeMem );          pxAssume( eeMem );
657    
658  #ifdef ENABLECACHE  #ifdef ENABLECACHE
659          memset(pCache,0,sizeof(_cacheS)*64);          memset(pCache,0,sizeof(_cacheS)*64);
660  #endif  #endif
# Line 759  void memReset() Line 766  void memReset()
766          LoadBIOS();          LoadBIOS();
767  }  }
768    
769  //////////////////////////////////////////////////////////////////////////////////////////  void eeMemoryReserve::Decommit()
770  // Memory Protection and Block Checking, vtlb Style!  {
771  //          _parent::Decommit();
772            eeMem = NULL;
773    }
774    
775    void eeMemoryReserve::Release()
776    {
777            safe_delete(mmap_faultHandler);
778            _parent::Release();
779            eeMem = NULL;
780            vtlb_Term();
781    }
782    
783    
784    // ===========================================================================================
785    //  Memory Protection and Block Checking, vtlb Style!
786    // ===========================================================================================
787  // For the first time code is recompiled (executed), the PS2 ram page for that code is  // For the first time code is recompiled (executed), the PS2 ram page for that code is
788  // protected using Virtual Memory (mprotect).  If the game modifies its own code then this  // protected using Virtual Memory (mprotect).  If the game modifies its own code then this
789  // protection causes an *exception* to be raised (signal in Linux), which is handled by  // protection causes an *exception* to be raised (signal in Linux), which is handled by
# Line 794  enum vtlb_ProtectionMode Line 816  enum vtlb_ProtectionMode
816    
817  struct vtlb_PageProtectionInfo  struct vtlb_PageProtectionInfo
818  {  {
819          // Ram De-mapping -- used to convert fully translated/mapped offsets into psM back          // Ram De-mapping -- used to convert fully translated/mapped offsets (which reside with
820          // into their originating ps2 physical ram address.  Values are assigned when pages          // in the eeMem->Main block) back into their originating ps2 physical ram address.
821          // are marked for protection.          // Values are assigned when pages are marked for protection.  since pages are automatically
822            // cleared and reset when TLB-remapped, stale values in this table (due to on-the-fly TLB
823            // changes) will be re-assigned the next time the page is accessed.
824          u32 ReverseRamMap;          u32 ReverseRamMap;
825    
826          vtlb_ProtectionMode Mode;          vtlb_ProtectionMode Mode;
827  };  };
828    
829  static __aligned16 vtlb_PageProtectionInfo m_PageProtectInfo[Ps2MemSize::Base >> 12];  static __aligned16 vtlb_PageProtectionInfo m_PageProtectInfo[Ps2MemSize::MainRam >> 12];
830    
831    
832  // returns:  // returns:
# Line 813  static __aligned16 vtlb_PageProtectionIn Line 837  static __aligned16 vtlb_PageProtectionIn
837  //  //
838  int mmap_GetRamPageInfo( u32 paddr )  int mmap_GetRamPageInfo( u32 paddr )
839  {  {
840            pxAssume( eeMem );
841    
842          paddr &= ~0xfff;          paddr &= ~0xfff;
843    
844          uptr ptr = (uptr)PSM( paddr );          uptr ptr = (uptr)PSM( paddr );
845          uptr rampage = ptr - (uptr)eeMem->Main;          uptr rampage = ptr - (uptr)eeMem->Main;
846    
847          if (rampage >= Ps2MemSize::Base)          if (rampage >= Ps2MemSize::MainRam)
848                  return -1; //not in ram, no tracking done ...                  return -1; //not in ram, no tracking done ...
849    
850          rampage >>= 12;          rampage >>= 12;
851          return ( m_PageProtectInfo[rampage].Mode == ProtMode_Manual ) ? 1 : 0;          return ( m_PageProtectInfo[rampage].Mode == ProtMode_Manual ) ? 1 : 0;
852  }  }
853    
854  // paddr - physically mapped address  // paddr - physically mapped PS2 address
855  void mmap_MarkCountedRamPage( u32 paddr )  void mmap_MarkCountedRamPage( u32 paddr )
856  {  {
857            pxAssume( eeMem );
858            
859          paddr &= ~0xfff;          paddr &= ~0xfff;
860    
861          uptr ptr = (uptr)PSM( paddr );          uptr ptr = (uptr)PSM( paddr );
862          int rampage = (ptr - (uptr)eeMem->Main) >> 12;          int rampage = (ptr - (uptr)eeMem->Main) >> 12;
863    
864          // Important: reassign paddr here, since TLB changes could alter the paddr->psM mapping          // Important: Update the ReverseRamMap here because TLB changes could alter the paddr
865          // (and clear blocks accordingly), but don't necessarily clear the protection status.          // mapping into eeMem->Main.
866    
867          m_PageProtectInfo[rampage].ReverseRamMap = paddr;          m_PageProtectInfo[rampage].ReverseRamMap = paddr;
868    
869          if( m_PageProtectInfo[rampage].Mode == ProtMode_Write )          if( m_PageProtectInfo[rampage].Mode == ProtMode_Write )
# Line 846  void mmap_MarkCountedRamPage( u32 paddr Line 875  void mmap_MarkCountedRamPage( u32 paddr
875          );          );
876    
877          m_PageProtectInfo[rampage].Mode = ProtMode_Write;          m_PageProtectInfo[rampage].Mode = ProtMode_Write;
878          HostSys::MemProtect( &eeMem->Main[rampage<<12], __pagesize, Protect_ReadOnly );          HostSys::MemProtect( &eeMem->Main[rampage<<12], __pagesize, PageAccess_ReadOnly() );
879  }  }
880    
881  // offset - offset of address relative to psM.  // offset - offset of address relative to psM.
# Line 854  void mmap_MarkCountedRamPage( u32 paddr Line 883  void mmap_MarkCountedRamPage( u32 paddr
883  // from code residing in this page will use manual protection.  // from code residing in this page will use manual protection.
884  static __fi void mmap_ClearCpuBlock( uint offset )  static __fi void mmap_ClearCpuBlock( uint offset )
885  {  {
886            pxAssume( eeMem );
887    
888          int rampage = offset >> 12;          int rampage = offset >> 12;
889    
890          // Assertion: This function should never be run on a block that's already under          // Assertion: This function should never be run on a block that's already under
# Line 861  static __fi void mmap_ClearCpuBlock( uin Line 892  static __fi void mmap_ClearCpuBlock( uin
892          pxAssertMsg( m_PageProtectInfo[rampage].Mode != ProtMode_Manual,          pxAssertMsg( m_PageProtectInfo[rampage].Mode != ProtMode_Manual,
893                  "Attempted to clear a block that is already under manual protection." );                  "Attempted to clear a block that is already under manual protection." );
894    
895          HostSys::MemProtect( &eeMem->Main[rampage<<12], __pagesize, Protect_ReadWrite );          HostSys::MemProtect( &eeMem->Main[rampage<<12], __pagesize, PageAccess_ReadWrite() );
896          m_PageProtectInfo[rampage].Mode = ProtMode_Manual;          m_PageProtectInfo[rampage].Mode = ProtMode_Manual;
897          Cpu->Clear( m_PageProtectInfo[rampage].ReverseRamMap, 0x400 );          Cpu->Clear( m_PageProtectInfo[rampage].ReverseRamMap, 0x400 );
898  }  }
899    
900  void mmap_PageFaultHandler::OnPageFaultEvent( const PageFaultInfo& info, bool& handled )  void mmap_PageFaultHandler::OnPageFaultEvent( const PageFaultInfo& info, bool& handled )
901  {  {
902            pxAssume( eeMem );
903    
904          // get bad virtual address          // get bad virtual address
905          uptr offset = info.addr - (uptr)eeMem->Main;          uptr offset = info.addr - (uptr)eeMem->Main;
906          if( offset >= Ps2MemSize::Base ) return;          if( offset >= Ps2MemSize::MainRam ) return;
907    
908          mmap_ClearCpuBlock( offset );          mmap_ClearCpuBlock( offset );
909          handled = true;          handled = true;
# Line 884  void mmap_ResetBlockTracking() Line 917  void mmap_ResetBlockTracking()
917  {  {
918          //DbgCon.WriteLn( "vtlb/mmap: Block Tracking reset..." );          //DbgCon.WriteLn( "vtlb/mmap: Block Tracking reset..." );
919          memzero( m_PageProtectInfo );          memzero( m_PageProtectInfo );
920          HostSys::MemProtect( eeMem->Main, Ps2MemSize::Base, Protect_ReadWrite );          if (eeMem) HostSys::MemProtect( eeMem->Main, Ps2MemSize::MainRam, PageAccess_ReadWrite() );
921  }  }

Legend:
Removed from v.62  
changed lines
  Added in v.280

  ViewVC Help
Powered by ViewVC 1.1.22