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/fr…
==============================================================================
--- 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/fr…
==============================================================================
--- 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/fr…
==============================================================================
--- 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*/