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

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

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