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

mmuobject.c
Go to the documentation of this file.
00001 #include <stdarg.h>
00002 #include "ppcmmu/mmu.h"
00003 #include "ppcmmu/mmuutil.h"
00004 #include "mmuobject.h"
00005 
00006 typedef unsigned long ULONG;
00007 
00008 /*
00009 
00010 The MMU Object:
00011 0x00300 -- Data miss
00012 0x00400 -- Instruction miss
00013 0x10000 -- Entry point
00014 ...        Code
00015 0x20000 -- Physical map (PTE + Process Ptr + Address : 16 bytes)
00016 
00017 4096 / 16 bytes = 256 entries per page
00018 256 pages = 1Megabyte = 1 page table page
00019 
00020 Setup by freeldr and used to build the kernel map, then used by the kernel
00021 
00022 Calling:
00023 
00024 r3       -- Action
00025 r4 .. r6 -- Args
00026 
00027 Actions:
00028 00 Init
00029 01 Map pages
00030 02 erase pages
00031 03 set segment vsid
00032 04 page miss callback
00033 05 inquire page
00034 06 unit test
00035 07 alloc page
00036 08 set memory size
00037 09 get first usable page
00038 10 alloc vsid
00039 11 revoke vsid
00040 */
00041 
00042 #define MMU_ADDR_RESERVED ((vaddr_t)-2)
00043 
00044 MmuTrapHandler callback[0x30];
00045 typedef struct _MmuFreePage {
00046     int page;
00047     struct _MmuFreePage *next;
00048 } MmuFreePage;
00049 typedef struct _MmuFreeTree {
00050     struct _MmuFreeTree *next;
00051 } MmuFreeTree;
00052 typedef struct _MmuVsidTree {
00053     ppc_map_t *leaves[256];
00054 } MmuVsidTree;
00055 typedef struct _MmuVsidInfo {
00056     int vsid;
00057     struct _MmuVsidInfo *next;
00058     MmuVsidTree *tree[256];
00059 } MmuVsidInfo;
00060 MmuFreePage *FreeList = 0;
00061 // Pages are allocated one by one until NextPage == RamSize >> PPC_PAGE_SHIFT
00062 // Then we take only from the free list
00063 int Clock = 0, TreeAlloc = 0, GdbAttach = 0, Booted = 0, Vsid[16];
00064 paddr_t RamSize, FirstUsablePage, NextPage;
00065 MmuVsidTree *NextTreePage = 0;
00066 MmuFreeTree *FreeTree;
00067 MmuVsidInfo *Segs[16], *VsidHead = 0;
00068 
00069 extern void fmtout(const char *fmt, ...);
00070 extern char *serport;
00071 int ptegreload(ppc_trap_frame_t *frame, vaddr_t addr);
00072 void SerialSetUp(int deviceType, void *deviceAddr, int baud);
00073 int SerialInterrupt(int n, ppc_trap_frame_t *tf);
00074 void TakeException(int n, ppc_trap_frame_t *tf);
00075 int mmuisfreepage(paddr_t pageno);
00076 void copy(void *t, void *s, int b);
00077 paddr_t mmunewpage();
00078 void dumpmap();
00079 void trapcallback(int action, ppc_trap_frame_t *trap_frame);
00080 
00081 int _mmumain(int action, void *arg1, void *arg2, void *arg3, void *tf)
00082 {
00083     ppc_trap_frame_t *trap_frame = (action >= 0x100) ? tf : arg1;
00084     int ret = 0, tmp, i;
00085 
00086     switch(action)
00087     {
00088         /* Trap Handlers */
00089     case 3:
00090     if(!ptegreload(trap_frame, trap_frame->dar))
00091     {
00092             trapcallback(action, trap_frame);
00093         }
00094     break;
00095     case 4:
00096     if(!ptegreload(trap_frame, trap_frame->srr0))
00097         {
00098             trapcallback(action, trap_frame);
00099         }
00100     break;
00101 
00102     case 5:
00103         /* EE -- Try to get a serial interrupt if debugging enabled, then fall
00104          * back to primary handler 
00105          */
00106         if (!SerialInterrupt(action, trap_frame) && callback[action]) 
00107         {
00108             trapcallback(action, trap_frame);
00109         }
00110         break;
00111     case 0:
00112     case 2:
00113     case 6:
00114     case 7:
00115     case 8:
00116     case 9:
00117     case 0xa:
00118     case 0xc:
00119     case 0x20:
00120         trapcallback(action, trap_frame);
00121         break;
00122 
00123         /* MMU Functions */
00124     case 0x100:
00125     initme();
00126         trap_frame->srr1 |= 0x8000;
00127     break;
00128     case 0x101:
00129     ret = mmuaddpage(arg1, (int)arg2);
00130     break;
00131     case 0x102:
00132     mmudelpage(arg1, (int)arg2);
00133     break;
00134     case 0x103:
00135     mmusetvsid((int)arg1, (int)arg2, (int)arg3);
00136     break;
00137     case 0x104:
00138     ret = (int)callback[(int)arg1];
00139     callback[(int)arg1] = (MmuTrapHandler)arg2;
00140     break;
00141     case 0x105:
00142     mmugetpage(arg1, (int)arg2);
00143     break;
00144     case 0x106:
00145     ret = mmunitest();
00146     break;
00147     case 0x107:
00148         callkernel(arg1, arg2);
00149     break;
00150     case 0x108:
00151     mmusetramsize((paddr_t)arg1);
00152     break;
00153     case 0x109:
00154     return FirstUsablePage;
00155     case 0x10a:
00156     mmuallocvsid((int)arg1, (int)arg2);
00157     break;
00158     case 0x10b:
00159     mmufreevsid((int)arg1, (int)arg2);
00160     break;
00161     case 0x10c:
00162         ret = mmunewpage();
00163         break;
00164     case 0x10d:
00165         copy(trap_frame, (void *)0xf040, sizeof(*trap_frame));
00166         __asm__("mr 1,%0\n\tb trap_finish_start" : : "r" 
00167                 (((int)trap_frame) - 16));
00168         break;
00169     case 0x10e:
00170         dumpmap();
00171         break;
00172 
00173     case 0x200:
00174         SerialSetUp((int)arg1, arg2, 9600);
00175         break;
00176     case 0x201:
00177         TakeException((int)arg1, trap_frame);
00178         break;
00179 
00180     default:
00181     while(1);
00182     }
00183 
00184     /* Restore bats when we were called voluntarily.  We may not get a chance
00185      * to do this after returning.
00186      *
00187      * At this point, we're in address space that matches physical space.
00188      * We turn off mapping, restore bats, then let rfi switch us back to where
00189      * we came.
00190      */
00191 
00192     if (action >= 0x100)
00193     {
00194         __asm__("mfmsr %0" : "=r" (tmp));
00195         tmp &= ~0x30;
00196         __asm__("mtmsr %0" : : "r" (tmp));
00197         
00198         for(i = 0; i < 4; i++) {
00199             SetBat(i, 0, GetPhys(0xf000 + i * 16), GetPhys(0xf004 + i * 16));
00200             SetBat(i, 1, GetPhys(0xf008 + i * 16), GetPhys(0xf00c + i * 16));
00201         }
00202     }
00203 
00204     return ret;
00205 }
00206 
00207 void trapcallback(int action, ppc_trap_frame_t *trap_frame)
00208 {
00209     if ((paddr_t)callback[action] < PAGETAB)
00210         callback[action](action, trap_frame);
00211     else
00212     {
00213         int framecopy = 0xf040;
00214         copy((void *)framecopy, trap_frame, sizeof(*trap_frame));
00215         trap_frame->srr0 = (int)callback[action];
00216         trap_frame->srr1 &= 0x7fff;
00217         trap_frame->gpr[3] = action;
00218         trap_frame->gpr[4] = framecopy;
00219         __asm__("mr 1,%0\n\tsubi 1,1,16\n\tb trap_finish_start" : : "r" (trap_frame));
00220     }
00221 }
00222 
00223 void outchar(char c)
00224 {
00225     SetPhysByte(0x800003f8, c);
00226 }
00227 
00228 void copy(void *target, void *src, int bytes)
00229 {
00230     while(bytes--) *((char *)target++) = *((char *)src++);
00231 }
00232 
00233 void outstr(const char *str)
00234 {
00235     while(*str) outchar(*str);
00236 }
00237 
00238 void outdig(int dig)
00239 {
00240     if(dig < 10) outchar(dig + '0');
00241     else outchar(dig - 10 + 'A');
00242 }
00243 
00244 void outnum(unsigned long num)
00245 {
00246     int i;
00247     for( i = 0; i < 8; i++ ) 
00248     {
00249     outdig(num >> 28);
00250     num <<= 4;
00251     }
00252 }
00253 
00254 void fmtout(const char *str, ...)
00255 {
00256     va_list ap;
00257     va_start(ap, str);
00258     while(*str)
00259     {
00260     if(*str == '%')
00261     {
00262         if(str[1] == '%')
00263         {
00264         outchar('%');
00265         }
00266         else if(str[1] == 's')
00267         {
00268         outstr(va_arg(ap, const char *));
00269         }
00270         else
00271         {
00272         outnum(va_arg(ap, int));
00273         }
00274         str++;
00275     }
00276     else
00277     {
00278         outchar(*str);
00279     }
00280     str++;
00281     }
00282     va_end(ap);
00283 }
00284 
00285 void mmusetramsize(paddr_t ramsize)
00286 {
00287     ppc_map_t *last_map = &PpcPageTable[PPC_PAGE_NUMBER(ramsize)];
00288     if(!RamSize)
00289     {
00290     RamSize = ramsize;
00291     FirstUsablePage = (paddr_t)last_map;
00292     NextPage = PPC_PAGE_NUMBER(FirstUsablePage) + 1;
00293     }
00294 }
00295 
00296 int ignore(int trapCode, ppc_trap_frame_t *trap)
00297 {
00298     return 1;
00299 }
00300 
00301 int fpenable(int trapCode, ppc_trap_frame_t *trap)
00302 {
00303         /* Turn on FP */
00304         trap->srr1 |= 8192;
00305         return 1;
00306 }
00307 
00308 extern int trap_start[], trap_end[];
00309 void copy_trap_handler(int trap)
00310 {
00311     int i;
00312     paddr_t targetArea = trap * 0x100;
00313 
00314     /* Set target addr */
00315     trap_end[0] = (int)_mmumain;
00316 
00317     for (i = 0; i <= trap_end - trap_start; i++)
00318     {
00319         SetPhys(targetArea + (i * sizeof(int)), trap_start[i]);
00320     }
00321 }
00322 
00323 void initme()
00324 {
00325     int i;
00326 
00327     for(i = 0; i < HTABSIZ / sizeof(int); i++)
00328     {
00329     ((int *)HTABORG)[i] = 0;
00330     }
00331 
00332     /* Default to hang on unknown exception */
00333     for(i = 0; i < 30; i++)
00334     {
00335         callback[i] = (MmuTrapHandler)TakeException;
00336         if (i != 1) /* Preserve reset handler */
00337             copy_trap_handler(i);
00338     }
00339 
00340     /* Serial Interrupt */
00341     callback[5] = 0; /* Do nothing until the user asks */
00342 
00343     /* Program Exception */
00344     callback[6] = (MmuTrapHandler)TakeException;
00345 
00346     /* Floating point exception */
00347     callback[8] = fpenable;
00348 
00349     /* Ignore decrementer and EE */
00350     callback[9] = ignore;
00351 
00352     /* Single Step */
00353     callback[0x20] = (MmuTrapHandler)TakeException;
00354 }
00355 
00356 ppc_map_t *allocpage()
00357 {
00358     MmuFreePage *FreePage = 0;
00359 
00360     if (FreeList)
00361     {
00362         if ((void *)FreeList == (void *)PpcPageTable)
00363         {
00364             fmtout("Problem! FreeList: page 0 is free\n");
00365             while(1);
00366         }
00367 
00368     FreePage = FreeList;
00369     FreeList = FreeList->next;
00370         ((ppc_map_t*)FreePage)->addr = MMU_ADDR_RESERVED;
00371     return ((ppc_map_t*)FreePage);
00372     }
00373     else
00374     {
00375         while(!mmuisfreepage(NextPage) && NextPage < PPC_PAGE_NUMBER(RamSize))
00376         {
00377             NextPage++;
00378         }
00379         if (NextPage < PPC_PAGE_NUMBER(RamSize))
00380         {
00381             if (NextPage < 0x30)
00382             {
00383                 fmtout("Problem! NextPage is low (%x)\n", NextPage);
00384                 while(1);
00385             }
00386             
00387             PpcPageTable[NextPage].addr = MMU_ADDR_RESERVED;
00388             return &PpcPageTable[NextPage++];
00389         }
00390         else
00391         {
00392             return NULL;
00393         }
00394     }
00395 }
00396 
00397 void freepage(ppc_map_t *PagePtr)
00398 {
00399     MmuFreePage *FreePage = (MmuFreePage*)PagePtr;
00400     PagePtr->proc = PagePtr->addr = 0;
00401     FreePage->next = FreeList;
00402     FreeList = FreePage;
00403 }
00404 
00405 MmuVsidTree *allocvsidtree()
00406 {
00407     if(FreeTree)
00408     {
00409     MmuVsidTree *result = (MmuVsidTree*)FreeTree;
00410     FreeTree = FreeTree->next;
00411     return result;
00412     }
00413     else if(TreeAlloc >= 3 || !NextTreePage)
00414     {
00415     ppc_map_t *map = allocpage();
00416     NextTreePage = (MmuVsidTree*)PPC_PAGE_ADDR((map - PpcPageTable));
00417     TreeAlloc = 1;
00418     return NextTreePage;
00419     }
00420     else
00421     {
00422     return &NextTreePage[TreeAlloc++];
00423     }
00424 }
00425 
00426 void freevsidtree(MmuVsidTree *tree)
00427 {
00428     int i;
00429     for(i = 0; i < 256; i++)
00430     if(tree->leaves[i])
00431         freepage(tree->leaves[i]);
00432     MmuFreeTree *NextFreeTree = (MmuFreeTree *)tree;
00433     NextFreeTree->next = FreeTree;
00434     FreeTree = NextFreeTree;
00435 }
00436 
00437 void *allocvsid(int vsid)
00438 {
00439     ppc_map_t *map = allocpage();
00440     MmuVsidInfo *info;
00441     if(!map) return 0;
00442     map->pte.pteh = map->pte.ptel = 0;
00443     info = (MmuVsidInfo*)PPC_PAGE_ADDR((map - PpcPageTable));
00444     info->vsid = vsid;
00445     info->next = VsidHead;
00446     VsidHead = info;
00447     return info;
00448 }
00449 
00450 void mmuallocvsid(int vsid, int mask)
00451 {
00452     int i;
00453     for(i = 0; i < 16; i++)
00454     {
00455     if(mask & (1 << i))
00456         allocvsid((vsid << 4) + i);
00457     }
00458 }
00459 
00460 MmuVsidInfo *findvsid(int vsid)
00461 {
00462     MmuVsidInfo *info;
00463     for(info = VsidHead; info; info = info->next)
00464     {
00465     if(info->vsid == vsid) return info;
00466     }
00467     return 0;
00468 }
00469 
00470 void freevsid(int vsid)
00471 {
00472     int i;
00473     MmuVsidInfo *info = findvsid(vsid);
00474     if(!info) return;
00475     ppc_map_t *map = &PpcPageTable[PPC_PAGE_NUMBER((paddr_t)info)];
00476     for(i = 0; i < 256; i++)
00477     {
00478     if(info->tree[i]) 
00479         freevsidtree(info->tree[i]);
00480     }
00481     freepage(map);
00482 }
00483 
00484 void mmufreevsid(int vsid, int mask)
00485 {
00486     int i;
00487     for(i = 0; i < 16; i++)
00488     {
00489     if(mask & (1 << i))
00490         freevsid((vsid << 4) + i);
00491     }    
00492 }
00493 
00494 int mmuaddpage(ppc_map_info_t *info, int count)
00495 {
00496     int i, iva = 0, vsid, phys, virt;
00497     int ptehi;
00498     int ptelo, vsid_table_hi, vsid_table_lo;
00499     ppc_map_t *PagePtr;
00500     MmuVsidInfo *VsidInfo;
00501     MmuVsidTree *VsidTree;
00502 
00503     for(i = 0; i < count; i++)
00504     {
00505         info[i].phys &= ~PPC_PAGE_MASK;
00506         info[i].addr &= ~PPC_PAGE_MASK;
00507 
00508     virt = info[i].addr;
00509     vsid = ((info[i].addr >> 28) & 15) | (info[i].proc << 4);
00510     VsidInfo = findvsid(vsid);
00511 
00512     if(!VsidInfo) return -1;
00513 
00514     ptehi = (1 << 31) | (vsid << 7) | ((virt >> 22) & 0x3f);
00515     
00516     if(info[i].phys) {
00517         PagePtr = &PpcPageTable[PPC_PAGE_NUMBER(info[i].phys)];
00518     } else {
00519         PagePtr = allocpage();
00520         if(!PagePtr)
00521         {
00522         return 0;
00523         }
00524     }
00525 
00526     phys = PPC_PAGE_ADDR((PagePtr - PpcPageTable));
00527     ptelo = phys & ~PPC_PAGE_MASK;
00528     
00529         if (phys < 0x30000)
00530         {
00531             /* Should not be allocating physical */
00532             fmtout("Allocated physical: %x, logical %x\n", phys, virt);
00533             fmtout("PagePtr %x (page %d)\n", PagePtr, i);
00534             fmtout("info [ %x %x %x %x ]\n", info[i].proc, info[i].addr, info[i].flags, info[i].phys);
00535             while(1);
00536         }
00537 
00538     /* Update page data */
00539     PagePtr->pte.pteh = ptehi;
00540     PagePtr->pte.ptel = ptelo;
00541     PagePtr->proc = info[i].proc;
00542     PagePtr->addr = virt;
00543 
00544     vsid_table_hi = virt >> 20 & 255;
00545     vsid_table_lo = virt >> 12 & 255;
00546 
00547     if(!VsidInfo->tree[vsid_table_hi])
00548         VsidInfo->tree[vsid_table_hi] = allocvsidtree();
00549     VsidTree = VsidInfo->tree[vsid_table_hi];
00550     if(!VsidTree) return 0;
00551     VsidTree->leaves[vsid_table_lo] = PagePtr;
00552 
00553     __asm__("tlbie %0\n\tsync\n\tisync" : : "r" (iva));
00554     }
00555     return 1;
00556 }
00557 
00558 paddr_t mmunewpage()
00559 {
00560     ppc_map_t *PagePtr = allocpage();
00561     if (!PagePtr) return 0;
00562     return PPC_PAGE_ADDR(PagePtr - PpcPageTable);
00563 }
00564 
00565 ppc_pteg_t *PtegFromPage(ppc_map_t *map, int hfun)
00566 {
00567     if(!map->proc && !map->addr) return 0;
00568     return &PpcHashedPTE[PtegNumber(map->addr, hfun)];
00569 }
00570 
00571 int PageMatch(vaddr_t addr, ppc_pte_t pte)
00572 {
00573     int vsid_pte = (pte.pteh >> 7) & 15, api_pte = pte.pteh & 63;
00574     return 
00575     (((addr >> 28) & 15) == vsid_pte) &&
00576     (((addr >> 22) & 63) == api_pte);
00577 }
00578 
00579 ppc_map_t *mmuvirtmap(vaddr_t addr)
00580 {
00581     int seg = (addr >> 28) & 15;
00582     MmuVsidInfo *seginfo = Segs[seg];
00583     MmuVsidTree *segtree = 0;
00584     if(!seginfo) return 0;
00585     segtree = seginfo->tree[(addr >> 20) & 255];
00586     if(!segtree) return 0;
00587     return segtree->leaves[(addr >> 12) & 255];
00588 }
00589 
00590 void mmudelpage(ppc_map_info_t *info, int count)
00591 {
00592     int i, j, k, ipa;
00593     ppc_map_t *PagePtr;
00594     ppc_pteg_t *PageEntry;
00595     ppc_pte_t ZeroPte = { 0 };
00596 
00597     for(i = 0; i < count; i++)
00598     {
00599     if (info[i].phys)
00600     {
00601         ipa = info[i].phys;
00602         PagePtr = &PpcPageTable[ipa];
00603         info[i].proc = PagePtr->proc;
00604         info[i].addr = PagePtr->addr;
00605     }
00606     else
00607     {
00608         PagePtr = mmuvirtmap(info[i].addr);
00609         ipa = PPC_PAGE_ADDR(PagePtr - PpcPageTable);
00610     }
00611 
00612     for(j = 0; j < 2; j++)
00613     {
00614         PageEntry = PtegFromPage(PagePtr, j);
00615         for(k = 0; k < 8; k++)
00616         {
00617         if(PageMatch(ipa, PageEntry->block[k]))
00618         {
00619             if(PageEntry->block[k].ptel & 0x100)
00620             info[i].flags |= MMU_PAGE_DIRTY;
00621             PageEntry->block[k] = ZeroPte;
00622         }
00623         }
00624     }
00625     freepage(PagePtr);
00626     __asm__("tlbie %0\n\tsync\n\tisync" : : "r" (info[i].addr));
00627     }
00628 }
00629 
00630 void mmugetpage(ppc_map_info_t *info, int count)
00631 {
00632     int i;
00633     ppc_map_t *PagePtr;
00634     
00635     for( i = 0; i < count; i++ )
00636     {
00637     if(!info[i].addr && !info[i].proc)
00638     {
00639         PagePtr = &((ppc_map_t*)PAGETAB)[info[i].phys];
00640             info[i].proc = PagePtr->proc;
00641             info[i].addr = PagePtr->addr;
00642             info[i].flags = MMU_ALL_RW;
00643     } else {
00644         vaddr_t addr = info[i].addr;
00645         int vsid = ((addr >> 28) & 15) | (info[i].proc << 4);
00646         PagePtr = mmuvirtmap(info[i].addr);
00647         if(!PagePtr)
00648         info[i].phys = 0;
00649         else
00650         {
00651         info[i].phys = PPC_PAGE_ADDR(PagePtr - PpcPageTable);
00652         info[i].flags = MMU_ALL_RW; // HACK
00653         }
00654     }
00655     }
00656 }
00657 
00658 int mmuisfreepage(paddr_t pageno)
00659 {
00660     ppc_map_t *PagePtr = PpcPageTable + pageno;
00661     return !PagePtr->addr;
00662 }
00663 
00664 void mmusetvsid(int start, int end, int vsid)
00665 {
00666     int i, sr, s_vsid;
00667     for(i = start; i < end; i++)
00668     {
00669     s_vsid = (vsid << 4) | (i & 15);
00670     sr = (GetSR(i) & ~PPC_VSID_MASK) | s_vsid;
00671     if (Booted)
00672             SetSR(i, sr);
00673     Segs[i] = findvsid(s_vsid);
00674         Vsid[i] = vsid;
00675     }
00676 }
00677 
00678 int ptegreload(ppc_trap_frame_t *frame, vaddr_t addr)
00679 {
00680     int hfun = (Clock >> 3) & 1, ptegnum = PtegNumber(addr, hfun);
00681     ppc_map_t *map = mmuvirtmap(addr);
00682     if(!map) return 0;
00683     map->pte.pteh = (map->pte.pteh & ~64) | (hfun << 6);
00684     PpcHashedPTE[ptegnum].block[Clock & 7] = map->pte;
00685 #if 0
00686     fmtout("Reloading addr %x (phys %x) at %x[%x] (%x:%x)\r\n",
00687        addr, PPC_PAGE_ADDR(map - PpcPageTable), ptegnum, Clock & 15,
00688        PpcHashedPTE[ptegnum].block[Clock&7].pteh,
00689        PpcHashedPTE[ptegnum].block[Clock&7].ptel);
00690 #endif
00691     Clock++;
00692     __asm__("tlbie %0\n\tsync\n\tisync" : : "r" (addr));
00693     return 1;
00694 }
00695 
00696 void printmap(vaddr_t vaddr, ppc_map_t *map)
00697 {
00698     fmtout("%x: proc %x addr %x\n", 
00699            PPC_PAGE_ADDR(map - PpcPageTable), 
00700            map->proc, vaddr);
00701 }
00702 
00703 void dumptree(vaddr_t vaddr, MmuVsidTree *tree)
00704 {
00705     int j;
00706 
00707     for (j = 0; j < 256; j++)
00708     {
00709         if (tree->leaves[j])
00710         {
00711             printmap(vaddr | (j << 12), tree->leaves[j]);
00712         }
00713     }
00714 }
00715 
00716 void dumpvsid(MmuVsidInfo *vsid)
00717 {
00718     int i;
00719 
00720     fmtout("vsid %d (%x):\n", vsid->vsid>>4, vsid->vsid<<28);
00721     for (i = 0; i < 256; i++)
00722     {
00723         if (vsid->tree[i])
00724         {
00725             dumptree((vsid->vsid<<28) | i << 20, vsid->tree[i]);
00726         }
00727     }
00728 }
00729 
00730 void dumpmap()
00731 {
00732     int i,j;
00733     ppc_map_t *map;
00734     MmuVsidInfo *vsid;
00735     fmtout("Address spaces:\n");
00736     for (vsid = VsidHead; vsid; vsid = vsid->next)
00737     {
00738         dumpvsid(vsid);
00739     }
00740 }
00741 
00742 void callkernel(void *fun_ptr, void *arg)
00743 {
00744     int i;
00745 
00746     Booted = 1;
00747 
00748     for (i = 0; i < 16; i++)
00749     {
00750         // Patch up the vsid map.  We shouldn't muck with these until we're
00751         // booted.
00752         mmusetvsid(i, i+1, Vsid[i]);
00753     }
00754 
00755     void (*fun)(void *) = fun_ptr;
00756     __asm__("mfmsr 3\n\t"
00757             "ori 3,3,0x30\n\t"
00758             "mtmsr 3\n\t"
00759             "mtsdr1 %0\n\t" 
00760             "mr 0,%2\n\t"
00761             "mtctr 0\n\t"
00762             "mr 3,%1\n\t"
00763             "bctrl\n\t"
00764             : : "r" (HTABORG), "r" (arg), "r" (fun));
00765     /* BYE ! */
00766 }

Generated on Sat May 26 2012 04:35:16 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.