/[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 62 by william, Tue Sep 7 11:08:22 2010 UTC
# Line 39  Line 39 
39  using namespace R5900;  using namespace R5900;
40  using namespace vtlb_private;  using namespace vtlb_private;
41    
42  #ifdef PCSX2_DEVBUILD  #define verify pxAssume
 #define verify(x) {if (!(x)) { (*(u8*)0)=3; }}  
 #else  
 #define verify jASSUME  
 #endif  
43    
44  namespace vtlb_private  namespace vtlb_private
45  {  {
46          __aligned(64) MapData vtlbdata;          __aligned(64) MapData vtlbdata;
47  }  }
48    
49  vtlbHandler vtlbHandlerCount=0;  static vtlbHandler vtlbHandlerCount=0;
50    
51  vtlbHandler DefaultPhyHandler;  static vtlbHandler DefaultPhyHandler;
52  vtlbHandler UnmappedVirtHandler0;  static vtlbHandler UnmappedVirtHandler0;
53  vtlbHandler UnmappedVirtHandler1;  static vtlbHandler UnmappedVirtHandler1;
54  vtlbHandler UnmappedPhyHandler0;  static vtlbHandler UnmappedPhyHandler0;
55  vtlbHandler UnmappedPhyHandler1;  static vtlbHandler UnmappedPhyHandler1;
56    
57    
58  //////////////////////////////////////////////////////////////////////////////////////////  // --------------------------------------------------------------------------------------
59  // Interpreter Implementations of VTLB Memory Operations.  // Interpreter Implementations of VTLB Memory Operations.
60    // --------------------------------------------------------------------------------------
61  // See recVTLB.cpp for the dynarec versions.  // See recVTLB.cpp for the dynarec versions.
62    
63  // Interpreted VTLB lookup for 8, 16, and 32 bit accesses  template< typename DataType >
64  template<int DataSize,typename DataType>  DataType __fastcall vtlb_memRead(u32 addr)
 __forceinline DataType __fastcall MemOp_r0(u32 addr)  
65  {  {
66            static const uint DataSize = sizeof(DataType) * 8;
67          u32 vmv=vtlbdata.vmap[addr>>VTLB_PAGE_BITS];          u32 vmv=vtlbdata.vmap[addr>>VTLB_PAGE_BITS];
68          s32 ppf=addr+vmv;          s32 ppf=addr+vmv;
69    
# Line 81  __forceinline DataType __fastcall MemOp_ Line 78  __forceinline DataType __fastcall MemOp_
78    
79          switch( DataSize )          switch( DataSize )
80          {          {
81                  case 8: return ((vtlbMemR8FP*)vtlbdata.RWFT[0][0][hand])(paddr);          case 8: return ((vtlbMemR8FP*)vtlbdata.RWFT[0][0][hand])(paddr);
82                  case 16: return ((vtlbMemR16FP*)vtlbdata.RWFT[1][0][hand])(paddr);          case 16: return ((vtlbMemR16FP*)vtlbdata.RWFT[1][0][hand])(paddr);
83                  case 32: return ((vtlbMemR32FP*)vtlbdata.RWFT[2][0][hand])(paddr);          case 32: return ((vtlbMemR32FP*)vtlbdata.RWFT[2][0][hand])(paddr);
84    
85                  jNO_DEFAULT;                  jNO_DEFAULT;
86          }          }
# Line 91  __forceinline DataType __fastcall MemOp_ Line 88  __forceinline DataType __fastcall MemOp_
88          return 0;               // technically unreachable, but suppresses warnings.          return 0;               // technically unreachable, but suppresses warnings.
89  }  }
90    
91  // ------------------------------------------------------------------------  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)  
92  {  {
93          u32 vmv=vtlbdata.vmap[addr>>VTLB_PAGE_BITS];          u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
94          s32 ppf=addr+vmv;          s32 ppf=mem+vmv;
95    
96          if (!(ppf<0))          if (!(ppf<0))
97          {          {
98                  data[0]=*reinterpret_cast<DataType*>(ppf);                  *out = *(mem64_t*)ppf;
                 if (DataSize==128)  
                         data[1]=*reinterpret_cast<DataType*>(ppf+8);  
99          }          }
100          else          else
101          {          {
# Line 111  __forceinline void __fastcall MemOp_r1(u Line 103  __forceinline void __fastcall MemOp_r1(u
103                  u32 hand=(u8)vmv;                  u32 hand=(u8)vmv;
104                  u32 paddr=ppf-hand+0x80000000;                  u32 paddr=ppf-hand+0x80000000;
105                  //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);  
106    
107                  switch( DataSize )                  ((vtlbMemR64FP*)vtlbdata.RWFT[3][0][hand])(paddr, out);
108                  {          }
109                          case 64: ((vtlbMemR64FP*)vtlbdata.RWFT[3][0][hand])(paddr, data); break;  }
110                          case 128: ((vtlbMemR128FP*)vtlbdata.RWFT[4][0][hand])(paddr, data); break;  void __fastcall vtlb_memRead128(u32 mem, mem128_t *out)
111    {
112            u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
113            s32 ppf=mem+vmv;
114    
115                          jNO_DEFAULT;          if (!(ppf<0))
116                  }          {
117                    CopyQWC(out,(void*)ppf);
118            }
119            else
120            {
121                    //has to: translate, find function, call function
122                    u32 hand=(u8)vmv;
123                    u32 paddr=ppf-hand+0x80000000;
124                    //Console.WriteLn("Translated 0x%08X to 0x%08X", addr,paddr);
125    
126                    ((vtlbMemR128FP*)vtlbdata.RWFT[4][0][hand])(paddr, out);
127          }          }
128  }  }
129    
130  // ------------------------------------------------------------------------  template< typename DataType >
131  template<int DataSize,typename DataType>  void __fastcall vtlb_memWrite(u32 addr, DataType data)
 __forceinline void __fastcall MemOp_w0(u32 addr, DataType data)  
132  {  {
133            static const uint DataSize = sizeof(DataType) * 8;
134    
135          u32 vmv=vtlbdata.vmap[addr>>VTLB_PAGE_BITS];          u32 vmv=vtlbdata.vmap[addr>>VTLB_PAGE_BITS];
136          s32 ppf=addr+vmv;          s32 ppf=addr+vmv;
137          if (!(ppf<0))          if (!(ppf<0))
# Line 142  __forceinline void __fastcall MemOp_w0(u Line 147  __forceinline void __fastcall MemOp_w0(u
147    
148                  switch( DataSize )                  switch( DataSize )
149                  {                  {
150                          case 8: return ((vtlbMemW8FP*)vtlbdata.RWFT[0][1][hand])(paddr, (u8)data);                  case 8: return ((vtlbMemW8FP*)vtlbdata.RWFT[0][1][hand])(paddr, (u8)data);
151                          case 16: return ((vtlbMemW16FP*)vtlbdata.RWFT[1][1][hand])(paddr, (u16)data);                  case 16: return ((vtlbMemW16FP*)vtlbdata.RWFT[1][1][hand])(paddr, (u16)data);
152                          case 32: return ((vtlbMemW32FP*)vtlbdata.RWFT[2][1][hand])(paddr, (u32)data);                  case 32: return ((vtlbMemW32FP*)vtlbdata.RWFT[2][1][hand])(paddr, (u32)data);
153    
154                          jNO_DEFAULT;                          jNO_DEFAULT;
155                  }                  }
156          }          }
157  }  }
158    
159  // ------------------------------------------------------------------------  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)  
160  {  {
161          verify(DataSize==128 || DataSize==64);          u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
162          u32 vmv=vtlbdata.vmap[addr>>VTLB_PAGE_BITS];          s32 ppf=mem+vmv;
         s32 ppf=addr+vmv;  
163          if (!(ppf<0))          if (!(ppf<0))
164          {          {
165                  *reinterpret_cast<DataType*>(ppf)=*data;                  *(mem64_t*)ppf = *value;
                 if (DataSize==128)  
                         *reinterpret_cast<DataType*>(ppf+8)=data[1];  
166          }          }
167          else          else
168          {          {
# Line 170  __forceinline void __fastcall MemOp_w1(u Line 170  __forceinline void __fastcall MemOp_w1(u
170                  u32 hand=(u8)vmv;                  u32 hand=(u8)vmv;
171                  u32 paddr=ppf-hand+0x80000000;                  u32 paddr=ppf-hand+0x80000000;
172                  //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);  
173    
174                          jNO_DEFAULT;                  ((vtlbMemW64FP*)vtlbdata.RWFT[3][1][hand])(paddr, value);
                 }  
175          }          }
176  }  }
177    
178  mem8_t __fastcall vtlb_memRead8(u32 mem)  void __fastcall vtlb_memWrite128(u32 mem, const mem128_t *value)
179  {  {
180          return MemOp_r0<8,mem8_t>(mem);          u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
181            s32 ppf=mem+vmv;
182            if (!(ppf<0))
183            {
184                    CopyQWC((void*)ppf, value);
185            }
186            else
187            {
188                    //has to: translate, find function, call function
189                    u32 hand=(u8)vmv;
190                    u32 paddr=ppf-hand+0x80000000;
191                    //Console.WriteLn("Translated 0x%08X to 0x%08X", addr,paddr);
192    
193                    ((vtlbMemW128FP*)vtlbdata.RWFT[4][1][hand])(paddr, value);
194            }
195  }  }
196  mem16_t __fastcall vtlb_memRead16(u32 mem)  
197    template mem8_t vtlb_memRead<mem8_t>(u32 mem);
198    template mem16_t vtlb_memRead<mem16_t>(u32 mem);
199    template mem32_t vtlb_memRead<mem32_t>(u32 mem);
200    template void vtlb_memWrite<mem8_t>(u32 mem, mem8_t data);
201    template void vtlb_memWrite<mem16_t>(u32 mem, mem16_t data);
202    template void vtlb_memWrite<mem32_t>(u32 mem, mem32_t data);
203    
204    // --------------------------------------------------------------------------------------
205    //  TLB Miss / BusError Handlers
206    // --------------------------------------------------------------------------------------
207    // These are valid VM memory errors that should typically be handled by the VM itself via
208    // its own cpu exception system.
209    //
210    // [TODO]  Add first-chance debugging hooks to these exceptions!
211    //
212    // Important recompiler note: Mid-block Exception handling isn't reliable *yet* because
213    // memory ops don't flush the PC prior to invoking the indirect handlers.
214    
215    // Generates a tlbMiss Exception
216    static __ri void vtlb_Miss(u32 addr,u32 mode)
217  {  {
218          return MemOp_r0<16,mem16_t>(mem);          if( IsDevBuild )
219                    Cpu->ThrowCpuException( R5900Exception::TLBMiss( addr, !!mode ) );
220            else
221                    Console.Error( R5900Exception::TLBMiss( addr, !!mode ).FormatMessage() );
222  }  }
223  mem32_t __fastcall vtlb_memRead32(u32 mem)  
224    // BusError exception: more serious than a TLB miss.  If properly emulated the PS2 kernel
225    // itself would invoke a diagnostic/assertion screen that displays the cpu state at the
226    // time of the exception.
227    static __ri void vtlb_BusError(u32 addr,u32 mode)
228  {  {
229          return MemOp_r0<32,mem32_t>(mem);          if( IsDevBuild )
230                    Cpu->ThrowCpuException( R5900Exception::BusError( addr, !!mode ) );
231            else
232                    Console.Error( R5900Exception::TLBMiss( addr, !!mode ).FormatMessage() );
233  }  }
234  void __fastcall vtlb_memRead64(u32 mem, u64 *out)  
235    #define _tmpl(ret) template<typename OperandType, u32 saddr> ret __fastcall
236    
237    _tmpl(OperandType) vtlbUnmappedVReadSm(u32 addr)                                        { vtlb_Miss(addr|saddr,0); return 0; }
238    _tmpl(void) vtlbUnmappedVReadLg(u32 addr,OperandType* data)                     { vtlb_Miss(addr|saddr,0); }
239    _tmpl(void) vtlbUnmappedVWriteSm(u32 addr,OperandType data)                     { vtlb_Miss(addr|saddr,1); }
240    _tmpl(void) vtlbUnmappedVWriteLg(u32 addr,const OperandType* data)      { vtlb_Miss(addr|saddr,1); }
241    
242    _tmpl(OperandType) vtlbUnmappedPReadSm(u32 addr)                                        { vtlb_BusError(addr|saddr,0); return 0; }
243    _tmpl(void) vtlbUnmappedPReadLg(u32 addr,OperandType* data)                     { vtlb_BusError(addr|saddr,0); }
244    _tmpl(void) vtlbUnmappedPWriteSm(u32 addr,OperandType data)                     { vtlb_BusError(addr|saddr,1); }
245    _tmpl(void) vtlbUnmappedPWriteLg(u32 addr,const OperandType* data)      { vtlb_BusError(addr|saddr,1); }
246    
247    #undef _tmpl
248    
249    // --------------------------------------------------------------------------------------
250    //  VTLB mapping errors
251    // --------------------------------------------------------------------------------------
252    // These errors are assertion/logic errors that should never occur if PCSX2 has been initialized
253    // properly.  All addressable physical memory should be configured as TLBMiss or Bus Error.
254    //
255    
256    static mem8_t __fastcall vtlbDefaultPhyRead8(u32 addr)
257  {  {
258          return MemOp_r1<64,mem64_t>(mem,out);          Console.Error("vtlbDefaultPhyRead8: 0x%08X", addr);
259            pxFailDev("(VTLB) Attempted read from an unmapped physical address.");
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);          Console.Error("vtlbDefaultPhyRead16: 0x%08X", addr);
266            pxFailDev("(VTLB) Attempted read from an unmapped physical address.");
267            return 0;
268  }  }
269  void __fastcall vtlb_memWrite8 (u32 mem, mem8_t value)  
270    static mem32_t __fastcall vtlbDefaultPhyRead32(u32 addr)
271  {  {
272          MemOp_w0<8,mem8_t>(mem,value);          Console.Error("vtlbDefaultPhyRead32: 0x%08X", addr);
273            pxFailDev("(VTLB) Attempted read from an unmapped physical address.");
274            return 0;
275  }  }
276  void __fastcall vtlb_memWrite16(u32 mem, mem16_t value)  
277    static void __fastcall vtlbDefaultPhyRead64(u32 addr, mem64_t* dest)
278  {  {
279          MemOp_w0<16,mem16_t>(mem,value);          Console.Error("vtlbDefaultPhyRead64: 0x%08X", addr);
280            pxFailDev("(VTLB) Attempted read from an unmapped physical address.");
281  }  }
282  void __fastcall vtlb_memWrite32(u32 mem, mem32_t value)  
283    static void __fastcall vtlbDefaultPhyRead128(u32 addr, mem128_t* dest)
284  {  {
285          MemOp_w0<32,mem32_t>(mem,value);          Console.Error("vtlbDefaultPhyRead128: 0x%08X", addr);
286            pxFailDev("(VTLB) Attempted read from an unmapped physical address.");
287  }  }
288  void __fastcall vtlb_memWrite64(u32 mem, const mem64_t* value)  
289    static void __fastcall vtlbDefaultPhyWrite8(u32 addr, mem8_t data)
290  {  {
291          MemOp_w1<64,mem64_t>(mem,value);          Console.Error("vtlbDefaultPhyWrite8: 0x%08X",addr);
292            pxFailDev("(VTLB) Attempted write to an unmapped physical address.");
293  }  }
294  void __fastcall vtlb_memWrite128(u32 mem, const mem128_t *value)  
295    static void __fastcall vtlbDefaultPhyWrite16(u32 addr, mem16_t data)
296  {  {
297          MemOp_w1<128,mem128_t>(mem,value);          Console.Error("vtlbDefaultPhyWrite16: 0x%08X",addr);
298            pxFailDev("(VTLB) Attempted write to an unmapped physical address.");
299  }  }
300    
301  /////////////////////////////////////////////////////////////////////////  static void __fastcall vtlbDefaultPhyWrite32(u32 addr, mem32_t data)
 // Error / TLB Miss Handlers  
 //  
   
 static const char* _getModeStr( u32 mode )  
302  {  {
303          return (mode==0) ? "read" : "write";          Console.Error("vtlbDefaultPhyWrite32: 0x%08X",addr);
304            pxFailDev("(VTLB) Attempted write to an unmapped physical address.");
305  }  }
306    
307  // Generates a tlbMiss Exception  static void __fastcall vtlbDefaultPhyWrite64(u32 addr,const mem64_t* data)
308  // Note: Don't throw exceptions yet, they cause a crash when otherwise  {
309  // there would be a (slight) chance the game continues (rama).          Console.Error("vtlbDefaultPhyWrite64: 0x%08X",addr);
310  static __forceinline void vtlb_Miss(u32 addr,u32 mode)          pxFailDev("(VTLB) Attempted write to an unmapped physical address.");
311  {  }
         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); }  
312    
313    static void __fastcall vtlbDefaultPhyWrite128(u32 addr,const mem128_t* data)
314    {
315            Console.Error("vtlbDefaultPhyWrite128: 0x%08X",addr);
316            pxFailDev("(VTLB) Attempted write to an unmapped physical address.");
317    }
318    #undef _tmpl
319    
320  //////////////////////////////////////////////////////////////////////////////////////////  // ===========================================================================================
321  // VTLB Public API -- Init/Term/RegisterHandler stuff  //  VTLB Public API -- Init/Term/RegisterHandler stuff
322    // ===========================================================================================
323  //  //
324    
325  // 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 329  void __fastcall vtlbDefaultPhyWrite128(u
329  //  //
330  // 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()
331  //  //
332  void vtlb_ReassignHandler( vtlbHandler rv,  __ri void vtlb_ReassignHandler( vtlbHandler rv,
333                   vtlbMemR8FP* r8,vtlbMemR16FP* r16,vtlbMemR32FP* r32,vtlbMemR64FP* r64,vtlbMemR128FP* r128,                                                             vtlbMemR8FP* r8,vtlbMemR16FP* r16,vtlbMemR32FP* r32,vtlbMemR64FP* r64,vtlbMemR128FP* r128,
334                   vtlbMemW8FP* w8,vtlbMemW16FP* w16,vtlbMemW32FP* w32,vtlbMemW64FP* w64,vtlbMemW128FP* w128 )                                                             vtlbMemW8FP* w8,vtlbMemW16FP* w16,vtlbMemW32FP* w32,vtlbMemW64FP* w64,vtlbMemW128FP* w128 )
335  {  {
336          vtlbdata.RWFT[0][0][rv] = (r8!=0) ? (void*)(r8): (void*)vtlbDefaultPhyRead8;          vtlbdata.RWFT[0][0][rv] = (void*)((r8!=0)   ? r8        : vtlbDefaultPhyRead8);
337          vtlbdata.RWFT[1][0][rv] = (r16!=0)  ? (void*)r16: (void*)vtlbDefaultPhyRead16;          vtlbdata.RWFT[1][0][rv] = (void*)((r16!=0)  ? r16       : vtlbDefaultPhyRead16);
338          vtlbdata.RWFT[2][0][rv] = (r32!=0)  ? (void*)r32: (void*)vtlbDefaultPhyRead32;          vtlbdata.RWFT[2][0][rv] = (void*)((r32!=0)  ? r32       : vtlbDefaultPhyRead32);
339          vtlbdata.RWFT[3][0][rv] = (r64!=0)  ? (void*)r64: (void*)vtlbDefaultPhyRead64;          vtlbdata.RWFT[3][0][rv] = (void*)((r64!=0)  ? r64       : vtlbDefaultPhyRead64);
340          vtlbdata.RWFT[4][0][rv] = (r128!=0) ? (void*)r128: (void*)vtlbDefaultPhyRead128;          vtlbdata.RWFT[4][0][rv] = (void*)((r128!=0) ? r128      : vtlbDefaultPhyRead128);
341    
342          vtlbdata.RWFT[0][0][rv] = (r8!=0)   ? (void*)r8:(void*)vtlbDefaultPhyRead8;          vtlbdata.RWFT[0][1][rv] = (void*)((w8!=0)   ? w8        : vtlbDefaultPhyWrite8);
343          vtlbdata.RWFT[1][0][rv] = (r16!=0)  ? (void*)r16:(void*)vtlbDefaultPhyRead16;          vtlbdata.RWFT[1][1][rv] = (void*)((w16!=0)  ? w16       : vtlbDefaultPhyWrite16);
344          vtlbdata.RWFT[2][0][rv] = (r32!=0)  ? (void*)r32:(void*)vtlbDefaultPhyRead32;          vtlbdata.RWFT[2][1][rv] = (void*)((w32!=0)  ? w32       : vtlbDefaultPhyWrite32);
345          vtlbdata.RWFT[3][0][rv] = (r64!=0)  ? (void*)r64:(void*)vtlbDefaultPhyRead64;          vtlbdata.RWFT[3][1][rv] = (void*)((w64!=0)  ? w64       : vtlbDefaultPhyWrite64);
346          vtlbdata.RWFT[4][0][rv] = (r128!=0) ? (void*)r128:(void*)vtlbDefaultPhyRead128;          vtlbdata.RWFT[4][1][rv] = (void*)((w128!=0) ? w128      : vtlbDefaultPhyWrite128);
   
         vtlbdata.RWFT[0][1][rv] = (void*)((w8!=0)   ? w8:vtlbDefaultPhyWrite8);  
         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);  
347  }  }
348    
349  vtlbHandler vtlb_NewHandler()  vtlbHandler vtlb_NewHandler()
# Line 356  vtlbHandler vtlb_NewHandler() Line 361  vtlbHandler vtlb_NewHandler()
361  //  //
362  // 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.
363  //  //
364  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,
365                                                                          vtlbMemW8FP* w8,vtlbMemW16FP* w16,vtlbMemW32FP* w32,vtlbMemW64FP* w64,vtlbMemW128FP* w128)                                                                          vtlbMemW8FP* w8,vtlbMemW16FP* w16,vtlbMemW32FP* w32,vtlbMemW64FP* w64,vtlbMemW128FP* w128)
366  {  {
367          vtlbHandler rv = vtlb_NewHandler();          vtlbHandler rv = vtlb_NewHandler();
# Line 365  vtlbHandler vtlb_RegisterHandler(      vtlbMe Line 370  vtlbHandler vtlb_RegisterHandler(      vtlbMe
370  }  }
371    
372    
 //////////////////////////////////////////////////////////////////////////////////////////  
373  // 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.
374  // 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
375  // 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 432  void vtlb_Mirror(u32 new_region,u32 star Line 436  void vtlb_Mirror(u32 new_region,u32 star
436          }          }
437  }  }
438    
439  __forceinline void* vtlb_GetPhyPtr(u32 paddr)  __fi void* vtlb_GetPhyPtr(u32 paddr)
440  {  {
441          if (paddr>=VTLB_PMAP_SZ || vtlbdata.pmap[paddr>>VTLB_PAGE_BITS]<0)          if (paddr>=VTLB_PMAP_SZ || vtlbdata.pmap[paddr>>VTLB_PAGE_BITS]<0)
442                  return NULL;                  return NULL;
# Line 505  void vtlb_VMapUnmap(u32 vaddr,u32 sz) Line 509  void vtlb_VMapUnmap(u32 vaddr,u32 sz)
509          }          }
510  }  }
511    
512  //////////////////////////////////////////////////////////////////////////////////////////  // vtlb_Init -- Clears vtlb handlers and memory mappings.
 // vtlb_init -- Clears vtlb handlers and memory mappings.  
513  void vtlb_Init()  void vtlb_Init()
514  {  {
515          vtlbHandlerCount=0;          vtlbHandlerCount=0;
516          memzero(vtlbdata.RWFT);          memzero(vtlbdata.RWFT);
517    
518    #define VTLB_BuildUnmappedHandler(baseName, highBit) \
519            baseName##ReadSm<mem8_t,0>,             baseName##ReadSm<mem16_t,0>,    baseName##ReadSm<mem32_t,0>, \
520            baseName##ReadLg<mem64_t,0>,    baseName##ReadLg<mem128_t,0>, \
521            baseName##WriteSm<mem8_t,0>,    baseName##WriteSm<mem16_t,0>,   baseName##WriteSm<mem32_t,0>, \
522            baseName##WriteLg<mem64_t,0>,   baseName##WriteLg<mem128_t,0>
523    
524          //Register default handlers          //Register default handlers
525          //Unmapped Virt handlers _MUST_ be registered first.          //Unmapped Virt handlers _MUST_ be registered first.
526          //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
527          //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
528          //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 :)
529    
530          UnmappedVirtHandler0 = vtlb_RegisterHandler(          UnmappedVirtHandler0 = vtlb_RegisterHandler( VTLB_BuildUnmappedHandler(vtlbUnmappedV, 0) );
531                  vtlbUnmappedVRead8<0>,vtlbUnmappedVRead16<0>,vtlbUnmappedVRead32<0>,vtlbUnmappedVRead64<0>,vtlbUnmappedVRead128<0>,          UnmappedVirtHandler1 = vtlb_RegisterHandler( VTLB_BuildUnmappedHandler(vtlbUnmappedV, 0x80000000) );
532                  vtlbUnmappedVWrite8<0>,vtlbUnmappedVWrite16<0>,vtlbUnmappedVWrite32<0>,vtlbUnmappedVWrite64<0>,vtlbUnmappedVWrite128<0>  
533          );          UnmappedPhyHandler0 = vtlb_RegisterHandler( VTLB_BuildUnmappedHandler(vtlbUnmappedP, 0) );
534            UnmappedPhyHandler1 = vtlb_RegisterHandler( VTLB_BuildUnmappedHandler(vtlbUnmappedP, 0x80000000) );
         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>  
         );  
   
         UnmappedPhyHandler1 = vtlb_RegisterHandler(  
                 vtlbUnmappedPRead8<0x80000000>,vtlbUnmappedPRead16<0x80000000>,vtlbUnmappedPRead32<0x80000000>, vtlbUnmappedPRead64<0x80000000>,vtlbUnmappedPRead128<0x80000000>,  
                 vtlbUnmappedPWrite8<0x80000000>,vtlbUnmappedPWrite16<0x80000000>,vtlbUnmappedPWrite32<0x80000000>, vtlbUnmappedPWrite64<0x80000000>,vtlbUnmappedPWrite128<0x80000000>  
         );  
535    
536          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);
537    
# Line 554  void vtlb_Init() Line 549  void vtlb_Init()
549          vtlb_dynarec_init();          vtlb_dynarec_init();
550  }  }
551    
 //////////////////////////////////////////////////////////////////////////////////////////  
552  // vtlb_Reset -- Performs a COP0-level reset of the PS2's TLB.  // vtlb_Reset -- Performs a COP0-level reset of the PS2's TLB.
553  // 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.
554  void vtlb_Reset()  void vtlb_Reset()
# Line 567  void vtlb_Term() Line 561  void vtlb_Term()
561          //nothing to do for now          //nothing to do for now
562  }  }
563    
 //////////////////////////////////////////////////////////////////////////////////////////  
564  // Reserves the vtlb core allocation used by various emulation components!  // Reserves the vtlb core allocation used by various emulation components!
565  //  //
566  void vtlb_Core_Alloc()  void vtlb_Core_Alloc()
# Line 582  void vtlb_Core_Alloc() Line 575  void vtlb_Core_Alloc()
575          // Win32 just needs this, since malloc always maps below 2GB.          // Win32 just needs this, since malloc always maps below 2GB.
576          vtlbdata.alloc_base = (u8*)_aligned_malloc( VTLB_ALLOC_SIZE, 4096 );          vtlbdata.alloc_base = (u8*)_aligned_malloc( VTLB_ALLOC_SIZE, 4096 );
577          if( vtlbdata.alloc_base == NULL )          if( vtlbdata.alloc_base == NULL )
578                  throw Exception::OutOfMemory( "Fatal Error: could not allocate 42Meg buffer for PS2's mappable system ram." );                  throw Exception::OutOfMemory( pxsFmt(L"PS2 mappable system ram (%u megs)", VTLB_ALLOC_SIZE / _1mb) );
579  #endif  #endif
580  }  }
581    
 //////////////////////////////////////////////////////////////////////////////////////////  
 //  
582  void vtlb_Core_Shutdown()  void vtlb_Core_Shutdown()
583  {  {
584          if( vtlbdata.alloc_base == NULL ) return;          if( vtlbdata.alloc_base == NULL ) return;
# Line 602  void vtlb_Core_Shutdown() Line 593  void vtlb_Core_Shutdown()
593    
594  }  }
595    
 //////////////////////////////////////////////////////////////////////////////////////////  
596  // This function allocates memory block with are compatible with the Vtlb's requirements  // This function allocates memory block with are compatible with the Vtlb's requirements
597  // for memory locations.  The Vtlb requires the topmost bit (Sign bit) of the memory  // for memory locations.  The Vtlb requires the topmost bit (Sign bit) of the memory
598  // pointer to be cleared.  Some operating systems and/or implementations of malloc do that,  // pointer to be cleared.  Some operating systems and/or implementations of malloc do that,
# Line 616  u8* vtlb_malloc( uint size, uint align ) Line 606  u8* vtlb_malloc( uint size, uint align )
606    
607          int rv = vtlbdata.alloc_current;          int rv = vtlbdata.alloc_current;
608          vtlbdata.alloc_current += size;          vtlbdata.alloc_current += size;
609    
610            pxAssertDev( vtlbdata.alloc_current < VTLB_ALLOC_SIZE, "(vtlb_malloc) memory overflow! Please increase the size of VTLB_ALLOC_SIZE!" );
611          return &vtlbdata.alloc_base[rv];          return &vtlbdata.alloc_base[rv];
612  }  }
613    
 //////////////////////////////////////////////////////////////////////////////////////////  
 //  
614  void vtlb_free( void* pmem, uint size )  void vtlb_free( void* pmem, uint size )
615  {  {
616          // Does nothing anymore!  Alloc/dealloc is now handled by vtlb_Core_Alloc /          vtlbdata.alloc_current -= size;
617          // vtlb_Core_Shutdown.  Placebo is left in place in case it becomes useful again  
618          // at a later date.          pxAssertDev( vtlbdata.alloc_current >= 0, "(vtlb_free) mismatched calls to vtlb_malloc and free detected via memory underflow." );
619    
620          return;          return;
621  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.22