Fixed, separated mmu related functions. We now get correct translations

in every case.

fat.c: workaround for now.  Need to figure out why the fs is b0rked.

svn path=/branches/powerpc/; revision=23893
This commit is contained in:
Art Yerkes
2006-09-03 03:37:20 +00:00
parent 62f408e7e6
commit 3cc6a119fb
8 changed files with 240 additions and 223 deletions
+13
View File
@@ -28,6 +28,19 @@ _begin:
/* Claim enough bytes to place freeldr at 0x8000 */
lis %r3,0x8000@ha
li %r3,0x8000@l
lis %r4,_binary_freeldr_tmp_end@ha
addi %r4,%r4,_binary_freeldr_tmp_end@l
lis %r5,_binary_freeldr_tmp_start@ha
addi %r5,%r5,_binary_freeldr_tmp_start@l
sub %r4,%r4,%r5
li %r5,0x1000
bl ofw_claim
/* Now copy freeldr */
lis %r3,0x8000@ha
addi %r3,%r3,0x8000@l
lis %r4,_binary_freeldr_tmp_end@ha
@@ -19,6 +19,7 @@
#include "freeldr.h"
#include "machine.h"
#include "of.h"
#include "mmu.h"
#define TOTAL_HEAP_NEEDED (16 * 1024 * 1024) /* 16 megs */
@@ -223,10 +224,6 @@ ULONG PpcGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap,
BiosMemoryMap[num_mem].Length = TOTAL_HEAP_NEEDED;
ofw_claim(BiosMemoryMap[num_mem].BaseAddress,
BiosMemoryMap[num_mem].Length, 0x1000); /* claim it */
printf("virt2phys(%x)->%x\n",
BiosMemoryMap[num_mem].BaseAddress,
ofw_virt2phys
(mmuhandle, BiosMemoryMap[num_mem].BaseAddress));
total += BiosMemoryMap[0].Length;
num_mem++;
}
@@ -378,197 +375,8 @@ BOOLEAN PpcDiskNormalizeSystemPath(char *SystemPath, unsigned Size) {
typedef unsigned int uint32_t;
int GetMSR() {
register int res asm ("r3");
__asm__("mfmsr 3");
return res;
}
int GetPhys( int addr ) {
register int res asm ("r3");
__asm__("mfmsr 5\n\t"
"mr 4,5\n\t"
"xor 1,1,1\n\t"
"addi 1,1,-1\n\t"
"xori 1,1,0x10\n\t"
"and 5,1,5\n\t"
"mtmsr 5\n\t"
"lwz 3,0(3)\n\t"
"mtmsr 4");
return res;
}
int GetSR(int n) {
register int res asm ("r3");
switch( n ) {
case 0:
__asm__("mfsr 3,0");
break;
case 1:
__asm__("mfsr 3,1");
break;
case 2:
__asm__("mfsr 3,2");
break;
case 3:
__asm__("mfsr 3,3");
break;
case 4:
__asm__("mfsr 3,4");
break;
case 5:
__asm__("mfsr 3,5");
break;
case 6:
__asm__("mfsr 3,6");
break;
case 7:
__asm__("mfsr 3,7");
break;
case 8:
__asm__("mfsr 3,8");
break;
case 9:
__asm__("mfsr 3,9");
break;
case 10:
__asm__("mfsr 3,10");
break;
case 11:
__asm__("mfsr 3,11");
break;
case 12:
__asm__("mfsr 3,12");
break;
case 13:
__asm__("mfsr 3,13");
break;
case 14:
__asm__("mfsr 3,14");
break;
case 15:
__asm__("mfsr 3,15");
break;
}
return res;
}
void GetBat( int bat, int inst, int *batHi, int *batLo ) {
register int bh asm("r3"), bl asm("r4");
if( inst ) {
switch( bat ) {
case 0:
__asm__("mfibatu 3,0");
__asm__("mfibatl 4,0");
break;
case 1:
__asm__("mfibatu 3,1");
__asm__("mfibatl 4,1");
break;
case 2:
__asm__("mfibatu 3,2");
__asm__("mfibatl 4,2");
break;
case 3:
__asm__("mfibatu 3,3");
__asm__("mfibatl 4,3");
break;
}
} else {
switch( bat ) {
case 0:
__asm__("mfdbatu 3,0");
__asm__("mfdbatl 4,0");
break;
case 1:
__asm__("mfdbatu 3,1");
__asm__("mfdbatl 4,1");
break;
case 2:
__asm__("mfdbatu 3,2");
__asm__("mfdbatl 4,2");
break;
case 3:
__asm__("mfdbatu 3,3");
__asm__("mfdbatl 4,3");
break;
}
}
*batHi = bh;
*batLo = bl;
}
int GetSDR1() {
register int res asm("r3");
__asm__("mfsdr1 3");
return res;
}
int BatHit( int bath, int batl, int virt ) {
return (virt & 0xfffc0000) == (bath & 0xfffc0000);
}
int BatTranslate( int bath, int batl, int virt ) {
return (virt & 0x3ffff) | (batl & 0xfffc0000);
}
/* translate address */
int virt2phys( int virt, int inst ) {
int msr = GetMSR();
int txmask = inst ? 0x20 : 0x10;
if( msr & txmask ) {
int i, bath, batl, sr, sdr1, physbase, vahi, valo;
int npteg, hash, ptegaddr, hashmask, ptehi, ptelo;
int vsid, pteh;
for( i = 0; i < 4; i++ ) {
GetBat( i, inst, &bath, &batl );
if( BatHit( bath, batl, virt ) ) {
return BatTranslate( bath, batl, virt );
}
}
sr = GetSR( virt >> 28 );
vsid = sr & 0xfffffff;
valo = (vsid << 28) | (virt & 0xfffffff);
if( sr & 0x80000000 )
return valo;
sdr1 = GetSDR1();
physbase = sdr1 & ~0xffff;
vahi = vsid >> 4;
npteg = ((sdr1 & 0x1ff) << 10);
hash = (vsid & 0x7ffff) ^ ((valo >> 12) & 0xffff);
hashmask = ((sdr1 & 0xffff) << 12) | 0x3ff;
for( pteh = 0; pteh < 0xff; pteh += 64, hash ^= ~0 ) {
ptegaddr = ((hashmask & hash) * 64) + physbase;
for( i = 0; i < 8; i++ ) {
int ptevsid, pteapi;
ptehi = GetPhys( ptegaddr + (i * 8) );
ptelo = GetPhys( ptegaddr + (i * 8) + 4 );
ptevsid = (ptehi >> 8) & 0x7fffff;
pteapi = ptehi & 0x3f;
//printf("pte[%d] @ %x = %x:%x\n",
//i, ptegaddr + (i * 8), ptehi, ptelo);
if( (ptehi & 64) != pteh ) continue;
if( ptevsid != (vsid & 0x7fffff) ) continue;
if( pteapi != ((virt >> 22) & 0x3f) ) continue;
return (ptelo & 0xfffff000) | (virt & 0xfff);
}
}
return -1;
} else return virt;
}
void PpcInit( of_proxy the_ofproxy ) {
int i, len, stdin_handle_chosen, bathi, batlo;
int len, stdin_handle_chosen;
ofproxy = the_ofproxy;
ofw_print_string("Freeldr PowerPC Init\n");
@@ -595,25 +403,8 @@ void PpcInit( of_proxy the_ofproxy ) {
MachVtbl.ConsGetCh = PpcConsGetCh;
printf( "stdin_handle is %x\n", stdin_handle );
/* List MMU Status */
printf("MSR %x\n", GetMSR());
for( i = 0; i < 16; i++ ) {
printf("SR%d %x\n", i, GetSR(i));
}
for( i = 0; i < 4; i++ ) {
GetBat( i, 0, &bathi, &batlo );
printf("DBAT%d %x:%x\n", i, bathi, batlo);
}
for( i = 0; i < 4; i++ ) {
GetBat( i, 1, &bathi, &batlo );
printf("IBAT%d %x:%x\n", i, bathi, batlo);
}
printf("virt2phys (0x8000,I) -> %x\n", virt2phys(0x8000,1));
printf("virt2phys (0xe00000,D) -> %x\n", virt2phys(0x60000000,0));
printf("virt2phys (0xe00000,D) -> %x\n", PpcVirt2phys(0xe00000,0));
printf("virt2phys (0xe01000,D) -> %x\n", PpcVirt2phys(0xe01000,0));
MachVtbl.VideoClearScreen = PpcVideoClearScreen;
MachVtbl.VideoSetDisplayMode = PpcVideoSetDisplayMode;
@@ -19,8 +19,8 @@
*/
#include <freeldr.h>
#include <of_call.h>
#include "mmu.h"
#define NDEBUG
#include <debug.h>
@@ -37,7 +37,7 @@ static PVOID KernelMemory = 0;
/* Converts a Relative Address read from the Kernel into a Physical Address */
ULONG RaToPa(ULONG p) {
return ofw_virt2phys((ULONG)(p + KernelMemory), 1);
return PpcVirt2phys((ULONG)(KernelMemory) + p, 0);
}
/* Converts a Phsyical Address Pointer into a Page Frame Number */
@@ -284,12 +284,6 @@ FrLdrMapKernel(FILE *KernelImage)
KernelBase = NtHeader->OptionalHeader.ImageBase;
FrLdrGetKernelBase();
printf("About to do RaToPa(%x)\n",
NtHeader->OptionalHeader.AddressOfEntryPoint);
/* Save Entrypoint */
KernelEntry = RaToPa(NtHeader->OptionalHeader.AddressOfEntryPoint);
printf("RaToPa -> %x\n", KernelEntry);
/* Save the Image Size */
ImageSize = NtHeader->OptionalHeader.SizeOfImage;
@@ -302,6 +296,13 @@ FrLdrMapKernel(FILE *KernelImage)
/* Allocate kernel memory */
KernelMemory = MmAllocateMemory(ImageSize);
/* Save Entrypoint */
KernelEntry = RaToPa(NtHeader->OptionalHeader.AddressOfEntryPoint);
printf("RaToPa(%x + %x) -> %x\n",
KernelMemory,
NtHeader->OptionalHeader.AddressOfEntryPoint,
KernelEntry);
/* Load the file image */
FsReadFile(KernelImage, ImageSize, NULL, KernelMemory);
@@ -0,0 +1,193 @@
#include <freeldr.h>
#include "mmu.h"
inline int GetMSR() {
register int res asm ("r3");
__asm__("mfmsr 3");
return res;
}
__asm__("\t.globl GetPhys\n"
"GetPhys:\t\n"
"mflr 0\n\t"
"stwu 0,-16(1)\n\t"
"mfmsr 5\n\t"
"xori 3,3,4\n\t" /* Undo effects of LE without swapping */
"andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
"mtmsr 6\n\t"
"lwz 3,0(3)\n\t" /* Get actual value at phys addr r3 */
"mtmsr 5\n\t"
"lwz 0,0(1)\n\t"
"addi 1,1,16\n\t"
"mtlr 0\n\t"
"blr"
);
inline int GetSR(int n) {
register int res asm ("r3");
switch( n ) {
case 0:
__asm__("mfsr 3,0");
break;
case 1:
__asm__("mfsr 3,1");
break;
case 2:
__asm__("mfsr 3,2");
break;
case 3:
__asm__("mfsr 3,3");
break;
case 4:
__asm__("mfsr 3,4");
break;
case 5:
__asm__("mfsr 3,5");
break;
case 6:
__asm__("mfsr 3,6");
break;
case 7:
__asm__("mfsr 3,7");
break;
case 8:
__asm__("mfsr 3,8");
break;
case 9:
__asm__("mfsr 3,9");
break;
case 10:
__asm__("mfsr 3,10");
break;
case 11:
__asm__("mfsr 3,11");
break;
case 12:
__asm__("mfsr 3,12");
break;
case 13:
__asm__("mfsr 3,13");
break;
case 14:
__asm__("mfsr 3,14");
break;
case 15:
__asm__("mfsr 3,15");
break;
}
return res;
}
inline void GetBat( int bat, int inst, int *batHi, int *batLo ) {
register int bh asm("r3"), bl asm("r4");
if( inst ) {
switch( bat ) {
case 0:
__asm__("mfibatu 3,0");
__asm__("mfibatl 4,0");
break;
case 1:
__asm__("mfibatu 3,1");
__asm__("mfibatl 4,1");
break;
case 2:
__asm__("mfibatu 3,2");
__asm__("mfibatl 4,2");
break;
case 3:
__asm__("mfibatu 3,3");
__asm__("mfibatl 4,3");
break;
}
} else {
switch( bat ) {
case 0:
__asm__("mfdbatu 3,0");
__asm__("mfdbatl 4,0");
break;
case 1:
__asm__("mfdbatu 3,1");
__asm__("mfdbatl 4,1");
break;
case 2:
__asm__("mfdbatu 3,2");
__asm__("mfdbatl 4,2");
break;
case 3:
__asm__("mfdbatu 3,3");
__asm__("mfdbatl 4,3");
break;
}
}
*batHi = bh;
*batLo = bl;
}
inline int GetSDR1() {
register int res asm("r3");
__asm__("mfsdr1 3");
return res;
}
inline int BatHit( int bath, int batl, int virt ) {
int mask = 0xfffe0000 & ~((batl & 0x3f) << 17);
return (batl & 0x40) && ((virt & mask) == (bath & mask));
}
inline int BatTranslate( int bath, int batl, int virt ) {
return (virt & 0x007fffff) | (batl & 0xfffe0000);
}
/* translate address */
int PpcVirt2phys( int virt, int inst ) {
int msr = GetMSR();
int txmask = inst ? 0x20 : 0x10;
int i, bath, batl, sr, sdr1, physbase, vahi, valo;
int npteg, hash, hashmask, ptehi, ptelo, ptegaddr;
int vsid, pteh, ptevsid, pteapi;
if( msr & txmask ) {
sr = GetSR( virt >> 28 );
vsid = sr & 0xfffffff;
vahi = vsid >> 4;
valo = (vsid << 28) | (virt & 0xfffffff);
if( sr & 0x80000000 ) {
return valo;
}
for( i = 0; i < 4; i++ ) {
GetBat( i, inst, &bath, &batl );
if( BatHit( bath, batl, virt ) ) {
return BatTranslate( bath, batl, virt );
}
}
sdr1 = GetSDR1();
physbase = sdr1 & ~0xffff;
hashmask = ((sdr1 & 0x1ff) << 10) | 0x3ff;
hash = (vsid & 0x7ffff) ^ ((valo >> 12) & 0xffff);
npteg = hashmask + 1;
for( pteh = 0; pteh < 0x80; pteh += 64, hash ^= 0x7ffff ) {
ptegaddr = ((hashmask & hash) * 64) + physbase;
for( i = 0; i < 8; i++ ) {
ptehi = GetPhys( ptegaddr + (i * 8) );
ptelo = GetPhys( ptegaddr + (i * 8) + 4 );
ptevsid = (ptehi >> 7) & 0xffffff;
pteapi = ptehi & 0x3f;
if( (ptehi & 64) != pteh ) continue;
if( ptevsid != (vsid & 0xffffff) ) continue;
if( pteapi != ((virt >> 22) & 0x3f) ) continue;
return (ptelo & 0xfffff000) | (virt & 0xfff);
}
}
return -1;
} else {
return virt;
}
}
@@ -0,0 +1,14 @@
#ifndef FREELDR_MMU_H
#define FREELDR_MMU_H
int GetMSR();
int GetPhys( int addr );
int GetSR(int n);
void GetBat( int bat, int inst, int *batHi, int *batLo );
int GetSDR1();
int BatHit( int bath, int batl, int virt );
int BatTranslate( int bath, int batl, int virt );
/* translate address */
int PpcVirt2phys( int virt, int inst );
#endif/*FREELDR_MMU_H*/
@@ -66,6 +66,7 @@
<compilerflag>-meabi</compilerflag>
<file>boot.s</file>
<file>ofw.c</file>
<file>mmu.c</file>
<file>mach.c</file>
<file>mboot.c</file>
</module>
+5 -1
View File
@@ -431,7 +431,11 @@ BOOLEAN FatSearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectorySi
//
if (DirEntry->FileName[0] == '\0')
{
return FALSE;
/* A workaround for something I see ... there are
* zero entries in the middle of the dir. This is
* probably a bug in the way the fat fs was made.
*/
continue; //return FALSE;
}
//
+1 -1
View File
@@ -1,7 +1,7 @@
#!/bin/sh -v
export PATH=$PATH:/usr/local/pkg/reactos-powerpc/bin
ld -EL -g -nostartfiles -nostdlib -N -Ttext=0x8000 -o freeldr.elf obj-ppc/boot/freeldr/freeldr/arch/powerpc/boot.o obj-ppc/boot/freeldr/freeldr/cache/blocklist.o obj-ppc/boot/freeldr/freeldr/cache/cache.o obj-ppc/boot/freeldr/freeldr/comm/rs232.o obj-ppc/boot/freeldr/freeldr/disk/disk.o obj-ppc/boot/freeldr/freeldr/disk/partition.o obj-ppc/boot/freeldr/freeldr/fs/ext2.o obj-ppc/boot/freeldr/freeldr/fs/fat.o obj-ppc/boot/freeldr/freeldr/fs/fs.o obj-ppc/boot/freeldr/freeldr/fs/fsrec.o obj-ppc/boot/freeldr/freeldr/fs/iso.o obj-ppc/boot/freeldr/freeldr/fs/ntfs.o obj-ppc/boot/freeldr/freeldr/inifile/ini_init.o obj-ppc/boot/freeldr/freeldr/inifile/inifile.o obj-ppc/boot/freeldr/freeldr/inifile/parse.o obj-ppc/boot/freeldr/freeldr/math/libgcc2.o obj-ppc/boot/freeldr/freeldr/mm/meminit.o obj-ppc/boot/freeldr/freeldr/mm/mm.o obj-ppc/boot/freeldr/freeldr/reactos/registry.o obj-ppc/boot/freeldr/freeldr/reactos/arcname.o obj-ppc/boot/freeldr/freeldr/reactos/binhive.o obj-ppc/boot/freeldr/freeldr/reactos/reactos.o obj-ppc/boot/freeldr/freeldr/rtl/list.o obj-ppc/boot/freeldr/freeldr/ui/gui.o obj-ppc/boot/freeldr/freeldr/ui/tui.o obj-ppc/boot/freeldr/freeldr/ui/tuimenu.o obj-ppc/boot/freeldr/freeldr/ui/ui.o obj-ppc/boot/freeldr/freeldr/video/bank.o obj-ppc/boot/freeldr/freeldr/video/fade.o obj-ppc/boot/freeldr/freeldr/video/palette.o obj-ppc/boot/freeldr/freeldr/video/pixel.o obj-ppc/boot/freeldr/freeldr/video/video.o obj-ppc/boot/freeldr/freeldr/freeldr.o obj-ppc/boot/freeldr/freeldr/debug.o obj-ppc/boot/freeldr/freeldr/version.o obj-ppc/boot/freeldr/freeldr/cmdline.o obj-ppc/boot/freeldr/freeldr/machine.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mach.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/ofw.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mboot.o obj-ppc/boot/freeldr/freeldr/bootmgr.o obj-ppc/boot/freeldr/freeldr/drivemap.o obj-ppc/boot/freeldr/freeldr/miscboot.o obj-ppc/boot/freeldr/freeldr/options.o obj-ppc/boot/freeldr/freeldr/linuxboot.o obj-ppc/boot/freeldr/freeldr/oslist.o obj-ppc/boot/freeldr/freeldr/custom.o obj-ppc/lib/rossym/rossym.a obj-ppc/lib/string/string.a obj-ppc/lib/rtl/rtl.a /usr/local/pkg/reactos-powerpc/lib/libgcc.a
ld -EL -g -nostartfiles -nostdlib -N -Ttext=0x8000 -o freeldr.elf obj-ppc/boot/freeldr/freeldr/arch/powerpc/boot.o obj-ppc/boot/freeldr/freeldr/cache/blocklist.o obj-ppc/boot/freeldr/freeldr/cache/cache.o obj-ppc/boot/freeldr/freeldr/comm/rs232.o obj-ppc/boot/freeldr/freeldr/disk/disk.o obj-ppc/boot/freeldr/freeldr/disk/partition.o obj-ppc/boot/freeldr/freeldr/fs/ext2.o obj-ppc/boot/freeldr/freeldr/fs/fat.o obj-ppc/boot/freeldr/freeldr/fs/fs.o obj-ppc/boot/freeldr/freeldr/fs/fsrec.o obj-ppc/boot/freeldr/freeldr/fs/iso.o obj-ppc/boot/freeldr/freeldr/fs/ntfs.o obj-ppc/boot/freeldr/freeldr/inifile/ini_init.o obj-ppc/boot/freeldr/freeldr/inifile/inifile.o obj-ppc/boot/freeldr/freeldr/inifile/parse.o obj-ppc/boot/freeldr/freeldr/math/libgcc2.o obj-ppc/boot/freeldr/freeldr/mm/meminit.o obj-ppc/boot/freeldr/freeldr/mm/mm.o obj-ppc/boot/freeldr/freeldr/reactos/registry.o obj-ppc/boot/freeldr/freeldr/reactos/arcname.o obj-ppc/boot/freeldr/freeldr/reactos/binhive.o obj-ppc/boot/freeldr/freeldr/reactos/reactos.o obj-ppc/boot/freeldr/freeldr/rtl/list.o obj-ppc/boot/freeldr/freeldr/ui/gui.o obj-ppc/boot/freeldr/freeldr/ui/tui.o obj-ppc/boot/freeldr/freeldr/ui/tuimenu.o obj-ppc/boot/freeldr/freeldr/ui/ui.o obj-ppc/boot/freeldr/freeldr/video/bank.o obj-ppc/boot/freeldr/freeldr/video/fade.o obj-ppc/boot/freeldr/freeldr/video/palette.o obj-ppc/boot/freeldr/freeldr/video/pixel.o obj-ppc/boot/freeldr/freeldr/video/video.o obj-ppc/boot/freeldr/freeldr/freeldr.o obj-ppc/boot/freeldr/freeldr/debug.o obj-ppc/boot/freeldr/freeldr/version.o obj-ppc/boot/freeldr/freeldr/cmdline.o obj-ppc/boot/freeldr/freeldr/machine.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mach.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/ofw.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mmu.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mboot.o obj-ppc/boot/freeldr/freeldr/bootmgr.o obj-ppc/boot/freeldr/freeldr/drivemap.o obj-ppc/boot/freeldr/freeldr/miscboot.o obj-ppc/boot/freeldr/freeldr/options.o obj-ppc/boot/freeldr/freeldr/linuxboot.o obj-ppc/boot/freeldr/freeldr/oslist.o obj-ppc/boot/freeldr/freeldr/custom.o obj-ppc/lib/rossym/rossym.a obj-ppc/lib/string/string.a obj-ppc/lib/rtl/rtl.a /usr/local/pkg/reactos-powerpc/lib/libgcc.a
objcopy -O binary freeldr.elf freeldr.tmp.le
output-ppc/tools/ppc-le2be freeldr.tmp.le freeldr.tmp
objcopy -I binary -B powerpc:common -O elf32-powerpc freeldr.tmp ofwldr.payload