PowerPC support drop in freeldr, from my branch.
Some stuff not working, but disk IO now implemented.
Get boot partition either from boot-device env var or from cmd line.
Needs some work to build with the new tools.
Modified: trunk/reactos/boot/freeldr/bootsect/ofwboot.s
Modified: trunk/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s
Modified: trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c
Added: trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c
_____
Modified: trunk/reactos/boot/freeldr/bootsect/ofwboot.s
--- trunk/reactos/boot/freeldr/bootsect/ofwboot.s 2005-12-04
12:07:08 UTC (rev 19856)
+++ trunk/reactos/boot/freeldr/bootsect/ofwboot.s 2005-12-04
12:13:48 UTC (rev 19857)
@@ -61,9 +61,10 @@
li %r9,0x12 /* BATL(0, BAT_M, BAT_PP_RW) */
mtibatl 0,%r9
mtdbatl 0,%r9
- li %r9,0x1ffe /* BATU(0, BAT_BL_256M, BAT_Vs) */
- mtibatu 0,%r9
- mtdbatu 0,%r9
+ li %r10,0x1ffe /* BATU(0, BAT_BL_256M, BAT_Vs) */
+ mtibatu 0,%r10
+ mtdbatu 0,%r10
+
isync
li %r8,0x3030
@@ -93,6 +94,8 @@
bl ofw_print_eol
+ bl setup_exc
+
/* Zero CTR */
mtcr %r31
@@ -630,6 +633,53 @@
/* Return */
blr
+ofw_open:
+ /* Reserve stack space ...
+ * 20 bytes for the ofw call,
+ * r8, r9, and lr */
+ subi %r1,%r1,32
+
+ /* Store r8, r9, lr */
+ stw %r8,20(%r1)
+ stw %r9,24(%r1)
+ mflr %r8
+ stw %r8,28(%r1)
+
+ /* Get open name */
+ lis %r8,0xe00000@ha
+ addi %r9,%r8,ofw_open_name - _start
+ stw %r9,0(%r1)
+
+ /* 1 Argument and 1 return */
+ li %r9,1
+ stw %r9,4(%r1)
+ stw %r9,8(%r1)
+
+ stw %r3,12(%r1)
+
+ /* Load up the call address */
+ lwz %r9,ofw_call_addr - _start(%r8)
+ mtlr %r9
+
+ /* Set argument */
+ mr %r3,%r1
+
+ /* Fire */
+ blrl
+
+ lwz %r3,16(%r1)
+
+ /* Restore registers */
+ lwz %r8,28(%r1)
+ mtlr %r8
+ lwz %r9,24(%r1)
+ lwz %r8,20(%r1)
+
+ addi %r1,%r1,32
+
+ /* Return */
+ blr
+
ofw_getprop_hook:
/* Reserve stack space:
* 32 bytes for the ofw call
@@ -889,7 +939,224 @@
/* Fire */
blrl
/* No return from exit */
+
+ofw_child:
+ /* Reserve stack space ...
+ * 20 bytes for the ofw call,
+ * r8, r9, and lr */
+ subi %r1,%r1,32
+
+ /* Store r8, r9, lr */
+ stw %r8,20(%r1)
+ stw %r9,24(%r1)
+ mflr %r8
+ stw %r8,28(%r1)
+
+ /* Get child name */
+ lis %r8,0xe00000@ha
+ addi %r9,%r8,ofw_child_name - _start
+ stw %r9,0(%r1)
+
+ /* 1 Argument and 1 return */
+ li %r9,1
+ stw %r9,4(%r1)
+ stw %r9,8(%r1)
+
+ stw %r3,12(%r1)
+
+ /* Load up the call address */
+ lwz %r9,ofw_call_addr - _start(%r8)
+ mtlr %r9
+
+ /* Set argument */
+ mr %r3,%r1
+
+ /* Fire */
+ blrl
+
+ lwz %r3,16(%r1)
+
+ /* Restore registers */
+ lwz %r8,28(%r1)
+ mtlr %r8
+ lwz %r9,24(%r1)
+ lwz %r8,20(%r1)
+
+ addi %r1,%r1,32
+
+ /* Return */
+ blr
+
+ofw_peer:
+ /* Reserve stack space ...
+ * 20 bytes for the ofw call,
+ * r8, r9, and lr */
+ subi %r1,%r1,32
+
+ /* Store r8, r9, lr */
+ stw %r8,20(%r1)
+ stw %r9,24(%r1)
+ mflr %r8
+ stw %r8,28(%r1)
+
+ /* Get peer name */
+ lis %r8,0xe00000@ha
+ addi %r9,%r8,ofw_peer_name - _start
+ stw %r9,0(%r1)
+
+ /* 1 Argument and 1 return */
+ li %r9,1
+ stw %r9,4(%r1)
+ stw %r9,8(%r1)
+
+ stw %r3,12(%r1)
+
+ /* Load up the call address */
+ lwz %r9,ofw_call_addr - _start(%r8)
+ mtlr %r9
+
+ /* Set argument */
+ mr %r3,%r1
+
+ /* Fire */
+ blrl
+
+ lwz %r3,16(%r1)
+
+ /* Restore registers */
+ lwz %r8,28(%r1)
+ mtlr %r8
+ lwz %r9,24(%r1)
+ lwz %r8,20(%r1)
+
+ addi %r1,%r1,32
+
+ /* Return */
+ blr
+
+ofw_seek:
+ /* Reserve stack space ...
+ * 20 bytes for the ofw call,
+ * r8, r9, and lr */
+ subi %r1,%r1,32
+
+ /* Store r8, r9, lr */
+ stw %r8,20(%r1)
+ stw %r9,24(%r1)
+ mflr %r8
+ stw %r8,28(%r1)
+
+ /* Get peer name */
+ lis %r8,0xe00000@ha
+ addi %r9,%r8,ofw_seek_name - _start
+ stw %r9,0(%r1)
+
+ /* 3 Arguments and 1 return */
+ li %r9,3
+ stw %r9,4(%r1)
+ li %r9,1
+ stw %r9,8(%r1)
+
+ stw %r3,12(%r1)
+ stw %r4,16(%r1)
+ stw %r5,20(%r1)
+
+ /* Load up the call address */
+ lwz %r9,ofw_call_addr - _start(%r8)
+ mtlr %r9
+
+ /* Set argument */
+ mr %r3,%r1
+
+ /* Fire */
+ blrl
+
+ lwz %r3,16(%r1)
+
+ /* Restore registers */
+ lwz %r8,28(%r1)
+ mtlr %r8
+ lwz %r9,24(%r1)
+ lwz %r8,20(%r1)
+
+ addi %r1,%r1,32
+
+ /* Return */
+ blr
+
+
+setup_exc:
+ subi %r1,%r1,32
+
+ stw %r3,0(%r1)
+ mflr %r3
+ stw %r3,4(%r1)
+ stw %r8,8(%r1)
+ stw %r9,12(%r1)
+ stw %r10,16(%r1)
+ stw %r12,20(%r1)
+
+ lis %r8,0xe00000@ha
+ xor %r12,%r12,%r12
+ addi %r12,%r12,0x300
+ addi %r9,%r8,dsi_exc - _start
+ addi %r10,%r8,dsi_end - _start
+
+copy_loop:
+ cmp 0,0,%r9,%r10
+ beq ret_setup_exc
+
+ mr %r3,%r12
+ bl ofw_print_number
+ bl ofw_print_space
+
+ lwz %r3,0(%r9)
+ stw %r3,0(%r12)
+
+ bl ofw_print_number
+ bl ofw_print_eol
+
+ addi %r12,%r12,4
+ addi %r9,%r9,4
+ b copy_loop
+
+ret_setup_exc:
+ mfmsr %r12
+ andi. %r12,%r12,0xffbf
+ mtmsr %r12
+
+ lwz %r12,20(%r1)
+ lwz %r10,16(%r1)
+ lwz %r9,12(%r1)
+ lwz %r8,8(%r1)
+
+ lwz %r3,4(%r1)
+ mtlr %r3
+ lwz %r3,0(%r1)
+
+ blr
+
+dsi_exc:
+ subi %r1,%r1,16
+
+ stw %r0,0(%r1)
+ stw %r3,4(%r1)
+
+ mfsrr0 %r3
+ addi %r3,%r3,4
+ mtsrr0 %r3
+
+ /* mfsrr1 %r3 */
+ /* ori %r3,%r3,2 */
+ /* mtsrr1 %r3 */
+ lwz %r3,4(%r1)
+ lwz %r0,0(%r1)
+
+ addi %r1,%r1,16
+ rfi
+dsi_end:
+
.org 0x1000
freeldr_banner:
.ascii "ReactOS OpenFirmware Boot Program\r\n\0"
@@ -899,7 +1166,6 @@
freeldr_reg_init:
.ascii "r\0"
-
freeldr_reg_lr:
.ascii "lr \0"
freeldr_reg_cr:
@@ -933,6 +1199,18 @@
ofw_exit_name:
.ascii "exit\0"
+ofw_open_name:
+ .ascii "open\0"
+
+ofw_child_name:
+ .ascii "child\0"
+
+ofw_peer_name:
+ .ascii "peer\0"
+
+ofw_seek_name:
+ .ascii "seek\0"
+
ofw_chosen_name:
.ascii "/chosen\0"
@@ -954,6 +1232,10 @@
.long ofw_print_regs
.long ofw_print_string
.long ofw_print_number
+ .long ofw_open
+ .long ofw_child
+ .long ofw_peer
+ .long ofw_seek
.org 0x2000
stack:
_____
Modified: trunk/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s
--- trunk/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s
2005-12-04 12:07:08 UTC (rev 19856)
+++ trunk/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s
2005-12-04 12:13:48 UTC (rev 19857)
@@ -1,3 +1,3 @@
.extern PpcInit
_start:
- b PpcInit
+ b PpcInit+4
_____
Modified: trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c
--- trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c
2005-12-04 12:07:08 UTC (rev 19856)
+++ trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c
2005-12-04 12:13:48 UTC (rev 19857)
@@ -22,20 +22,18 @@
extern void BootMain( char * );
extern char *GetFreeLoaderVersionString();
-ULONG BootPartition = 0;
-ULONG BootDrive = 0;
-
of_proxy ofproxy;
void *PageDirectoryStart, *PageDirectoryEnd;
-static int chosen_package, stdin_handle;
+static int chosen_package, stdin_handle, part_handle = -1;
BOOLEAN AcpiPresent = FALSE;
-char BootPath[0x100];
+char BootPath[0x100] = { 0 }, BootPart[0x100] = { 0 }, CmdLine[0x100] =
{ 0 };
+jmp_buf jmp;
-void le_swap( const void *start_addr_v,
- const void *end_addr_v,
+void le_swap( const void *start_addr_v,
+ const void *end_addr_v,
const void *target_addr_v ) {
- long *start_addr = (long *)ROUND_DOWN((long)start_addr_v,8),
- *end_addr = (long *)ROUND_UP((long)end_addr_v,8),
+ long *start_addr = (long *)ROUND_DOWN((long)start_addr_v,8),
+ *end_addr = (long *)ROUND_UP((long)end_addr_v,8),
*target_addr = (long *)ROUND_DOWN((long)target_addr_v,8);
long tmp;
while( start_addr <= end_addr ) {
@@ -68,6 +66,7 @@
return ret;
}
+/* Since this is from external storage, it doesn't need swapping */
int ofw_write( int handle, const char *data, int len ) {
int ret;
le_swap( data, data + len, data );
@@ -77,12 +76,15 @@
return ret;
}
+/* Since this is from external storage, it doesn't need swapping */
int ofw_read( int handle, const char *data, int len ) {
int ret;
+
le_swap( data, data + len, data );
ret = ofproxy
( 12, (void *)handle, (char *)data, (void *)len, NULL );
le_swap( data, data + len, data );
+
return ret;
}
@@ -105,14 +107,75 @@
ofproxy( 28, (void *)num, NULL, NULL, NULL );
}
+int ofw_open( const char *name ) {
+ int ret, len;
+
+ len = strlen(name);
+ le_swap( name, name + len, name );
+ ret = ofproxy( 32, (char *)name, NULL, NULL, NULL );
+ le_swap( name, name + len, name );
+ return ret;
+}
+
+int ofw_child( int package ) {
+ return ofproxy( 36, (void *)package, NULL, NULL, NULL );
+}
+
+int ofw_peer( int package ) {
+ return ofproxy( 40, (void *)package, NULL, NULL, NULL );
+}
+
+int ofw_seek( int handle, long long location ) {
+ return ofproxy( 44, (void *)handle, (void *)(int)(location >> 32),
(void *)(int)location, NULL );
+}
+
void PpcPutChar( int ch ) {
char buf[3];
- if( ch == 0x0a ) { buf[0] = 0x0d; buf[1] = 0x0a; }
+ if( ch == 0x0a ) { buf[0] = 0x0d; buf[1] = 0x0a; }
else { buf[0] = ch; buf[1] = 0; }
buf[2] = 0;
ofw_print_string( buf );
}
+int PpcFindDevice( int depth, int parent, char *devname, int *nth ) {
+ static char buf[256];
+ int next = 0;
+ int gotname = 0;
+ int match = 0;
+ int i;
+
+ next = ofw_child( parent );
+
+ //printf( "next = %x\n", next );
+
+ gotname = ofw_getprop(parent, "name", buf, 256);
+
+ //printf( "gotname = %d\n", gotname );
+
+ match = !strncmp(buf, devname, strlen(devname));
+
+ if( !nth && match ) return parent;
+ else if( match ) *nth--;
+
+ for( i = 0; i < depth; i++ ) PpcPutChar( ' ' );
+
+ if( depth == 1 ) {
+ if( gotname > 0 ) {
+ printf( "%c Name: %s\n", match ? '*' : ' ', buf );
+ } else {
+ printf( "- No name attribute for %x\n", parent );
+ }
+ }
+
+ while( !match && next ) {
+ i = PpcFindDevice( depth+1, next, devname, nth );
+ if( i ) return i;
+ next = ofw_peer( next );
+ }
+
+ return 0;
+}
+
BOOL PpcConsKbHit() {
return TRUE;
}
@@ -167,12 +230,12 @@
return FALSE;
}
-VOID PpcVideoSetPaletteColor( UCHAR Color,
+VOID PpcVideoSetPaletteColor( UCHAR Color,
UCHAR Red, UCHAR Green, UCHAR Blue ) {
printf( "SetPaletteColor(%x,%x,%x,%x)\n", Color, Red, Green, Blue
);
}
-VOID PpcVideoGetPaletteColor( UCHAR Color,
+VOID PpcVideoGetPaletteColor( UCHAR Color,
UCHAR *Red, UCHAR *Green, UCHAR *Blue ) {
printf( "GetPaletteColor(%x)\n", Color);
}
@@ -198,16 +261,74 @@
BiosMemoryMap[0].BaseAddress = 0;
BiosMemoryMap[0].Length = 32 * 1024 * 1024; /* Assume 32 meg for
now */
- printf( "Returning memory map (%dk total)\n",
+ printf( "Returning memory map (%dk total)\n",
(int)BiosMemoryMap[0].Length / 1024 );
return 1;
}
+/* Strategy:
+ *
+ * For now, it'll be easy enough to use the boot command line as our
boot path.
+ * Treat it as the path of a disk partition. We might even be able to
get
+ * away with grabbing a partition image by tftp in this scenario.
+ */
+
+BOOL PpcDiskGetBootVolume( PULONG DriveNumber, PULONGLONG StartSector,
PULONGLONG SectorCount, int *FsType ) {
+ *DriveNumber = 0;
+ *StartSector = 0;
+ *SectorCount = 0;
+ *FsType = FS_FAT;
+ return TRUE;
+}
+
+BOOL PpcDiskGetSystemVolume( char *SystemPath,
+ char *RemainingPath,
+ PULONG Device,
+ PULONG DriveNumber,
+ PULONGLONG StartSector,
+ PULONGLONG SectorCount,
+ int *FsType ) {
+ return FALSE;
+}
+
+BOOL PpcDiskGetBootPath( char *OutBootPath, unsigned Size ) {
+ strncpy( OutBootPath, BootPath, Size );
+ return TRUE;
+}
+
+VOID PpcDiskGetBootDevice( PULONG BootDevice ) {
+ BootDevice[0] = BootDevice[1] = 0;
+}
+
+BOOL PpcDiskBootingFromFloppy(VOID) {
+ return FALSE;
+}
+
BOOL PpcDiskReadLogicalSectors( ULONG DriveNumber, ULONGLONG
SectorNumber,
ULONG SectorCount, PVOID Buffer ) {
- printf("DiskReadLogicalSectors\n");
- return FALSE;
+ int rlen = 0;
+
+ if( part_handle == -1 ) {
+ part_handle = ofw_open( BootPart );
+
+ if( part_handle == -1 ) {
+ printf("Could not open any disk devices we know about\n");
+ return FALSE;
+ }
+ }
+
+ if( part_handle == -1 ) {
+ printf("Got partition handle %x\n", part_handle);
+ return FALSE;
+ }
+
+ if( ofw_seek( part_handle, SectorNumber * 512 ) ) {
+ printf("Seek to %x failed\n", SectorNumber * 512);
+ return FALSE;
+ }
+ rlen = ofw_read( part_handle, Buffer, SectorCount * 512 );
+ return rlen > 0;
}
BOOL PpcDiskGetPartitionEntry( ULONG DriveNumber, ULONG
PartitionNumber,
@@ -218,24 +339,32 @@
BOOL PpcDiskGetDriveGeometry( ULONG DriveNumber, PGEOMETRY
DriveGeometry ) {
printf("GetGeometry(%d)\n", DriveNumber);
- return FALSE;
+ DriveGeometry->BytesPerSector = 512;
+ DriveGeometry->Heads = 16;
+ DriveGeometry->Sectors = 63;
+ return TRUE;
}
ULONG PpcDiskGetCacheableBlockCount( ULONG DriveNumber ) {
printf("GetCacheableBlockCount\n");
- return 0;
+ return 1;
}
-VOID PpcRTCGetCurrentDateTime( PULONG Hear, PULONG Month, PULONG Day,
+VOID PpcRTCGetCurrentDateTime( PULONG Hear, PULONG Month, PULONG Day,
PULONG Hour, PULONG Minute, PULONG
Second ) {
printf("RTCGeturrentDateTime\n");
}
VOID PpcHwDetect() {
+ printf("PpcHwDetect\n");
}
+typedef unsigned int uint32_t;
+
void PpcInit( of_proxy the_ofproxy ) {
+ int len;
ofproxy = the_ofproxy;
+
chosen_package = ofw_finddevice( "/chosen" );
ofw_getprop( chosen_package, "stdin",
@@ -246,9 +375,9 @@
MachVtbl.ConsPutChar = PpcPutChar;
MachVtbl.ConsKbHit = PpcConsKbHit;
MachVtbl.ConsGetCh = PpcConsGetCh;
+
+ printf( "stdin_handle is %x\n", stdin_handle );
- printf("chosen_package = %x\n", chosen_package);
-
MachVtbl.VideoClearScreen = PpcVideoClearScreen;
MachVtbl.VideoSetDisplayMode = PpcVideoSetDisplayMode;
MachVtbl.VideoGetDisplaySize = PpcVideoGetDisplaySize;
@@ -256,7 +385,7 @@
MachVtbl.VideoSetTextCursorPosition =
PpcVideoSetTextCursorPosition;
MachVtbl.VideoHideShowTextCursor = PpcVideoHideShowTextCursor;
MachVtbl.VideoPutChar = PpcVideoPutChar;
- MachVtbl.VideoCopyOffScreenBufferToVRAM =
+ MachVtbl.VideoCopyOffScreenBufferToVRAM =
PpcVideoCopyOffScreenBufferToVRAM;
MachVtbl.VideoIsPaletteFixed = PpcVideoIsPaletteFixed;
MachVtbl.VideoSetPaletteColor = PpcVideoSetPaletteColor;
@@ -266,6 +395,11 @@
MachVtbl.GetMemoryMap = PpcGetMemoryMap;
+ MachVtbl.DiskGetBootVolume = PpcDiskGetBootVolume;
+ MachVtbl.DiskGetSystemVolume = PpcDiskGetSystemVolume;
+ MachVtbl.DiskGetBootPath = PpcDiskGetBootPath;
+ MachVtbl.DiskGetBootDevice = PpcDiskGetBootDevice;
+ MachVtbl.DiskBootingFromFloppy = PpcDiskBootingFromFloppy;
MachVtbl.DiskReadLogicalSectors = PpcDiskReadLogicalSectors;
MachVtbl.DiskGetPartitionEntry = PpcDiskGetPartitionEntry;
MachVtbl.DiskGetDriveGeometry = PpcDiskGetDriveGeometry;
@@ -276,24 +410,57 @@
MachVtbl.HwDetect = PpcHwDetect;
printf( "FreeLDR version [%s]\n", GetFreeLoaderVersionString() );
- BootMain("freeldr-ppc");
-}
-void MachInit(const char *CmdLine) {
- int len;
- printf( "Determining boot device:\n" );
- len = ofw_getprop(chosen_package, "bootpath",
- BootPath, sizeof(BootPath));
- printf( "Got %d bytes of path\n", len );
- BootPath[len] = 0;
- printf( "Boot Path: %s\n", BootPath );
+ len = ofw_getprop(chosen_package, "bootargs",
+ CmdLine, sizeof(CmdLine));
- printf( "FreeLDR starting\n" );
+ if( len < 0 ) len = 0;
+ CmdLine[len] = 0;
+
+ BootMain( CmdLine );
}
-void FrLdrSetupPageDirectory() {
+void MachInit(char *CmdLine) {
+ int len, i;
+ char *sep;
+
+ BootPart[0] = 0;
+ BootPath[0] = 0;
+
+ printf( "Determining boot device: [%s]\n", CmdLine );
+
+ printf( "Boot Args: %s\n", CmdLine );
+ sep = NULL;
+ for( i = 0; i < strlen(CmdLine); i++ ) {
+ if( strncmp(CmdLine + i, "boot=", 5) == 0) {
+ strcpy(BootPart, CmdLine + i + 5);
+ sep = strchr(BootPart, ' ');
+ if( sep )
+ *sep = 0;
+ break;
+ }
+ }
+
+ if( strlen(BootPart) == 0 ) {
+ len = ofw_getprop(chosen_package, "bootpath",
+ BootPath, sizeof(BootPath));
+
+ if( len < 0 ) len = 0;
+ BootPath[len] = 0;
+ printf( "Boot Path: %s\n", BootPath );
+
+ sep = strrchr(BootPath, ',');
+
+ strcpy(BootPart, BootPath);
+ if( sep ) {
+ BootPart[sep - BootPath] = 0;
+ }
+ }
+
+ printf( "FreeLDR starting (boot partition: %s)\n", BootPart );
}
+/* Compatibility functions that don't do much */
void beep() {
}
@@ -303,3 +470,18 @@
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value) {
}
+
+void DiskStopFloppyMotor() {
+}
+
+void BootOldLinuxKernel( unsigned long size ) {
+ ofw_exit();
+}
+
+void BootNewLinuxKernel() {
+ ofw_exit();
+}
+
+void ChainLoadBiosBootSectorCode() {
+ ofw_exit();
+}
_____
Added: trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c
--- trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c
2005-12-04 12:07:08 UTC (rev 19856)
+++ trunk/reactos/boot/freeldr/freeldr/arch/powerpc/mboot.c
2005-12-04 12:13:48 UTC (rev 19857)
@@ -0,0 +1,661 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: Freeloader
+ * FILE: boot/freeldr/freeldr/multiboot.c
+ * PURPOSE: ReactOS Loader
+ * PROGRAMMERS: Alex Ionescu (alex(a)relsoft.net)
+ * Hartmut Birr - SMP/PAE Code
+ */
+
+#include <freeldr.h>
+#include <internal/powerpc/ke.h>
+
+#define NDEBUG
+#include <debug.h>
+
+/* Base Addres of Kernel in Physical Memory */
+#define KERNEL_BASE_PHYS 0x200000
+
+/* Bits to shift to convert a Virtual Address into an Offset in the
Page Table */
+#define PFN_SHIFT 12
+
+/* Bits to shift to convert a Virtual Address into an Offset in the
Page Directory */
+#define PDE_SHIFT 20
+#define PDE_SHIFT_PAE 18
+
+
+/* Converts a Relative Address read from the Kernel into a Physical
Address */
+#define RaToPa(p) \
+ (ULONG_PTR)((ULONG_PTR)p + KERNEL_BASE_PHYS)
+
+/* Converts a Phsyical Address Pointer into a Page Frame Number */
+#define PaPtrToPfn(p) \
+ (((ULONG_PTR)&p) >> PFN_SHIFT)
+
+/* Converts a Phsyical Address into a Page Frame Number */
+#define PaToPfn(p) \
+ ((p) >> PFN_SHIFT)
+
+#define STARTUP_BASE 0xF0000000
+#define HYPERSPACE_BASE 0xF0800000
+#define APIC_BASE 0xFEC00000
+#define KPCR_BASE 0xFF000000
+
+#define LowMemPageTableIndex 0
+#define StartupPageTableIndex (STARTUP_BASE >> 20) /
sizeof(HARDWARE_PTE_X86)
+#define HyperspacePageTableIndex (HYPERSPACE_BASE >> 20) /
sizeof(HARDWARE_PTE_X86)
+#define KpcrPageTableIndex (KPCR_BASE >> 20) /
sizeof(HARDWARE_PTE_X86)
+#define ApicPageTableIndex (APIC_BASE >> 20) /
sizeof(HARDWARE_PTE_X86)
+
+#define LowMemPageTableIndexPae 0
+#define StartupPageTableIndexPae (STARTUP_BASE >> 21)
+#define HyperspacePageTableIndexPae (HYPERSPACE_BASE >> 21)
+#define KpcrPageTableIndexPae (KPCR_BASE >> 21)
+#define ApicPageTableIndexPae (APIC_BASE >> 21)
+
+
+#define KernelEntryPoint (KernelEntry - KERNEL_BASE_PHYS) +
KernelBase
+
+/* Load Address of Next Module */
+ULONG_PTR NextModuleBase = 0;
+
+/* Currently Opened Module */
+PFRLDR_MODULE CurrentModule = NULL;
+
+/* Unrelocated Kernel Base in Virtual Memory */
+ULONG_PTR KernelBase;
+
+/* Wether PAE is to be used or not */
+BOOLEAN PaeModeEnabled;
+
+/* Kernel Entrypoint in Physical Memory */
+ULONG_PTR KernelEntry;
+
+/* FUNCTIONS
*****************************************************************/
+
+/*++
+ * FrLdrStartup
+ * INTERNAL
+ *
+ * Prepares the system for loading the Kernel.
+ *
+ * Params:
+ * Magic - Multiboot Magic
+ *
+ * Returns:
+ * None.
+ *
+ * Remarks:
+ * None.
+ *
+ *--*/
+VOID
+STDCALL
+FrLdrStartup(ULONG Magic)
+{
+#if 0
+ /* Disable Interrupts */
+ KeArchDisableInterrupts();
+
+ /* Re-initalize EFLAGS */
+ KeArchEraseFlags();
+
+ /* Initialize the page directory */
+ FrLdrSetupPageDirectory();
+#endif
+}
+
+/*++
+ * FrLdrGetKernelBase
+ * INTERNAL
+ *
+ * Gets the Kernel Base to use.
+ *
+ * Params:
+ *
+ * Returns:
+ * None.
+ *
+ * Remarks:
+ * Sets both the FreeLdr internal variable as well as the one which
+ * will be used by the Kernel.
+ *
+ *--*/
+VOID
+FASTCALL
+FrLdrGetKernelBase(VOID)
+{
+ PCHAR p;
+
+ /* Read Command Line */
+ p = (PCHAR)LoaderBlock.CommandLine;
+ while ((p = strchr(p, '/')) != NULL) {
+
+ /* Find "/3GB" */
+ if (!strnicmp(p + 1, "3GB", 3)) {
+
+ /* Make sure there's nothing following it */
+ if (p[4] == ' ' || p[4] == 0) {
+
+ /* Use 3GB */
+ KernelBase = 0xC0000000;
+ }
+ }
+
+ p++;
+ }
+
+ /* Set KernelBase */
+ LoaderBlock.KernelBase = KernelBase;
+}
+
+/*++
+ * FrLdrSetupPageDirectory
+ * INTERNAL
+ *
+ * Sets up the ReactOS Startup Page Directory.
+ *
+ * Params:
+ * None.
+ *
+ * Returns:
+ * None.
+ *
+ * Remarks:
+ * We are setting PDEs, but using the equvivalent (for our purpose)
PTE structure.
+ * As such, please note that PageFrameNumber == PageEntryNumber.
+ *
+ *--*/
+VOID
+FASTCALL
+FrLdrSetupPageDirectory(VOID)
+{
+#if 0
+ PPAGE_DIRECTORY_X86 PageDir;
+ PPAGE_DIRECTORY_TABLE_X64 PageDirTablePae;
+ PPAGE_DIRECTORY_X64 PageDirPae;
+ ULONG KernelPageTableIndex;
+ ULONG i;
+
+ if (PaeModeEnabled) {
+
+ /* Get the Kernel Table Index */
+ KernelPageTableIndex = (KernelBase >> 21);
+
+ /* Get the Startup Page Directory Table */
+ PageDirTablePae =
(PPAGE_DIRECTORY_TABLE_X64)&startup_pagedirectorytable_pae;
+
+ /* Get the Startup Page Directory */
+ PageDirPae = (PPAGE_DIRECTORY_X64)&startup_pagedirectory_pae;
+
+ /* Set the Startup page directory table */
+ for (i = 0; i < 4; i++)
+ {
+ PageDirTablePae->Pde[i].Valid = 1;
+ PageDirTablePae->Pde[i].PageFrameNumber =
PaPtrToPfn(startup_pagedirectory_pae) + i;
+ }
+
+ /* Set up the Low Memory PDE */
+ for (i = 0; i < 2; i++)
+ {
+ PageDirPae->Pde[LowMemPageTableIndexPae + i].Valid = 1;
+ PageDirPae->Pde[LowMemPageTableIndexPae + i].Write = 1;
+ PageDirPae->Pde[LowMemPageTableIndexPae +
i].PageFrameNumber = PaPtrToPfn(lowmem_pagetable_pae) + i;
+ }
+
+ /* Set up the Kernel PDEs */
+ for (i = 0; i < 3; i++)
+ {
+ PageDirPae->Pde[KernelPageTableIndex + i].Valid = 1;
+ PageDirPae->Pde[KernelPageTableIndex + i].Write = 1;
+ PageDirPae->Pde[KernelPageTableIndex + i].PageFrameNumber =
PaPtrToPfn(kernel_pagetable_pae) + i;
+ }
+
+ /* Set up the Startup PDE */
+ for (i = 0; i < 4; i++)
+ {
+ PageDirPae->Pde[StartupPageTableIndexPae + i].Valid = 1;
+ PageDirPae->Pde[StartupPageTableIndexPae + i].Write = 1;
+ PageDirPae->Pde[StartupPageTableIndexPae +
i].PageFrameNumber = PaPtrToPfn(startup_pagedirectory_pae) + i;
+ }
+
+ /* Set up the Hyperspace PDE */
+ for (i = 0; i < 2; i++)
+ {
+ PageDirPae->Pde[HyperspacePageTableIndexPae + i].Valid = 1;
+ PageDirPae->Pde[HyperspacePageTableIndexPae + i].Write = 1;
+ PageDirPae->Pde[HyperspacePageTableIndexPae +
i].PageFrameNumber = PaPtrToPfn(hyperspace_pagetable_pae) + i;
+ }
+
+ /* Set up the Apic PDE */
+ for (i = 0; i < 2; i++)
+ {
+ PageDirPae->Pde[ApicPageTableIndexPae + i].Valid = 1;
+ PageDirPae->Pde[ApicPageTableIndexPae + i].Write = 1;
+ PageDirPae->Pde[ApicPageTableIndexPae + i].PageFrameNumber
= PaPtrToPfn(apic_pagetable_pae) + i;
+ }
+
+ /* Set up the KPCR PDE */
+ PageDirPae->Pde[KpcrPageTableIndexPae].Valid = 1;
+ PageDirPae->Pde[KpcrPageTableIndexPae].Write = 1;
+ PageDirPae->Pde[KpcrPageTableIndexPae].PageFrameNumber =
PaPtrToPfn(kpcr_pagetable_pae);
+
+ /* Set up Low Memory PTEs */
+ PageDirPae = (PPAGE_DIRECTORY_X64)&lowmem_pagetable_pae;
+ for (i=0; i<1024; i++) {
+
+ PageDirPae->Pde[i].Valid = 1;
+ PageDirPae->Pde[i].Write = 1;
+ PageDirPae->Pde[i].Owner = 1;
+ PageDirPae->Pde[i].PageFrameNumber = i;
+ }
+
+ /* Set up Kernel PTEs */
+ PageDirPae = (PPAGE_DIRECTORY_X64)&kernel_pagetable_pae;
+ for (i=0; i<1536; i++) {
+
+ PageDirPae->Pde[i].Valid = 1;
+ PageDirPae->Pde[i].Write = 1;
[truncated at 1000 lines; 403 more skipped]