Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmmu.c
Go to the documentation of this file.
00001 #include <freeldr.h> 00002 #include "ppcmmu/mmu.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 asm ("r3"); 00138 switch( n ) { 00139 case 0: 00140 __asm__("mfsr 3,0"); 00141 break; 00142 case 1: 00143 __asm__("mfsr 3,1"); 00144 break; 00145 case 2: 00146 __asm__("mfsr 3,2"); 00147 break; 00148 case 3: 00149 __asm__("mfsr 3,3"); 00150 break; 00151 case 4: 00152 __asm__("mfsr 3,4"); 00153 break; 00154 case 5: 00155 __asm__("mfsr 3,5"); 00156 break; 00157 case 6: 00158 __asm__("mfsr 3,6"); 00159 break; 00160 case 7: 00161 __asm__("mfsr 3,7"); 00162 break; 00163 case 8: 00164 __asm__("mfsr 3,8"); 00165 break; 00166 case 9: 00167 __asm__("mfsr 3,9"); 00168 break; 00169 case 10: 00170 __asm__("mfsr 3,10"); 00171 break; 00172 case 11: 00173 __asm__("mfsr 3,11"); 00174 break; 00175 case 12: 00176 __asm__("mfsr 3,12"); 00177 break; 00178 case 13: 00179 __asm__("mfsr 3,13"); 00180 break; 00181 case 14: 00182 __asm__("mfsr 3,14"); 00183 break; 00184 case 15: 00185 __asm__("mfsr 3,15"); 00186 break; 00187 } 00188 return res; 00189 } 00190 00191 inline void GetBat( int bat, int inst, int *batHi, int *batLo ) { 00192 register int bh asm("r3"), bl asm("r4"); 00193 if( inst ) { 00194 switch( bat ) { 00195 case 0: 00196 __asm__("mfibatu 3,0"); 00197 __asm__("mfibatl 4,0"); 00198 break; 00199 case 1: 00200 __asm__("mfibatu 3,1"); 00201 __asm__("mfibatl 4,1"); 00202 break; 00203 case 2: 00204 __asm__("mfibatu 3,2"); 00205 __asm__("mfibatl 4,2"); 00206 break; 00207 case 3: 00208 __asm__("mfibatu 3,3"); 00209 __asm__("mfibatl 4,3"); 00210 break; 00211 } 00212 } else { 00213 switch( bat ) { 00214 case 0: 00215 __asm__("mfdbatu 3,0"); 00216 __asm__("mfdbatl 4,0"); 00217 break; 00218 case 1: 00219 __asm__("mfdbatu 3,1"); 00220 __asm__("mfdbatl 4,1"); 00221 break; 00222 case 2: 00223 __asm__("mfdbatu 3,2"); 00224 __asm__("mfdbatl 4,2"); 00225 break; 00226 case 3: 00227 __asm__("mfdbatu 3,3"); 00228 __asm__("mfdbatl 4,3"); 00229 break; 00230 } 00231 } 00232 *batHi = bh; 00233 *batLo = bl; 00234 } 00235 00236 inline void SetBat( int bat, int inst, int batHi, int batLo ) { 00237 register int bh asm("r3"), bl asm("r4"); 00238 bh = batHi; 00239 bl = batLo; 00240 if( inst ) { 00241 switch( bat ) { 00242 case 0: 00243 __asm__("mtibatu 0,3"); 00244 __asm__("mtibatl 0,4"); 00245 break; 00246 case 1: 00247 __asm__("mtibatu 1,3"); 00248 __asm__("mtibatl 1,4"); 00249 break; 00250 case 2: 00251 __asm__("mtibatu 2,3"); 00252 __asm__("mtibatl 2,4"); 00253 break; 00254 case 3: 00255 __asm__("mtibatu 3,3"); 00256 __asm__("mtibatl 3,4"); 00257 break; 00258 } 00259 } else { 00260 switch( bat ) { 00261 case 0: 00262 __asm__("mtdbatu 0,3"); 00263 __asm__("mtdbatl 0,4"); 00264 break; 00265 case 1: 00266 __asm__("mtdbatu 1,3"); 00267 __asm__("mtdbatl 1,4"); 00268 break; 00269 case 2: 00270 __asm__("mtdbatu 2,3"); 00271 __asm__("mtdbatl 2,4"); 00272 break; 00273 case 3: 00274 __asm__("mtdbatu 3,3"); 00275 __asm__("mtdbatl 3,4"); 00276 break; 00277 } 00278 } 00279 __asm__("isync\n\tsync"); 00280 } 00281 00282 inline int GetSDR1() { 00283 register int res asm("r3"); 00284 __asm__("mfsdr1 3"); 00285 return res; 00286 } 00287 00288 inline void SetSDR1( int sdr ) { 00289 #if 0 00290 int i,j; 00291 #endif 00292 __asm__("mtsdr1 3"); 00293 #if 0 00294 __asm__("sync"); 00295 __asm__("isync"); 00296 __asm__("ptesync"); 00297 00298 for( i = 0; i < 256; i++ ) { 00299 j = i << 12; 00300 __asm__("tlbie %0,0" : : "r" (j)); 00301 } 00302 __asm__("eieio"); 00303 __asm__("tlbsync"); 00304 __asm__("ptesync"); 00305 #endif 00306 } 00307 00308 inline int BatHit( int bath, int batl, int virt ) { 00309 int mask = 0xfffe0000 & ~((batl & 0x3f) << 17); 00310 return (batl & 0x40) && ((virt & mask) == (bath & mask)); 00311 } 00312 00313 inline int BatTranslate( int bath, int batl, int virt ) { 00314 return (virt & 0x007fffff) | (batl & 0xfffe0000); 00315 } 00316 00317 /* translate address */ 00318 int PpcVirt2phys( int virt, int inst ) { 00319 int msr = GetMSR(); 00320 int txmask = inst ? 0x20 : 0x10; 00321 int i, bath, batl, sr, sdr1, physbase, valo; 00322 int hash, hashmask, ptehi, ptelo, ptegaddr; 00323 //int vahi, npteg; 00324 int vsid, pteh, ptevsid, pteapi; 00325 00326 if( msr & txmask ) { 00327 sr = GetSR( virt >> 28 ); 00328 vsid = sr & 0xfffffff; 00329 //vahi = vsid >> 4; 00330 valo = (vsid << 28) | (virt & 0xfffffff); 00331 if( sr & 0x80000000 ) { 00332 return valo; 00333 } 00334 00335 for( i = 0; i < 4; i++ ) { 00336 GetBat( i, inst, &bath, &batl ); 00337 if( BatHit( bath, batl, virt ) ) { 00338 return BatTranslate( bath, batl, virt ); 00339 } 00340 } 00341 00342 sdr1 = GetSDR1(); 00343 00344 physbase = sdr1 & ~0xffff; 00345 hashmask = ((sdr1 & 0x1ff) << 10) | 0x3ff; 00346 hash = (vsid & 0x7ffff) ^ ((valo >> 12) & 0xffff); 00347 //npteg = hashmask + 1; 00348 00349 for( pteh = 0; pteh < 0x80; pteh += 64, hash ^= 0x7ffff ) { 00350 ptegaddr = ((hashmask & hash) * 64) + physbase; 00351 00352 for( i = 0; i < 8; i++ ) { 00353 ptehi = GetPhys( ptegaddr + (i * 8) ); 00354 ptelo = GetPhys( ptegaddr + (i * 8) + 4 ); 00355 00356 ptevsid = (ptehi >> 7) & 0xffffff; 00357 pteapi = ptehi & 0x3f; 00358 00359 if( (ptehi & 64) != pteh ) continue; 00360 if( ptevsid != (vsid & 0xffffff) ) continue; 00361 if( pteapi != ((virt >> 22) & 0x3f) ) continue; 00362 00363 return (ptelo & 0xfffff000) | (virt & 0xfff); 00364 } 00365 } 00366 return -1; 00367 } else { 00368 return virt; 00369 } 00370 } 00371 00372 /* Add a new page table entry for the indicated mapping */ 00373 BOOLEAN InsertPageEntry( int virt, int phys, int slot, int _sdr1 ) { 00374 int i, ptehi, ptelo; 00375 int sdr1 = _sdr1 ? _sdr1 : GetSDR1(); 00376 int sr = GetSR( (virt >> 28) & 0xf ); 00377 int vsid = sr & 0xfffffff; 00378 int physbase = sdr1 & ~0xffff; 00379 int hashmask = ((sdr1 & 0x1ff) << 10) | 0x3ff; 00380 int valo = (vsid << 28) | (virt & 0xfffffff); 00381 int hash = (vsid & 0x7ffff) ^ ((valo >> 12) & 0xffff); 00382 int ptegaddr = ((hashmask & hash) * 64) + physbase; 00383 00384 for( i = 0; i < 8; i++ ) { 00385 ptehi = GetPhys( ptegaddr + (i * 8) ); 00386 00387 if( (slot != i) && (ptehi & 0x80000000) ) continue; 00388 00389 ptehi = (1 << 31) | (vsid << 7) | ((virt >> 22) & 0x3f); 00390 ptelo = phys & ~0xfff; 00391 00392 SetPhys( ptegaddr + (i * 8), ptehi ); 00393 SetPhys( ptegaddr + (i * 8) + 4, ptelo ); 00394 00395 return TRUE; 00396 } 00397 00398 return FALSE; 00399 } Generated on Sun May 27 2012 04:19:09 for ReactOS by
1.7.6.1
|