Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmmuobject.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
1.7.6.1
|