/[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

revision 31 by william, Tue Sep 7 03:24:11 2010 UTC revision 280 by william, Thu Dec 23 12:02:12 2010 UTC
# Line 33  Line 33 
33  #include "Common.h"  #include "Common.h"
34  #include "vtlb.h"  #include "vtlb.h"
35  #include "COP0.h"  #include "COP0.h"
   
36  #include "R5900Exceptions.h"  #include "R5900Exceptions.h"
37    
38    #include "Utilities/MemsetFast.inl"
39    
40  using namespace R5900;  using namespace R5900;
41  using namespace vtlb_private;  using namespace vtlb_private;
42    
43  #ifdef PCSX2_DEVBUILD  #define verify pxAssume
 #define verify(x) {if (!(x)) { (*(u8*)0)=3; }}  
 #else  
 #define verify jASSUME  
 #endif  
44    
45  namespace vtlb_private  namespace vtlb_private
46  {  {
47          __aligned(64) MapData vtlbdata;          __aligned(64) MapData vtlbdata;
48  }  }
49    
50  vtlbHandler vtlbHandlerCount=0;  static vtlbHandler vtlbHandlerCount = 0;
51    
52  vtlbHandler DefaultPhyHandler;  static vtlbHandler DefaultPhyHandler;
53  vtlbHandler UnmappedVirtHandler0;  static vtlbHandler UnmappedVirtHandler0;
54  vtlbHandler UnmappedVirtHandler1;  static vtlbHandler UnmappedVirtHandler1;
55  vtlbHandler UnmappedPhyHandler0;  static vtlbHandler UnmappedPhyHandler0;
56  vtlbHandler UnmappedPhyHandler1;  static vtlbHandler UnmappedPhyHandler1;
57    
58    
59  //////////////////////////////////////////////////////////////////////////////////////////  // --------------------------------------------------------------------------------------
60  // Interpreter Implementations of VTLB Memory Operations.  // Interpreter Implementations of VTLB Memory Operations.
61    // --------------------------------------------------------------------------------------
62  // See recVTLB.cpp for the dynarec versions.  // See recVTLB.cpp for the dynarec versions.
63    
64  // Interpreted VTLB lookup for 8, 16, and 32 bit accesses  template< typename DataType >
65  template<int DataSize,typename DataType>  DataType __fastcall vtlb_memRead(u32 addr)
 __forceinline DataType __fastcall MemOp_r0(u32 addr)  
66  {  {
67            static const uint DataSize = sizeof(DataType) * 8;
68          u32 vmv=vtlbdata.vmap[addr>>VTLB_PAGE_BITS];          u32 vmv=vtlbdata.vmap[addr>>VTLB_PAGE_BITS];
69          s32 ppf=addr+vmv;          s32 ppf=addr+vmv;
70    
# Line 91  __forceinline DataType __fastcall MemOp_ Line 89  __forceinline DataType __fastcall MemOp_
89          return 0;               // technically unreachable, but suppresses warnings.          return 0;               // technically unreachable, but suppresses warnings.
90  }  }
91    
92  // ------------------------------------------------------------------------  void __fastcall vtlb_memRead64(u32 mem, mem64_t *out)
 // Interpreterd VTLB lookup for 64 and 128 bit accesses.  
 template<int DataSize,typename DataType>  
 __forceinline void __fastcall MemOp_r1(u32 addr, DataType* data)  
93  {  {
94          u32 vmv=vtlbdata.vmap[addr>>VTLB_PAGE_BITS];          u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
95          s32 ppf=addr+vmv;          s32 ppf=mem+vmv;
96    
97          if (!(ppf<0))          if (!(ppf<0))
98          {          {
99                  data[0]=*reinterpret_cast<DataType*>(ppf);                  *out = *(mem64_t*)ppf;
                 if (DataSize==128)  
                         data[1]=*reinterpret_cast<DataType*>(ppf+8);  
100          }          }
101          else          else
102          {          {
# Line 111  __forceinline void __fastcall MemOp_r1(u Line 104  __forceinline void __fastcall MemOp_r1(u
104                  u32 hand=(u8)vmv;                  u32 hand=(u8)vmv;
105                  u32 paddr=ppf-hand+0x80000000;                  u32 paddr=ppf-hand+0x80000000;
106                  //Console.WriteLn("Translated 0x%08X to 0x%08X", addr,paddr);                  //Console.WriteLn("Translated 0x%08X to 0x%08X", addr,paddr);
                 //return reinterpret_cast<TemplateHelper<DataSize,false>::HandlerType*>(RWFT[TemplateHelper<DataSize,false>::sidx][0][hand])(paddr,data);  
107    
108                  switch( DataSize )                  ((vtlbMemR64FP*)vtlbdata.RWFT[3][0][hand])(paddr, out);
109                  {          }
110                          case 64: ((vtlbMemR64FP*)vtlbdata.RWFT[3][0][hand])(paddr, data); break;  }
111                          case 128: ((vtlbMemR128FP*)vtlbdata.RWFT[4][0][hand])(paddr, data); break;  void __fastcall vtlb_memRead128(u32 mem, mem128_t *out)
112    {
113            u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
114            s32 ppf=mem+vmv;
115    
116                          jNO_DEFAULT;          if (!(ppf<0))
117                  }          {
118                    CopyQWC(out,(void*)ppf);
119            }
120            else
121            {
122                    //has to: translate, find function, call function
123                    u32 hand=(u8)vmv;
124                    u32 paddr=ppf-hand+0x80000000;
125                    //Console.WriteLn("Translated 0x%08X to 0x%08X", addr,paddr);
126    
127                    ((vtlbMemR128FP*)vtlbdata.RWFT[4][0][hand])(paddr, out);
128          }          }
129  }  }
130    
131  // ------------------------------------------------------------------------  template< typename DataType >
132  template<int DataSize,typename DataType>  void __fastcall vtlb_memWrite(u32 addr, DataType data)
 __forceinline void __fastcall MemOp_w0(u32 addr, DataType data)  
133  {  {
134            static const uint DataSize = sizeof(DataType) * 8;
135    
136          u32 vmv=vtlbdata.vmap[addr>>VTLB_PAGE_BITS];          u32 vmv=vtlbdata.vmap[addr>>VTLB_PAGE_BITS];
137          s32 ppf=addr+vmv;          s32 ppf=addr+vmv;
138          if (!(ppf<0))          if (!(ppf<0))
# Line 151  __forceinline void __fastcall MemOp_w0(u Line 157  __forceinline void __fastcall MemOp_w0(u
157          }          }
158  }  }
159    
160  // ------------------------------------------------------------------------  void __fastcall vtlb_memWrite64(u32 mem, const mem64_t* value)
 template<int DataSize,typename DataType>  
 __forceinline void __fastcall MemOp_w1(u32 addr,const DataType* data)  
161  {  {
162          verify(DataSize==128 || DataSize==64);          u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
163          u32 vmv=vtlbdata.vmap[addr>>VTLB_PAGE_BITS];          s32 ppf=mem+vmv;
         s32 ppf=addr+vmv;  
164          if (!(ppf<0))          if (!(ppf<0))
165          {          {
166                  *reinterpret_cast<DataType*>(ppf)=*data;                  *(mem64_t*)ppf = *value;
                 if (DataSize==128)  
                         *reinterpret_cast<DataType*>(ppf+8)=data[1];  
167          }          }
168          else          else
169          {          {
# Line 170  __forceinline void __fastcall MemOp_w1(u Line 171  __forceinline void __fastcall MemOp_w1(u
171                  u32 hand=(u8)vmv;                  u32 hand=(u8)vmv;
172                  u32 paddr=ppf-hand+0x80000000;                  u32 paddr=ppf-hand+0x80000000;
173                  //Console.WriteLn("Translated 0x%08X to 0x%08X", addr,paddr);                  //Console.WriteLn("Translated 0x%08X to 0x%08X", addr,paddr);
                 switch( DataSize )  
                 {  
                         case 64: return ((vtlbMemW64FP*)vtlbdata.RWFT[3][1][hand])(paddr, data);  
                         case 128: return ((vtlbMemW128FP*)vtlbdata.RWFT[4][1][hand])(paddr, data);  
174    
175                          jNO_DEFAULT;                  ((vtlbMemW64FP*)vtlbdata.RWFT[3][1][hand])(paddr, value);
                 }  
176          }          }
177  }  }
178    
179  mem8_t __fastcall vtlb_memRead8(u32 mem)  void __fastcall vtlb_memWrite128(u32 mem, const mem128_t *value)
180  {  {
181          return MemOp_r0<8,mem8_t>(mem);          u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
182            s32 ppf=mem+vmv;
183            if (!(ppf<0))
184            {
185                    CopyQWC((void*)ppf, value);
186            }
187            else
188            {
189                    //has to: translate, find function, call function
190                    u32 hand=(u8)vmv;
191                    u32 paddr=ppf-hand+0x80000000;
192                    //Console.WriteLn("Translated 0x%08X to 0x%08X", addr,paddr);
193    
194                    ((vtlbMemW128FP*)vtlbdata.RWFT[4][1][hand])(paddr, value);
195            }
196  }  }
197  mem16_t __fastcall vtlb_memRead16(u32 mem)  
198    template mem8_t vtlb_memRead<mem8_t>(u32 mem);
199    template mem16_t vtlb_memRead<mem16_t>(u32 mem);
200    template mem32_t vtlb_memRead<mem32_t>(u32 mem);
201    template void vtlb_memWrite<mem8_t>(u32 mem, mem8_t data);
202    template void vtlb_memWrite<mem16_t>(u32 mem, mem16_t data);
203    template void vtlb_memWrite<mem32_t>(u32 mem, mem32_t data);
204    
205    // --------------------------------------------------------------------------------------
206    //  TLB Miss / BusError Handlers
207    // --------------------------------------------------------------------------------------
208    // These are valid VM memory errors that should typically be handled by the VM itself via
209    // its own cpu exception system.
210    //
211    // [TODO]  Add first-chance debugging hooks to these exceptions!
212    //
213    // Important recompiler note: Mid-block Exception handling isn't reliable *yet* because
214    // memory ops don't flush the PC prior to invoking the indirect handlers.
215    
216    // Generates a tlbMiss Exception
217    static __ri void vtlb_Miss(u32 addr,u32 mode)
218  {  {
219          return MemOp_r0<16,mem16_t>(mem);          if( IsDevBuild )
220                    Cpu->ThrowCpuException( R5900Exception::TLBMiss( addr, !!mode ) );
221            else
222                    Console.Error( R5900Exception::TLBMiss( addr, !!mode ).FormatMessage() );
223  }  }
224  mem32_t __fastcall vtlb_memRead32(u32 mem)  
225    // BusError exception: more serious than a TLB miss.  If properly emulated the PS2 kernel
226    // itself would invoke a diagnostic/assertion screen that displays the cpu state at the
227    // time of the exception.
228    static __ri void vtlb_BusError(u32 addr,u32 mode)
229  {  {
230          return MemOp_r0<32,mem32_t>(mem);          if( IsDevBuild )
231                    Cpu->ThrowCpuException( R5900Exception::BusError( addr, !!mode ) );
232            else
233                    Console.Error( R5900Exception::TLBMiss( addr, !!mode ).FormatMessage() );
234  }  }
235  void __fastcall vtlb_memRead64(u32 mem, u64 *out)  
236    #define _tmpl(ret) template<typename OperandType, u32 saddr> ret __fastcall
237    
238    _tmpl(OperandType) vtlbUnmappedVReadSm(u32 addr)                                        { vtlb_Miss(addr|saddr,0); return 0; }
239    _tmpl(void) vtlbUnmappedVReadLg(u32 addr,OperandType* data)                     { vtlb_Miss(addr|saddr,0); }
240    _tmpl(void) vtlbUnmappedVWriteSm(u32 addr,OperandType data)                     { vtlb_Miss(addr|saddr,1); }
241    _tmpl(void) vtlbUnmappedVWriteLg(u32 addr,const OperandType* data)      { vtlb_Miss(addr|saddr,1); }
242    
243    _tmpl(OperandType) vtlbUnmappedPReadSm(u32 addr)                                        { vtlb_BusError(addr|saddr,0); return 0; }
244    _tmpl(void) vtlbUnmappedPReadLg(u32 addr,OperandType* data)                     { vtlb_BusError(addr|saddr,0); }
245    _tmpl(void) vtlbUnmappedPWriteSm(u32 addr,OperandType data)                     { vtlb_BusError(addr|saddr,1); }
246    _tmpl(void) vtlbUnmappedPWriteLg(u32 addr,const OperandType* data)      { vtlb_BusError(addr|saddr,1); }
247    
248    #undef _tmpl
249    
250    // --------------------------------------------------------------------------------------
251    //  VTLB mapping errors
252    // --------------------------------------------------------------------------------------
253    // These errors are assertion/logic errors that should never occur if PCSX2 has been initialized
254    // properly.  All addressable physical memory should be configured as TLBMiss or Bus Error.
255    //
256    
257    static mem8_t __fastcall vtlbDefaultPhyRead8(u32 addr)
258  {  {
259          return MemOp_r1<64,mem64_t>(mem,out);          pxFailDev(pxsFmt("(VTLB) Attempted read8 from unmapped physical address @ 0x%08X.", addr));
260            return 0;
261  }  }
262  void __fastcall vtlb_memRead128(u32 mem, u64 *out)  
263    static mem16_t __fastcall vtlbDefaultPhyRead16(u32 addr)
264  {  {
265          return MemOp_r1<128,mem128_t>(mem,out);          pxFailDev(pxsFmt("(VTLB) Attempted read16 from unmapped physical address @ 0x%08X.", addr));
266            return 0;
267  }  }
268  void __fastcall vtlb_memWrite8 (u32 mem, mem8_t value)  
269    static mem32_t __fastcall vtlbDefaultPhyRead32(u32 addr)
270  {  {
271          MemOp_w0<8,mem8_t>(mem,value);          pxFailDev(pxsFmt("(VTLB) Attempted read32 from unmapped physical address @ 0x%08X.", addr));
272            return 0;
273  }  }
274  void __fastcall vtlb_memWrite16(u32 mem, mem16_t value)  
275    static void __fastcall vtlbDefaultPhyRead64(u32 addr, mem64_t* dest)
276  {  {
277          MemOp_w0<16,mem16_t>(mem,value);          pxFailDev(pxsFmt("(VTLB) Attempted read64 from unmapped physical address @ 0x%08X.", addr));
278  }  }
279  void __fastcall vtlb_memWrite32(u32 mem, mem32_t value)  
280    static void __fastcall vtlbDefaultPhyRead128(u32 addr, mem128_t* dest)
281  {  {
282          MemOp_w0<32,mem32_t>(mem,value);          pxFailDev(pxsFmt("(VTLB) Attempted read128 from unmapped physical address @ 0x%08X.", addr));
283  }  }
284  void __fastcall vtlb_memWrite64(u32 mem, const mem64_t* value)  
285    static void __fastcall vtlbDefaultPhyWrite8(u32 addr, mem8_t data)
286  {  {
287          MemOp_w1<64,mem64_t>(mem,value);          pxFailDev(pxsFmt("(VTLB) Attempted write8 to unmapped physical address @ 0x%08X.", addr));
288  }  }
289  void __fastcall vtlb_memWrite128(u32 mem, const mem128_t *value)  
290    static void __fastcall vtlbDefaultPhyWrite16(u32 addr, mem16_t data)
291  {  {
292          MemOp_w1<128,mem128_t>(mem,value);          pxFailDev(pxsFmt("(VTLB) Attempted write16 to unmapped physical address @ 0x%08X.", addr));
293  }  }
294    
295  /////////////////////////////////////////////////////////////////////////  static void __fastcall vtlbDefaultPhyWrite32(u32 addr, mem32_t data)
 // Error / TLB Miss Handlers  
 //  
   
 static const char* _getModeStr( u32 mode )  
296  {  {
297          return (mode==0) ? "read" : "write";          pxFailDev(pxsFmt("(VTLB) Attempted write32 to unmapped physical address @ 0x%08X.", addr));
298  }  }
299    
300  // Generates a tlbMiss Exception  static void __fastcall vtlbDefaultPhyWrite64(u32 addr,const mem64_t* data)
301  // Note: Don't throw exceptions yet, they cause a crash when otherwise  {
302  // there would be a (slight) chance the game continues (rama).          pxFailDev(pxsFmt("(VTLB) Attempted write64 to unmapped physical address @ 0x%08X.", addr));
303  static __forceinline void vtlb_Miss(u32 addr,u32 mode)  }
 {  
         Console.Error( "vtlb miss : addr 0x%X, mode %d [%s]", addr, mode, _getModeStr(mode) );  
         //verify(false);  
         //throw R5900Exception::TLBMiss( addr, !!mode );  
 }  
   
 // Just dies a horrible death for now.  
 // Eventually should generate a BusError exception.  
 static __forceinline void vtlb_BusError(u32 addr,u32 mode)  
 {  
         Console.Error( "vtlb bus error : addr 0x%X, mode %d\n", addr, _getModeStr(mode) );  
         //verify(false);  
         throw R5900Exception::BusError( addr, !!mode );  
 }  
   
 ///// Virtual Mapping Errors (TLB Miss)  
 template<u32 saddr>  
 mem8_t __fastcall vtlbUnmappedVRead8(u32 addr) { vtlb_Miss(addr|saddr,0); return 0; }  
 template<u32 saddr>  
 mem16_t __fastcall vtlbUnmappedVRead16(u32 addr)  { vtlb_Miss(addr|saddr,0); return 0; }  
 template<u32 saddr>  
 mem32_t __fastcall vtlbUnmappedVRead32(u32 addr) { vtlb_Miss(addr|saddr,0); return 0; }  
 template<u32 saddr>  
 void __fastcall vtlbUnmappedVRead64(u32 addr,mem64_t* data) { vtlb_Miss(addr|saddr,0); }  
 template<u32 saddr>  
 void __fastcall vtlbUnmappedVRead128(u32 addr,mem128_t* data) { vtlb_Miss(addr|saddr,0); }  
 template<u32 saddr>  
 void __fastcall vtlbUnmappedVWrite8(u32 addr,mem8_t data) { vtlb_Miss(addr|saddr,1); }  
 template<u32 saddr>  
 void __fastcall vtlbUnmappedVWrite16(u32 addr,mem16_t data) { vtlb_Miss(addr|saddr,1); }  
 template<u32 saddr>  
 void __fastcall vtlbUnmappedVWrite32(u32 addr,mem32_t data) { vtlb_Miss(addr|saddr,1); }  
 template<u32 saddr>  
 void __fastcall vtlbUnmappedVWrite64(u32 addr,const mem64_t* data) { vtlb_Miss(addr|saddr,1); }  
 template<u32 saddr>  
 void __fastcall vtlbUnmappedVWrite128(u32 addr,const mem128_t* data) { vtlb_Miss(addr|saddr,1); }  
   
 ///// Physical Mapping Errors (Bus Error)  
 template<u32 saddr>  
 mem8_t __fastcall vtlbUnmappedPRead8(u32 addr) { vtlb_BusError(addr|saddr,0); return 0; }  
 template<u32 saddr>  
 mem16_t __fastcall vtlbUnmappedPRead16(u32 addr)  { vtlb_BusError(addr|saddr,0); return 0; }  
 template<u32 saddr>  
 mem32_t __fastcall vtlbUnmappedPRead32(u32 addr) { vtlb_BusError(addr|saddr,0); return 0; }  
 template<u32 saddr>  
 void __fastcall vtlbUnmappedPRead64(u32 addr,mem64_t* data) { vtlb_BusError(addr|saddr,0); }  
 template<u32 saddr>  
 void __fastcall vtlbUnmappedPRead128(u32 addr,mem128_t* data) { vtlb_BusError(addr|saddr,0); }  
 template<u32 saddr>  
 void __fastcall vtlbUnmappedPWrite8(u32 addr,mem8_t data) { vtlb_BusError(addr|saddr,1); }  
 template<u32 saddr>  
 void __fastcall vtlbUnmappedPWrite16(u32 addr,mem16_t data) { vtlb_BusError(addr|saddr,1); }  
 template<u32 saddr>  
 void __fastcall vtlbUnmappedPWrite32(u32 addr,mem32_t data) { vtlb_BusError(addr|saddr,1); }  
 template<u32 saddr>  
 void __fastcall vtlbUnmappedPWrite64(u32 addr,const mem64_t* data) { vtlb_BusError(addr|saddr,1); }  
 template<u32 saddr>  
 void __fastcall vtlbUnmappedPWrite128(u32 addr,const mem128_t* data) { vtlb_BusError(addr|saddr,1); }  
   
 ///// VTLB mapping errors (unmapped address spaces)  
 mem8_t __fastcall vtlbDefaultPhyRead8(u32 addr) { Console.Error("vtlbDefaultPhyRead8: 0x%X",addr); verify(false); return -1; }  
 mem16_t __fastcall vtlbDefaultPhyRead16(u32 addr)  { Console.Error("vtlbDefaultPhyRead16: 0x%X",addr); verify(false); return -1; }  
 mem32_t __fastcall vtlbDefaultPhyRead32(u32 addr) { Console.Error("vtlbDefaultPhyRead32: 0x%X",addr); verify(false); return -1; }  
 void __fastcall vtlbDefaultPhyRead64(u32 addr,mem64_t* data) { Console.Error("vtlbDefaultPhyRead64: 0x%X",addr); verify(false); }  
 void __fastcall vtlbDefaultPhyRead128(u32 addr,mem128_t* data) { Console.Error("vtlbDefaultPhyRead128: 0x%X",addr); verify(false); }  
   
 void __fastcall vtlbDefaultPhyWrite8(u32 addr,mem8_t data) { Console.Error("vtlbDefaultPhyWrite8: 0x%X",addr); verify(false); }  
 void __fastcall vtlbDefaultPhyWrite16(u32 addr,mem16_t data) { Console.Error("vtlbDefaultPhyWrite16: 0x%X",addr); verify(false); }  
 void __fastcall vtlbDefaultPhyWrite32(u32 addr,mem32_t data) { Console.Error("vtlbDefaultPhyWrite32: 0x%X",addr); verify(false); }  
 void __fastcall vtlbDefaultPhyWrite64(u32 addr,const mem64_t* data) { Console.Error("vtlbDefaultPhyWrite64: 0x%X",addr); verify(false); }  
 void __fastcall vtlbDefaultPhyWrite128(u32 addr,const mem128_t* data) { Console.Error("vtlbDefaultPhyWrite128: 0x%X",addr); verify(false); }  
304    
305    static void __fastcall vtlbDefaultPhyWrite128(u32 addr,const mem128_t* data)
306    {
307            pxFailDev(pxsFmt("(VTLB) Attempted write128 to unmapped physical address @ 0x%08X.", addr));
308    }
309    #undef _tmpl
310    
311  //////////////////////////////////////////////////////////////////////////////////////////  // ===========================================================================================
312  // VTLB Public API -- Init/Term/RegisterHandler stuff  //  VTLB Public API -- Init/Term/RegisterHandler stuff
313    // ===========================================================================================
314  //  //
315    
316  // Assigns or re-assigns the callbacks for a VTLB memory handler.  The handler defines specific behavior  // Assigns or re-assigns the callbacks for a VTLB memory handler.  The handler defines specific behavior
# Line 318  void __fastcall vtlbDefaultPhyWrite128(u Line 320  void __fastcall vtlbDefaultPhyWrite128(u
320  //  //
321  // Note: All handlers persist across calls to vtlb_Reset(), but are wiped/invalidated by calls to vtlb_Init()  // Note: All handlers persist across calls to vtlb_Reset(), but are wiped/invalidated by calls to vtlb_Init()
322  //  //
323  void vtlb_ReassignHandler( vtlbHandler rv,  __ri void vtlb_ReassignHandler( vtlbHandler rv,
324                   vtlbMemR8FP* r8,vtlbMemR16FP* r16,vtlbMemR32FP* r32,vtlbMemR64FP* r64,vtlbMemR128FP* r128,                                                             vtlbMemR8FP* r8,vtlbMemR16FP* r16,vtlbMemR32FP* r32,vtlbMemR64FP* r64,vtlbMemR128FP* r128,
325                   vtlbMemW8FP* w8,vtlbMemW16FP* w16,vtlbMemW32FP* w32,vtlbMemW64FP* w64,vtlbMemW128FP* w128 )                                                             vtlbMemW8FP* w8,vtlbMemW16FP* w16,vtlbMemW32FP* w32,vtlbMemW64FP* w64,vtlbMemW128FP* w128 )
326  {  {
327          vtlbdata.RWFT[0][0][rv] = (r8!=0) ? (void*)(r8): (void*)vtlbDefaultPhyRead8;          pxAssume(rv < VTLB_HANDLER_ITEMS);
328          vtlbdata.RWFT[1][0][rv] = (r16!=0)  ? (void*)r16: (void*)vtlbDefaultPhyRead16;  
329          vtlbdata.RWFT[2][0][rv] = (r32!=0)  ? (void*)r32: (void*)vtlbDefaultPhyRead32;          vtlbdata.RWFT[0][0][rv] = (void*)((r8!=0)   ? r8        : vtlbDefaultPhyRead8);
330          vtlbdata.RWFT[3][0][rv] = (r64!=0)  ? (void*)r64: (void*)vtlbDefaultPhyRead64;          vtlbdata.RWFT[1][0][rv] = (void*)((r16!=0)  ? r16       : vtlbDefaultPhyRead16);
331          vtlbdata.RWFT[4][0][rv] = (r128!=0) ? (void*)r128: (void*)vtlbDefaultPhyRead128;          vtlbdata.RWFT[2][0][rv] = (void*)((r32!=0)  ? r32       : vtlbDefaultPhyRead32);
332            vtlbdata.RWFT[3][0][rv] = (void*)((r64!=0)  ? r64       : vtlbDefaultPhyRead64);
333          vtlbdata.RWFT[0][0][rv] = (r8!=0)   ? (void*)r8:(void*)vtlbDefaultPhyRead8;          vtlbdata.RWFT[4][0][rv] = (void*)((r128!=0) ? r128      : vtlbDefaultPhyRead128);
334          vtlbdata.RWFT[1][0][rv] = (r16!=0)  ? (void*)r16:(void*)vtlbDefaultPhyRead16;  
335          vtlbdata.RWFT[2][0][rv] = (r32!=0)  ? (void*)r32:(void*)vtlbDefaultPhyRead32;          vtlbdata.RWFT[0][1][rv] = (void*)((w8!=0)   ? w8        : vtlbDefaultPhyWrite8);
336          vtlbdata.RWFT[3][0][rv] = (r64!=0)  ? (void*)r64:(void*)vtlbDefaultPhyRead64;          vtlbdata.RWFT[1][1][rv] = (void*)((w16!=0)  ? w16       : vtlbDefaultPhyWrite16);
337          vtlbdata.RWFT[4][0][rv] = (r128!=0) ? (void*)r128:(void*)vtlbDefaultPhyRead128;          vtlbdata.RWFT[2][1][rv] = (void*)((w32!=0)  ? w32       : vtlbDefaultPhyWrite32);
338            vtlbdata.RWFT[3][1][rv] = (void*)((w64!=0)  ? w64       : vtlbDefaultPhyWrite64);
339          vtlbdata.RWFT[0][1][rv] = (void*)((w8!=0)   ? w8:vtlbDefaultPhyWrite8);          vtlbdata.RWFT[4][1][rv] = (void*)((w128!=0) ? w128      : vtlbDefaultPhyWrite128);
         vtlbdata.RWFT[1][1][rv] = (void*)((w16!=0)  ? w16:vtlbDefaultPhyWrite16);  
         vtlbdata.RWFT[2][1][rv] = (void*)((w32!=0)  ? w32:vtlbDefaultPhyWrite32);  
         vtlbdata.RWFT[3][1][rv] = (void*)((w64!=0)  ? w64:vtlbDefaultPhyWrite64);  
         vtlbdata.RWFT[4][1][rv] = (void*)((w128!=0) ? w128:vtlbDefaultPhyWrite128);  
340  }  }
341    
342  vtlbHandler vtlb_NewHandler()  vtlbHandler vtlb_NewHandler()
343  {  {
344          pxAssertDev( vtlbHandlerCount < 127, "VTLB allowed handler count exceeded!" );          pxAssertDev( vtlbHandlerCount < VTLB_HANDLER_ITEMS, "VTLB handler count overflow!" );
345          return vtlbHandlerCount++;          return vtlbHandlerCount++;
346  }  }
347    
# Line 356  vtlbHandler vtlb_NewHandler() Line 354  vtlbHandler vtlb_NewHandler()
354  //  //
355  // Returns a handle for the newly created handler  See vtlb_MapHandler for use of the return value.  // Returns a handle for the newly created handler  See vtlb_MapHandler for use of the return value.
356  //  //
357  vtlbHandler vtlb_RegisterHandler(       vtlbMemR8FP* r8,vtlbMemR16FP* r16,vtlbMemR32FP* r32,vtlbMemR64FP* r64,vtlbMemR128FP* r128,  __ri vtlbHandler vtlb_RegisterHandler(  vtlbMemR8FP* r8,vtlbMemR16FP* r16,vtlbMemR32FP* r32,vtlbMemR64FP* r64,vtlbMemR128FP* r128,
358                                                                          vtlbMemW8FP* w8,vtlbMemW16FP* w16,vtlbMemW32FP* w32,vtlbMemW64FP* w64,vtlbMemW128FP* w128)                                                                                  vtlbMemW8FP* w8,vtlbMemW16FP* w16,vtlbMemW32FP* w32,vtlbMemW64FP* w64,vtlbMemW128FP* w128)
359  {  {
360          vtlbHandler rv = vtlb_NewHandler();          vtlbHandler rv = vtlb_NewHandler();
361          vtlb_ReassignHandler( rv, r8, r16, r32, r64, r128, w8, w16, w32, w64, w128 );          vtlb_ReassignHandler( rv, r8, r16, r32, r64, r128, w8, w16, w32, w64, w128 );
# Line 365  vtlbHandler vtlb_RegisterHandler(      vtlbMe Line 363  vtlbHandler vtlb_RegisterHandler(      vtlbMe
363  }  }
364    
365    
 //////////////////////////////////////////////////////////////////////////////////////////  
366  // Maps the given hander (created with vtlb_RegisterHandler) to the specified memory region.  // Maps the given hander (created with vtlb_RegisterHandler) to the specified memory region.
367  // New mappings always assume priority over previous mappings, so place "generic" mappings for  // New mappings always assume priority over previous mappings, so place "generic" mappings for
368  // large areas of memory first, and then specialize specific small regions of memory afterward.  // large areas of memory first, and then specialize specific small regions of memory afterward.
# Line 373  vtlbHandler vtlb_RegisterHandler(      vtlbMe Line 370  vtlbHandler vtlb_RegisterHandler(      vtlbMe
370  // function.  // function.
371  //  //
372  // The memory region start and size parameters must be pagesize aligned.  // The memory region start and size parameters must be pagesize aligned.
373  void vtlb_MapHandler(vtlbHandler handler,u32 start,u32 size)  void vtlb_MapHandler(vtlbHandler handler, u32 start, u32 size)
374  {  {
375          verify(0==(start&VTLB_PAGE_MASK));          verify(0==(start&VTLB_PAGE_MASK));
376          verify(0==(size&VTLB_PAGE_MASK) && size>0);          verify(0==(size&VTLB_PAGE_MASK) && size>0);
         s32 value=handler|0x80000000;  
377    
378          while(size>0)          s32 value = handler | 0x80000000;
379          {          u32 end = start + (size - VTLB_PAGE_SIZE);
380                  vtlbdata.pmap[start>>VTLB_PAGE_BITS]=value;          pxAssume( (end>>VTLB_PAGE_BITS) < ArraySize(vtlbdata.pmap) );
381    
382                  start+=VTLB_PAGE_SIZE;          while (start <= end)
383                  size-=VTLB_PAGE_SIZE;          {
384                    vtlbdata.pmap[start>>VTLB_PAGE_BITS] = value;
385                    start += VTLB_PAGE_SIZE;
386          }          }
387  }  }
388    
389  void vtlb_MapBlock(void* base,u32 start,u32 size,u32 blocksize)  void vtlb_MapBlock(void* base, u32 start, u32 size, u32 blocksize)
390  {  {
         s32 baseint=(s32)base;  
   
391          verify(0==(start&VTLB_PAGE_MASK));          verify(0==(start&VTLB_PAGE_MASK));
392          verify(0==(size&VTLB_PAGE_MASK) && size>0);          verify(0==(size&VTLB_PAGE_MASK) && size>0);
393          if (blocksize==0)          if (!blocksize)
394                  blocksize=size;                  blocksize = size;
395          verify(0==(blocksize&VTLB_PAGE_MASK) && blocksize>0);          verify(0==(blocksize&VTLB_PAGE_MASK) && blocksize>0);
396          verify(0==(size%blocksize));          verify(0==(size%blocksize));
397    
398          while(size>0)          s32 baseint = (s32)base;
399            u32 end = start + (size - VTLB_PAGE_SIZE);
400            pxAssume( (end>>VTLB_PAGE_BITS) < ArraySize(vtlbdata.pmap) );
401    
402            while (start <= end)
403          {          {
404                  u32 blocksz=blocksize;                  u32 loopsz = blocksize;
405                  s32 ptr=baseint;                  s32 ptr = baseint;
406    
407                  while(blocksz>0)                  while (loopsz > 0)
408                  {                  {
409                          vtlbdata.pmap[start>>VTLB_PAGE_BITS]=ptr;                          vtlbdata.pmap[start>>VTLB_PAGE_BITS] = ptr;
410    
411                          start+=VTLB_PAGE_SIZE;                          start   += VTLB_PAGE_SIZE;
412                          ptr+=VTLB_PAGE_SIZE;                          ptr             += VTLB_PAGE_SIZE;
413                          blocksz-=VTLB_PAGE_SIZE;                          loopsz  -= VTLB_PAGE_SIZE;
                         size-=VTLB_PAGE_SIZE;  
414                  }                  }
415          }          }
416  }  }
# Line 422  void vtlb_Mirror(u32 new_region,u32 star Line 421  void vtlb_Mirror(u32 new_region,u32 star
421          verify(0==(start&VTLB_PAGE_MASK));          verify(0==(start&VTLB_PAGE_MASK));
422          verify(0==(size&VTLB_PAGE_MASK) && size>0);          verify(0==(size&VTLB_PAGE_MASK) && size>0);
423    
424          while(size>0)          u32 end = start + (size-VTLB_PAGE_SIZE);
425            pxAssume( (end>>VTLB_PAGE_BITS) < ArraySize(vtlbdata.pmap) );
426    
427            while(start <= end)
428          {          {
429                  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];
430    
431                  start+=VTLB_PAGE_SIZE;                  start           += VTLB_PAGE_SIZE;
432                  new_region+=VTLB_PAGE_SIZE;                  new_region      += VTLB_PAGE_SIZE;
                 size-=VTLB_PAGE_SIZE;  
433          }          }
434  }  }
435    
436  __forceinline void* vtlb_GetPhyPtr(u32 paddr)  __fi void* vtlb_GetPhyPtr(u32 paddr)
437  {  {
438          if (paddr>=VTLB_PMAP_SZ || vtlbdata.pmap[paddr>>VTLB_PAGE_BITS]<0)          if (paddr>=VTLB_PMAP_SZ || vtlbdata.pmap[paddr>>VTLB_PAGE_BITS]<0)
439                  return NULL;                  return NULL;
# Line 442  __forceinline void* vtlb_GetPhyPtr(u32 p Line 443  __forceinline void* vtlb_GetPhyPtr(u32 p
443    
444  //virtual mappings  //virtual mappings
445  //TODO: Add invalid paddr checks  //TODO: Add invalid paddr checks
446  void vtlb_VMap(u32 vaddr,u32 paddr,u32 sz)  void vtlb_VMap(u32 vaddr,u32 paddr,u32 size)
447  {  {
448          verify(0==(vaddr&VTLB_PAGE_MASK));          verify(0==(vaddr&VTLB_PAGE_MASK));
449          verify(0==(paddr&VTLB_PAGE_MASK));          verify(0==(paddr&VTLB_PAGE_MASK));
450          verify(0==(sz&VTLB_PAGE_MASK) && sz>0);          verify(0==(size&VTLB_PAGE_MASK) && size>0);
451    
452          while(sz>0)          while (size > 0)
453          {          {
454                  s32 pme;                  s32 pme;
455                  if (paddr>=VTLB_PMAP_SZ)                  if (paddr >= VTLB_PMAP_SZ)
456                  {                  {
457                          pme=UnmappedPhyHandler0;                          pme = UnmappedPhyHandler0;
458                          if (paddr&0x80000000)                          if (paddr & 0x80000000)
459                                  pme=UnmappedPhyHandler1;                                  pme = UnmappedPhyHandler1;
460                          pme|=0x80000000;                          pme |= 0x80000000;
461                          pme|=paddr;// top bit is set anyway ...                          pme |= paddr;// top bit is set anyway ...
462                  }                  }
463                  else                  else
464                  {                  {
465                          pme=vtlbdata.pmap[paddr>>VTLB_PAGE_BITS];                          pme = vtlbdata.pmap[paddr>>VTLB_PAGE_BITS];
466                          if (pme<0)                          if (pme<0)
467                                  pme|=paddr;// top bit is set anyway ...                                  pme |= paddr;// top bit is set anyway ...
468                  }                  }
469                  vtlbdata.vmap[vaddr>>VTLB_PAGE_BITS]=pme-vaddr;  
470                  vaddr+=VTLB_PAGE_SIZE;                  vtlbdata.vmap[vaddr>>VTLB_PAGE_BITS] = pme-vaddr;
471                  paddr+=VTLB_PAGE_SIZE;                  vaddr += VTLB_PAGE_SIZE;
472                  sz-=VTLB_PAGE_SIZE;                  paddr += VTLB_PAGE_SIZE;
473                    size -= VTLB_PAGE_SIZE;
474          }          }
475  }  }
476    
477  void vtlb_VMapBuffer(u32 vaddr,void* buffer,u32 sz)  void vtlb_VMapBuffer(u32 vaddr,void* buffer,u32 size)
478  {  {
479          verify(0==(vaddr&VTLB_PAGE_MASK));          verify(0==(vaddr&VTLB_PAGE_MASK));
480          verify(0==(sz&VTLB_PAGE_MASK) && sz>0);          verify(0==(size&VTLB_PAGE_MASK) && size>0);
481          u32 bu8=(u32)buffer;  
482          while(sz>0)          u32 bu8 = (u32)buffer;
483            while (size > 0)
484          {          {
485                  vtlbdata.vmap[vaddr>>VTLB_PAGE_BITS]=bu8-vaddr;                  vtlbdata.vmap[vaddr>>VTLB_PAGE_BITS] = bu8-vaddr;
486                  vaddr+=VTLB_PAGE_SIZE;                  vaddr += VTLB_PAGE_SIZE;
487                  bu8+=VTLB_PAGE_SIZE;                  bu8 += VTLB_PAGE_SIZE;
488                  sz-=VTLB_PAGE_SIZE;                  size -= VTLB_PAGE_SIZE;
489          }          }
490  }  }
491  void vtlb_VMapUnmap(u32 vaddr,u32 sz)  void vtlb_VMapUnmap(u32 vaddr,u32 size)
492  {  {
493          verify(0==(vaddr&VTLB_PAGE_MASK));          verify(0==(vaddr&VTLB_PAGE_MASK));
494          verify(0==(sz&VTLB_PAGE_MASK) && sz>0);          verify(0==(size&VTLB_PAGE_MASK) && size>0);
495    
496          while(sz>0)          while (size > 0)
497          {          {
498                  u32 handl=UnmappedVirtHandler0;                  u32 handl = UnmappedVirtHandler0;
499                  if (vaddr&0x80000000)                  if (vaddr & 0x80000000)
500                  {                  {
501                          handl=UnmappedVirtHandler1;                          handl = UnmappedVirtHandler1;
502                  }                  }
503                  handl|=vaddr; // top bit is set anyway ...  
504                  handl|=0x80000000;                  handl |= vaddr; // top bit is set anyway ...
505                  vtlbdata.vmap[vaddr>>VTLB_PAGE_BITS]=handl-vaddr;                  handl |= 0x80000000;
506                  vaddr+=VTLB_PAGE_SIZE;  
507                  sz-=VTLB_PAGE_SIZE;                  vtlbdata.vmap[vaddr>>VTLB_PAGE_BITS] = handl-vaddr;
508                    vaddr += VTLB_PAGE_SIZE;
509                    size -= VTLB_PAGE_SIZE;
510          }          }
511  }  }
512    
513  //////////////////////////////////////////////////////////////////////////////////////////  // vtlb_Init -- Clears vtlb handlers and memory mappings.
 // vtlb_init -- Clears vtlb handlers and memory mappings.  
514  void vtlb_Init()  void vtlb_Init()
515  {  {
516          vtlbHandlerCount=0;          vtlbHandlerCount=0;
517          memzero(vtlbdata.RWFT);          memzero(vtlbdata.RWFT);
518    
519    #define VTLB_BuildUnmappedHandler(baseName, highBit) \
520            baseName##ReadSm<mem8_t,0>,             baseName##ReadSm<mem16_t,0>,    baseName##ReadSm<mem32_t,0>, \
521            baseName##ReadLg<mem64_t,0>,    baseName##ReadLg<mem128_t,0>, \
522            baseName##WriteSm<mem8_t,0>,    baseName##WriteSm<mem16_t,0>,   baseName##WriteSm<mem32_t,0>, \
523            baseName##WriteLg<mem64_t,0>,   baseName##WriteLg<mem128_t,0>
524    
525          //Register default handlers          //Register default handlers
526          //Unmapped Virt handlers _MUST_ be registered first.          //Unmapped Virt handlers _MUST_ be registered first.
527          //On address translation the top bit cannot be preserved.This is not normaly a problem since          //On address translation the top bit cannot be preserved.This is not normaly a problem since
528          //the physical address space can be 'compressed' to just 29 bits.However, to properly handle exceptions          //the physical address space can be 'compressed' to just 29 bits.However, to properly handle exceptions
529          //there must be a way to get the full address back.Thats why i use these 2 functions and encode the hi bit directly into em :)          //there must be a way to get the full address back.Thats why i use these 2 functions and encode the hi bit directly into em :)
530    
531          UnmappedVirtHandler0 = vtlb_RegisterHandler(          UnmappedVirtHandler0 = vtlb_RegisterHandler( VTLB_BuildUnmappedHandler(vtlbUnmappedV, 0) );
532                  vtlbUnmappedVRead8<0>,vtlbUnmappedVRead16<0>,vtlbUnmappedVRead32<0>,vtlbUnmappedVRead64<0>,vtlbUnmappedVRead128<0>,          UnmappedVirtHandler1 = vtlb_RegisterHandler( VTLB_BuildUnmappedHandler(vtlbUnmappedV, 0x80000000) );
                 vtlbUnmappedVWrite8<0>,vtlbUnmappedVWrite16<0>,vtlbUnmappedVWrite32<0>,vtlbUnmappedVWrite64<0>,vtlbUnmappedVWrite128<0>  
         );  
   
         UnmappedVirtHandler1 = vtlb_RegisterHandler(  
                 vtlbUnmappedVRead8<0x80000000>,vtlbUnmappedVRead16<0x80000000>,vtlbUnmappedVRead32<0x80000000>, vtlbUnmappedVRead64<0x80000000>,vtlbUnmappedVRead128<0x80000000>,  
                 vtlbUnmappedVWrite8<0x80000000>,vtlbUnmappedVWrite16<0x80000000>,vtlbUnmappedVWrite32<0x80000000>, vtlbUnmappedVWrite64<0x80000000>,vtlbUnmappedVWrite128<0x80000000>  
         );  
   
         UnmappedPhyHandler0 = vtlb_RegisterHandler(  
                 vtlbUnmappedPRead8<0>,vtlbUnmappedPRead16<0>,vtlbUnmappedPRead32<0>,vtlbUnmappedPRead64<0>,vtlbUnmappedPRead128<0>,  
                 vtlbUnmappedPWrite8<0>,vtlbUnmappedPWrite16<0>,vtlbUnmappedPWrite32<0>,vtlbUnmappedPWrite64<0>,vtlbUnmappedPWrite128<0>  
         );  
533    
534          UnmappedPhyHandler1 = vtlb_RegisterHandler(          UnmappedPhyHandler0 = vtlb_RegisterHandler( VTLB_BuildUnmappedHandler(vtlbUnmappedP, 0) );
535                  vtlbUnmappedPRead8<0x80000000>,vtlbUnmappedPRead16<0x80000000>,vtlbUnmappedPRead32<0x80000000>, vtlbUnmappedPRead64<0x80000000>,vtlbUnmappedPRead128<0x80000000>,          UnmappedPhyHandler1 = vtlb_RegisterHandler( VTLB_BuildUnmappedHandler(vtlbUnmappedP, 0x80000000) );
                 vtlbUnmappedPWrite8<0x80000000>,vtlbUnmappedPWrite16<0x80000000>,vtlbUnmappedPWrite32<0x80000000>, vtlbUnmappedPWrite64<0x80000000>,vtlbUnmappedPWrite128<0x80000000>  
         );  
536    
537          DefaultPhyHandler = vtlb_RegisterHandler(0,0,0,0,0,0,0,0,0,0);          DefaultPhyHandler = vtlb_RegisterHandler(0,0,0,0,0,0,0,0,0,0);
538    
# Line 554  void vtlb_Init() Line 550  void vtlb_Init()
550          vtlb_dynarec_init();          vtlb_dynarec_init();
551  }  }
552    
 //////////////////////////////////////////////////////////////////////////////////////////  
553  // vtlb_Reset -- Performs a COP0-level reset of the PS2's TLB.  // vtlb_Reset -- Performs a COP0-level reset of the PS2's TLB.
554  // This function should probably be part of the COP0 rather than here in VTLB.  // This function should probably be part of the COP0 rather than here in VTLB.
555  void vtlb_Reset()  void vtlb_Reset()
# Line 567  void vtlb_Term() Line 562  void vtlb_Term()
562          //nothing to do for now          //nothing to do for now
563  }  }
564    
 //////////////////////////////////////////////////////////////////////////////////////////  
565  // Reserves the vtlb core allocation used by various emulation components!  // Reserves the vtlb core allocation used by various emulation components!
566  //  // [TODO] basemem - request allocating memory at the specified virtual location, which can allow
567    //    for easier debugging and/or 3rd party cheat programs.  If 0, the operating system
568    //    default is used.
569  void vtlb_Core_Alloc()  void vtlb_Core_Alloc()
570  {  {
571          if( vtlbdata.alloc_base != NULL ) return;          if (!vtlbdata.vmap)
572            {
573          vtlbdata.alloc_current = 0;                  vtlbdata.vmap = (s32*)_aligned_malloc( VTLB_VMAP_ITEMS * sizeof(*vtlbdata.vmap), 16 );
574                    if (!vtlbdata.vmap)
575                            throw Exception::OutOfMemory( L"VTLB Virtual Address Translation LUT" )
576                                    .SetDiagMsg(pxsFmt("(%u megs)", VTLB_VMAP_ITEMS * sizeof(*vtlbdata.vmap) / _1mb)
577                            );
578            }
579    }
580    
581  #ifdef __LINUX__  void vtlb_Core_Free()
582          vtlbdata.alloc_base = SysMmapEx( 0x16000000, VTLB_ALLOC_SIZE, 0x80000000, "Vtlb" );  {
583  #else          safe_aligned_free( vtlbdata.vmap );
         // 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( "Fatal Error: could not allocate 42Meg buffer for PS2's mappable system ram." );  
 #endif  
584  }  }
585    
586  //////////////////////////////////////////////////////////////////////////////////////////  static wxString GetHostVmErrorMsg()
 //  
 void vtlb_Core_Shutdown()  
587  {  {
588          if( vtlbdata.alloc_base == NULL ) return;          return pxE("!Notice:HostVmReserve",
589                    L"Your system is too low on virtual resources for PCSX2 to run.  This can be "
590                    L"caused by having a small or disabled swapfile, or by other programs that are "
591                    L"hogging resources."
592            );
593    }
594    // --------------------------------------------------------------------------------------
595    //  VtlbMemoryReserve  (implementations)
596    // --------------------------------------------------------------------------------------
597    VtlbMemoryReserve::VtlbMemoryReserve( const wxString& name, size_t size )
598            : m_reserve( name, size )
599    {
600            m_reserve.SetPageAccessOnCommit( PageAccess_ReadWrite() );
601    }
602    
603  #ifdef __LINUX__  void VtlbMemoryReserve::SetBaseAddr( uptr newaddr )
604          SafeSysMunmap( vtlbdata.alloc_base, VTLB_ALLOC_SIZE );  {
605  #else          m_reserve.SetBaseAddr( newaddr );
606          // 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  
607    
608    void VtlbMemoryReserve::Reserve( sptr hostptr )
609    {
610            if (!m_reserve.ReserveAt( hostptr ))
611            {
612                    throw Exception::OutOfMemory( m_reserve.GetName() )
613                            .SetDiagMsg(L"Vtlb memory could not be reserved.")
614                            .SetUserMsg(GetHostVmErrorMsg());
615            }
616  }  }
617    
618  //////////////////////////////////////////////////////////////////////////////////////////  void VtlbMemoryReserve::Commit()
 // 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 )  
619  {  {
620          vtlbdata.alloc_current += align-1;          if (IsCommitted()) return;
621          vtlbdata.alloc_current &= ~(align-1);          if (!m_reserve.Commit())
622            {
623                    throw Exception::OutOfMemory( m_reserve.GetName() )
624                            .SetDiagMsg(L"Vtlb memory could not be committed.")
625                            .SetUserMsg(GetHostVmErrorMsg());
626            }
627    }
628    
629          int rv = vtlbdata.alloc_current;  void VtlbMemoryReserve::Reset()
630          vtlbdata.alloc_current += size;  {
631          return &vtlbdata.alloc_base[rv];          Commit();
632            memzero_sse_a(m_reserve.GetPtr(), m_reserve.GetCommittedBytes());
633  }  }
634    
635  //////////////////////////////////////////////////////////////////////////////////////////  void VtlbMemoryReserve::Decommit()
 //  
 void vtlb_free( void* pmem, uint size )  
636  {  {
637          // Does nothing anymore!  Alloc/dealloc is now handled by vtlb_Core_Alloc /          m_reserve.Reset();
638          // vtlb_Core_Shutdown.  Placebo is left in place in case it becomes useful again  }
         // at a later date.  
639    
640          return;  void VtlbMemoryReserve::Release()
641    {
642            m_reserve.Release();
643  }  }
644    
645    bool VtlbMemoryReserve::IsCommitted() const
646    {
647            return !!m_reserve.GetCommittedPageCount();
648    }

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

  ViewVC Help
Powered by ViewVC 1.1.22