[ros-diffs] [arty] 24597: Build an entirely new page table.

arty at svn.reactos.org arty at svn.reactos.org
Sun Oct 22 09:24:21 CEST 2006


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/freeldr/arch/powerpc/mboot.c?rev=24597&r1=24596&r2=24597&view=diff
==============================================================================
--- 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/freeldr/arch/powerpc/mmu.c?rev=24597&r1=24596&r2=24597&view=diff
==============================================================================
--- 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/freeldr/include/mmu.h?rev=24597&r1=24596&r2=24597&view=diff
==============================================================================
--- 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*/




More information about the Ros-diffs mailing list