Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmmuutil.c
Go to the documentation of this file.
00001 #include "ppcmmu/mmu.h" 00002 #include "ppcmmu/mmuutil.h" 00003 00004 inline int GetMSR() { 00005 register int res asm ("r3"); 00006 __asm__("mfmsr 3"); 00007 return res; 00008 } 00009 00010 inline int GetDEC() { 00011 register int res asm ("r3"); 00012 __asm__("mfdec 3"); 00013 return res; 00014 } 00015 00016 __asm__("\t.globl GetPhys\n" 00017 "GetPhys:\t\n" 00018 "mflr 0\n\t" 00019 "stwu 0,-16(1)\n\t" 00020 "mfmsr 5\n\t" 00021 "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ 00022 "mtmsr 6\n\t" 00023 "isync\n\t" 00024 "sync\n\t" 00025 "lwz 3,0(3)\n\t" /* Get actual value at phys addr r3 */ 00026 "mtmsr 5\n\t" 00027 "isync\n\t" 00028 "sync\n\t" 00029 "lwz 0,0(1)\n\t" 00030 "addi 1,1,16\n\t" 00031 "mtlr 0\n\t" 00032 "blr" 00033 ); 00034 00035 __asm__("\t.globl GetPhysHalf\n" 00036 "GetPhysHalf:\t\n" 00037 "mflr 0\n\t" 00038 "stwu 0,-16(1)\n\t" 00039 "mfmsr 5\n\t" 00040 "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ 00041 "mtmsr 6\n\t" 00042 "isync\n\t" 00043 "sync\n\t" 00044 "lhz 3,0(3)\n\t" /* Get actual value at phys addr r3 */ 00045 "mtmsr 5\n\t" 00046 "isync\n\t" 00047 "sync\n\t" 00048 "lwz 0,0(1)\n\t" 00049 "addi 1,1,16\n\t" 00050 "mtlr 0\n\t" 00051 "blr" 00052 ); 00053 00054 __asm__("\t.globl GetPhysByte\n" 00055 "GetPhysByte:\t\n" 00056 "mflr 0\n\t" 00057 "stwu 0,-16(1)\n\t" 00058 "mfmsr 5\n\t" 00059 "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ 00060 "mtmsr 6\n\t" 00061 "isync\n\t" 00062 "sync\n\t" 00063 "lbz 3,0(3)\n\t" /* Get actual value at phys addr r3 */ 00064 "mtmsr 5\n\t" 00065 "isync\n\t" 00066 "sync\n\t" 00067 "lwz 0,0(1)\n\t" 00068 "addi 1,1,16\n\t" 00069 "mtlr 0\n\t" 00070 "blr" 00071 ); 00072 00073 __asm__("\t.globl SetPhys\n" 00074 "SetPhys:\t\n" 00075 "mflr 0\n\t" 00076 "stwu 0,-16(1)\n\t" 00077 "mfmsr 5\n\t" 00078 "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ 00079 "mtmsr 6\n\t" 00080 "sync\n\t" 00081 "eieio\n\t" 00082 "stw 4,0(3)\n\t" /* Set actual value at phys addr r3 */ 00083 "dcbst 0,3\n\t" 00084 "mtmsr 5\n\t" 00085 "sync\n\t" 00086 "eieio\n\t" 00087 "mr 3,4\n\t" 00088 "lwz 0,0(1)\n\t" 00089 "addi 1,1,16\n\t" 00090 "mtlr 0\n\t" 00091 "blr" 00092 ); 00093 00094 __asm__("\t.globl SetPhysHalf\n" 00095 "SetPhysHalf:\t\n" 00096 "mflr 0\n\t" 00097 "stwu 0,-16(1)\n\t" 00098 "mfmsr 5\n\t" 00099 "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ 00100 "mtmsr 6\n\t" 00101 "sync\n\t" 00102 "eieio\n\t" 00103 "sth 4,0(3)\n\t" /* Set actual value at phys addr r3 */ 00104 "dcbst 0,3\n\t" 00105 "mtmsr 5\n\t" 00106 "sync\n\t" 00107 "eieio\n\t" 00108 "mr 3,4\n\t" 00109 "lwz 0,0(1)\n\t" 00110 "addi 1,1,16\n\t" 00111 "mtlr 0\n\t" 00112 "blr" 00113 ); 00114 00115 __asm__("\t.globl SetPhysByte\n" 00116 "SetPhysByte:\t\n" 00117 "mflr 0\n\t" 00118 "stwu 0,-16(1)\n\t" 00119 "mfmsr 5\n\t" 00120 "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */ 00121 "mtmsr 6\n\t" 00122 "sync\n\t" 00123 "eieio\n\t" 00124 "stb 4,0(3)\n\t" /* Set actual value at phys addr r3 */ 00125 "dcbst 0,3\n\t" 00126 "mtmsr 5\n\t" 00127 "sync\n\t" 00128 "eieio\n\t" 00129 "mr 3,4\n\t" 00130 "lwz 0,0(1)\n\t" 00131 "addi 1,1,16\n\t" 00132 "mtlr 0\n\t" 00133 "blr" 00134 ); 00135 00136 inline int GetSR(int n) { 00137 register int res = 0; 00138 switch( n ) { 00139 case 0: 00140 __asm__("mfsr %0,0" : "=r" (res)); 00141 break; 00142 case 1: 00143 __asm__("mfsr %0,1" : "=r" (res)); 00144 break; 00145 case 2: 00146 __asm__("mfsr %0,2" : "=r" (res)); 00147 break; 00148 case 3: 00149 __asm__("mfsr %0,3" : "=r" (res)); 00150 break; 00151 case 4: 00152 __asm__("mfsr %0,4" : "=r" (res)); 00153 break; 00154 case 5: 00155 __asm__("mfsr %0,5" : "=r" (res)); 00156 break; 00157 case 6: 00158 __asm__("mfsr %0,6" : "=r" (res)); 00159 break; 00160 case 7: 00161 __asm__("mfsr %0,7" : "=r" (res)); 00162 break; 00163 case 8: 00164 __asm__("mfsr %0,8" : "=r" (res)); 00165 break; 00166 case 9: 00167 __asm__("mfsr %0,9" : "=r" (res)); 00168 break; 00169 case 10: 00170 __asm__("mfsr %0,10" : "=r" (res)); 00171 break; 00172 case 11: 00173 __asm__("mfsr %0,11" : "=r" (res)); 00174 break; 00175 case 12: 00176 __asm__("mfsr %0,12" : "=r" (res)); 00177 break; 00178 case 13: 00179 __asm__("mfsr %0,13" : "=r" (res)); 00180 break; 00181 case 14: 00182 __asm__("mfsr %0,14" : "=r" (res)); 00183 break; 00184 case 15: 00185 __asm__("mfsr %0,15" : "=r" (res)); 00186 break; 00187 } 00188 return res; 00189 } 00190 00191 inline void SetSR(int n, int val) { 00192 switch( n ) { 00193 case 0: 00194 __asm__("mtsr 0,%0" : : "r" (val)); 00195 break; 00196 case 1: 00197 __asm__("mtsr 1,%0" : : "r" (val)); 00198 break; 00199 case 2: 00200 __asm__("mtsr 2,%0" : : "r" (val)); 00201 break; 00202 case 3: 00203 __asm__("mtsr 3,%0" : : "r" (val)); 00204 break; 00205 case 4: 00206 __asm__("mtsr 4,%0" : : "r" (val)); 00207 break; 00208 case 5: 00209 __asm__("mtsr 5,%0" : : "r" (val)); 00210 break; 00211 case 6: 00212 __asm__("mtsr 6,%0" : : "r" (val)); 00213 break; 00214 case 7: 00215 __asm__("mtsr 7,%0" : : "r" (val)); 00216 break; 00217 case 8: 00218 __asm__("mtsr 8,%0" : : "r" (val)); 00219 break; 00220 case 9: 00221 __asm__("mtsr 9,%0" : : "r" (val)); 00222 break; 00223 case 10: 00224 __asm__("mtsr 10,%0" : : "r" (val)); 00225 break; 00226 case 11: 00227 __asm__("mtsr 11,%0" : : "r" (val)); 00228 break; 00229 case 12: 00230 __asm__("mtsr 12,%0" : : "r" (val)); 00231 break; 00232 case 13: 00233 __asm__("mtsr 13,%0" : : "r" (val)); 00234 break; 00235 case 14: 00236 __asm__("mtsr 14,%0" : : "r" (val)); 00237 break; 00238 case 15: 00239 __asm__("mtsr 15,%0" : : "r" (val)); 00240 break; 00241 } 00242 } 00243 00244 void GetBat( int bat, int inst, int *batHi, int *batLo ) { 00245 register int bh asm("r3"), bl asm("r4"); 00246 if( inst ) { 00247 switch( bat ) { 00248 case 0: 00249 __asm__("mfibatu 3,0"); 00250 __asm__("mfibatl 4,0"); 00251 break; 00252 case 1: 00253 __asm__("mfibatu 3,1"); 00254 __asm__("mfibatl 4,1"); 00255 break; 00256 case 2: 00257 __asm__("mfibatu 3,2"); 00258 __asm__("mfibatl 4,2"); 00259 break; 00260 case 3: 00261 __asm__("mfibatu 3,3"); 00262 __asm__("mfibatl 4,3"); 00263 break; 00264 } 00265 } else { 00266 switch( bat ) { 00267 case 0: 00268 __asm__("mfdbatu 3,0"); 00269 __asm__("mfdbatl 4,0"); 00270 break; 00271 case 1: 00272 __asm__("mfdbatu 3,1"); 00273 __asm__("mfdbatl 4,1"); 00274 break; 00275 case 2: 00276 __asm__("mfdbatu 3,2"); 00277 __asm__("mfdbatl 4,2"); 00278 break; 00279 case 3: 00280 __asm__("mfdbatu 3,3"); 00281 __asm__("mfdbatl 4,3"); 00282 break; 00283 } 00284 } 00285 *batHi = bh; 00286 *batLo = bl; 00287 } 00288 00289 #define BATSET(n,t) \ 00290 case n: __asm__("mt" #t "batu " #n ",%0\n\tmt" #t "batl " #n ",%1" \ 00291 : : "r" (batHi), "r" (batLo)); break; 00292 00293 void SetBat( int bat, int inst, int batHi, int batLo ) { 00294 if( inst ) { 00295 switch( bat ) { 00296 BATSET(0,i); 00297 BATSET(1,i); 00298 BATSET(2,i); 00299 BATSET(3,i); 00300 } 00301 } else { 00302 switch( bat ) { 00303 BATSET(0,d); 00304 BATSET(1,d); 00305 BATSET(2,d); 00306 BATSET(3,d); 00307 } 00308 } 00309 __asm__("isync\n\tsync"); 00310 } 00311 00312 inline int GetSDR1() { 00313 register int res asm("r3"); 00314 __asm__("mfsdr1 3"); 00315 return res; 00316 } 00317 00318 inline void SetSDR1( int sdr ) { 00319 int i,j; 00320 __asm__("mtsdr1 3"); 00321 __asm__("sync"); 00322 __asm__("isync"); 00323 00324 for( i = 0; i < 256; i++ ) { 00325 j = i << 12; 00326 __asm__("tlbie %0,0" : : "r" (j)); 00327 } 00328 __asm__("eieio"); 00329 __asm__("tlbsync"); 00330 __asm__("ptesync"); 00331 } 00332 00333 inline int BatTranslate( int batu, int batl, int virt ) { 00334 int mask; 00335 if(batu & 0x3fc) 00336 { 00337 mask = ~(0x1ffff | ((batu & 0x3fc)>>2)<<17); 00338 if((batu & 2) && ((batu & mask) == (virt & mask))) 00339 return (batl & mask) | (virt & ~mask); 00340 } else { 00341 mask = ~(0x1ffff | (batl << 17)); 00342 if(!(batl & 0x40) || ((batu & mask) != (virt & mask))) 00343 return (batl & mask) | (virt & ~mask); 00344 } 00345 return -1; 00346 } 00347 00348 inline int BatHit( int batu, int batl, int virt ) { 00349 return BatTranslate( batu, batl, virt ) != -1; 00350 } 00351 00352 /* translate address */ 00353 int PpcVirt2phys( vaddr_t virt, int inst ) { 00354 int msr = GetMSR(); 00355 int txmask = inst ? 0x20 : 0x10; 00356 int i, bath, batl, sr, sdr1, physbase, vahi, valo; 00357 int npteg, hash, hashmask, ptehi, ptelo, ptegaddr; 00358 int vsid, pteh, ptevsid, pteapi; 00359 00360 if( msr & txmask ) { 00361 sr = GetSR( virt >> 28 ); 00362 vsid = sr & 0xfffffff; 00363 vahi = vsid >> 4; 00364 valo = (vsid << 28) | (virt & 0xfffffff); 00365 if( sr & 0x80000000 ) { 00366 return valo; 00367 } 00368 00369 for( i = 0; i < 4; i++ ) { 00370 GetBat( i, inst, &bath, &batl ); 00371 if( BatHit( bath, batl, virt ) ) { 00372 return BatTranslate( bath, batl, virt ); 00373 } 00374 } 00375 00376 sdr1 = GetSDR1(); 00377 00378 physbase = sdr1 & ~0xffff; 00379 hashmask = ((sdr1 & 0x1ff) << 10) | 0x3ff; 00380 hash = (vsid & 0x7ffff) ^ ((valo >> 12) & 0xffff); 00381 npteg = hashmask + 1; 00382 00383 for( pteh = 0; pteh < 0x80; pteh += 64, hash ^= 0x7ffff ) { 00384 ptegaddr = ((hashmask & hash) * 64) + physbase; 00385 00386 for( i = 0; i < 8; i++ ) { 00387 ptehi = GetPhys( ptegaddr + (i * 8) ); 00388 ptelo = GetPhys( ptegaddr + (i * 8) + 4 ); 00389 00390 ptevsid = (ptehi >> 7) & 0xffffff; 00391 pteapi = ptehi & 0x3f; 00392 00393 if( (ptehi & 64) != pteh ) continue; 00394 if( ptevsid != (vsid & 0xffffff) ) continue; 00395 if( pteapi != ((virt >> 22) & 0x3f) ) continue; 00396 00397 return (ptelo & 0xfffff000) | (virt & 0xfff); 00398 } 00399 } 00400 return -1; 00401 } else { 00402 return virt; 00403 } 00404 } 00405 00406 int PtegNumber(vaddr_t virt, int hfun) 00407 { 00408 int sr = GetSR( (virt >> 28) & 0xf ); 00409 int vsid = sr & PPC_VSID_MASK; 00410 return ((((vsid & 0x7ffff) ^ ((virt >> 12) & 0xffff)) ^ (hfun ? -1 : 0)) & ((HTABSIZ - 1) >> 3) & 0x3ff); 00411 } Generated on Sun May 27 2012 04:36:15 for ReactOS by
1.7.6.1
|