Author: arty Date: Sun Oct 22 11:24:21 2006 New Revision: 24597
URL: http://svn.reactos.org/svn/reactos?rev=24597&view=rev Log: Build an entirely new page table.
Modified: branches/powerpc/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c branches/powerpc/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c branches/powerpc/reactos/boot/freeldr/freeldr/include/mmu.h
Modified: branches/powerpc/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c URL: http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/boot/freeldr/fre... ============================================================================== --- branches/powerpc/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c (original) +++ branches/powerpc/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c Sun Oct 22 11:24:21 2006 @@ -139,44 +139,92 @@ } }
+typedef struct _DIRECTORY_ENTRY { + ULONG Virt, Phys; +} DIRECTORY_ENTRY; + +typedef struct _DIRECTORY_HEADER { + UINT NumberOfPages; + UINT DirectoryPage, UsedSpace; + DIRECTORY_ENTRY *Directory[1]; +} DIRECTORY_HEADER; + +DIRECTORY_ENTRY * +GetPageMapping( DIRECTORY_HEADER *TranslationMap, ULONG Number ) { + if( Number >= (ULONG)TranslationMap->NumberOfPages ) return 0; + else { + int EntriesPerPage = (1<<PFN_SHIFT)/sizeof(DIRECTORY_ENTRY); + return &TranslationMap->Directory + [Number/EntriesPerPage][Number%EntriesPerPage]; + } +} + +VOID +AddPageMapping( DIRECTORY_HEADER *TranslationMap, + ULONG Virt, + ULONG OldVirt) { + ULONG Phys; + DIRECTORY_ENTRY *Entry; + if( !TranslationMap->DirectoryPage || + TranslationMap->UsedSpace >= ((1<<PFN_SHIFT)/sizeof(DIRECTORY_ENTRY)) ) + { + TranslationMap->Directory + [TranslationMap->DirectoryPage] = MmAllocateMemory(1<<PFN_SHIFT); + TranslationMap->UsedSpace = 0; + TranslationMap->DirectoryPage++; + AddPageMapping + (TranslationMap, + (ULONG)TranslationMap->Directory + [TranslationMap->DirectoryPage-1],0); + } + Phys = PpcVirt2phys(Virt,0); + TranslationMap->NumberOfPages++; + Entry = GetPageMapping(TranslationMap, TranslationMap->NumberOfPages-1); + Entry->Virt = OldVirt ? OldVirt : Virt; Entry->Phys = Phys; + TranslationMap->UsedSpace++; +} + VOID NTAPI FrLdrStartup(ULONG Magic) { KernelEntryFn KernelEntryAddress = (KernelEntryFn)(KernelEntry + KernelBase); - register ULONG_PTR i asm("r4"), j asm("r5"); - UINT NeededPTE = ((UINT)KernelMemory) >> PFN_SHIFT; - UINT NeededMemory = - (2 * sizeof(ULONG_PTR) * (NeededPTE + NeededPTE / 512)) + - sizeof(BootInfo) + sizeof(BootDigits); - UINT NeededPages = ROUND_UP(NeededMemory,(1<<PFN_SHIFT)); - register PULONG_PTR TranslationMap asm("r6") = - MmAllocateMemory(NeededMemory); + register ULONG_PTR i asm("r4"), j asm("r5") = 0; + register DIRECTORY_HEADER *TranslationMap asm("r6") = + MmAllocateMemory(1<<PFN_SHIFT); boot_infos_t *LocalBootInfo = (boot_infos_t *)TranslationMap; - TranslationMap = (PULONG_PTR) + TranslationMap = (DIRECTORY_HEADER *) (((PCHAR)&LocalBootInfo[1]) + sizeof(BootDigits)); memcpy(&LocalBootInfo[1], BootDigits, sizeof(BootDigits)); *LocalBootInfo = BootInfo; LocalBootInfo->dispFont = (font_char *)&LocalBootInfo[1]; - - TranslationMap[0] = (ULONG_PTR)FrLdrStartup; - for( i = 1; i < NeededPages; i++ ) - { - TranslationMap[i*2] = NeededMemory+(i<<PFN_SHIFT); - } - - for( j = 0; j < KernelMemorySize>>PFN_SHIFT; j++ ) - { - TranslationMap[(i+j)*2] = ((UINT)(KernelMemory+(i<<PFN_SHIFT))); - } - - for( i = 0; i < j; i++ ) - { - TranslationMap[(i*2)+1] = PpcVirt2phys(TranslationMap[i*2],0); - } - - printf("Built map of %d pages\n", j); + ULONG_PTR KernelVirtAddr, NewMapSdr = + (ULONG_PTR)MmAllocateMemory(128*1024); + DIRECTORY_ENTRY *Entry; + + NewMapSdr = ROUND_UP(NewMapSdr,64*1024); + printf("New SDR1 value will be %x\n", NewMapSdr); + + memset(TranslationMap,0,sizeof(*TranslationMap)); + + /* Add the page containing the page directory */ + AddPageMapping( TranslationMap, (ULONG)TranslationMap, 0 ); + + /* Map freeldr space 0xe00000 ... 0xe50000 */ + for( i = 0xe00000; i < 0xe50000; i += (1<<PFN_SHIFT),j++ ) { + AddPageMapping( TranslationMap, i, 0 ); + } + + /* Map kernel space 0x80000000 ... */ + for( i = (ULONG)KernelMemory; + i < (ULONG)KernelMemory + KernelMemorySize; + i += (1<<PFN_SHIFT),j++ ) { + KernelVirtAddr = LoaderBlock.KernelBase + (i - (ULONG)KernelMemory); + AddPageMapping( TranslationMap, i, KernelVirtAddr ); + } + + printf("Built map of %d pages\n", TranslationMap->NumberOfPages);
/* * Stuff page table entries for the page containing this code, @@ -185,22 +233,20 @@ * * When done, we'll be able to flop over to kernel land! */ - for( i = 0; i < j; i++ ) - { - DrawNumber(LocalBootInfo,i,10,90); - DrawNumber(LocalBootInfo,TranslationMap[i*2],10,100); - DrawNumber(LocalBootInfo,TranslationMap[i*2+1],10,110); - - InsertPageEntry - (TranslationMap[i*2], - TranslationMap[(i*2)+1], - (i>>10)); + for( i = 0, Entry = GetPageMapping( TranslationMap, i ); + Entry; + i++, Entry = GetPageMapping( TranslationMap, i ) ) { + DrawNumber(LocalBootInfo,Entry->Virt,10,90); + DrawNumber(LocalBootInfo,Entry->Phys,100,90); + InsertPageEntry( Entry->Virt, Entry->Phys, + (i & 0x3ff) >> 3, NewMapSdr ); }
/* Tell them we're booting */ - DrawNumber(LocalBootInfo,0x1cabba9e,10,120); - DrawNumber(LocalBootInfo,(ULONG)KernelEntryAddress,100,120); - + DrawNumber(LocalBootInfo,0x1cabba9e,10,100); + DrawNumber(LocalBootInfo,(ULONG)KernelEntryAddress,100,100); + + SetSDR1( NewMapSdr ); KernelEntryAddress( (void*)LocalBootInfo ); while(1); } @@ -481,6 +527,10 @@ LongPtr = (PULONG)ShortPtr; *LongPtr += Delta; break; + + default: + printf("Unknown relocation %d\n", *TypeOffset >> 12); + break; }
TypeOffset++;
Modified: branches/powerpc/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c URL: http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/boot/freeldr/fre... ============================================================================== --- branches/powerpc/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c (original) +++ branches/powerpc/reactos/boot/freeldr/freeldr/arch/powerpc/mmu.c Sun Oct 22 11:24:21 2006 @@ -227,6 +227,10 @@ register int res asm("r3"); __asm__("mfsdr1 3"); return res; +} + +inline void SetSDR1( int sdr ) { + __asm__("mtsdr1 3"); }
inline int BatHit( int bath, int batl, int virt ) { @@ -293,9 +297,9 @@ }
/* Add a new page table entry for the indicated mapping */ -BOOLEAN InsertPageEntry( int virt, int phys, int slot ) { +BOOLEAN InsertPageEntry( int virt, int phys, int slot, int _sdr1 ) { int i, ptehi, ptelo; - int sdr1 = GetSDR1(); + int sdr1 = _sdr1 ? _sdr1 : GetSDR1(); int sr = GetSR( (virt >> 28) & 0xf ); int vsid = sr & 0xfffffff; int physbase = sdr1 & ~0xffff; @@ -303,7 +307,7 @@ int valo = (vsid << 28) | (virt & 0xfffffff); int hash = (vsid & 0x7ffff) ^ ((valo >> 12) & 0xffff); int ptegaddr = ((hashmask & hash) * 64) + physbase; - + for( i = 0; i < 8; i++ ) { ptehi = GetPhys( ptegaddr + (i * 8) ); @@ -315,6 +319,12 @@ SetPhys( ptegaddr + (i * 8), ptehi ); SetPhys( ptegaddr + (i * 8) + 4, ptelo );
+ __asm__("ptesync"); + __asm__("tlbie %0,0" : : "r" (virt)); + __asm__("eieio"); + __asm__("tlbsync"); + __asm__("ptesync"); + return TRUE; }
Modified: branches/powerpc/reactos/boot/freeldr/freeldr/include/mmu.h URL: http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/boot/freeldr/fre... ============================================================================== --- branches/powerpc/reactos/boot/freeldr/freeldr/include/mmu.h (original) +++ branches/powerpc/reactos/boot/freeldr/freeldr/include/mmu.h Sun Oct 22 11:24:21 2006 @@ -12,10 +12,11 @@ void GetBat( int bat, int inst, int *batHi, int *batLo ); void SetBat( int bat, int inst, int batHi, int batLo ); int GetSDR1(); +void SetSDR1( int newsdr ); int BatHit( int bath, int batl, int virt ); int BatTranslate( int bath, int batl, int virt ); /* translate address */ int PpcVirt2phys( int virt, int inst ); -BOOLEAN InsertPageEntry( int virt, int phys, int slot ); +BOOLEAN InsertPageEntry( int virt, int phys, int slot, int sdr );
#endif/*FREELDR_MMU_H*/