ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

mmuutil.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.