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@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]