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,
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 );
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;
}
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; }
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;
}
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,
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 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",
MachVtbl.ConsPutChar = PpcPutChar;
MachVtbl.ConsKbHit = PpcConsKbHit;
MachVtbl.ConsGetCh = PpcConsGetCh;
-
- printf("chosen_package = %x\n", chosen_package);
+
+ printf( "stdin_handle is %x\n", stdin_handle );
MachVtbl.VideoClearScreen = PpcVideoClearScreen;
MachVtbl.VideoSetDisplayMode = PpcVideoSetDisplayMode;
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;
MachVtbl.HwDetect = PpcHwDetect;
printf( "FreeLDR version [%s]\n", GetFreeLoaderVersionString() );
- BootMain("freeldr-ppc");
+
+ len = ofw_getprop(chosen_package, "bootargs",
+ CmdLine, sizeof(CmdLine));
+
+ if( len < 0 ) len = 0;
+ CmdLine[len] = 0;
+
+ BootMain( CmdLine );
}
void MachInit(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 );
+ 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;
+ }
+ }
- printf( "FreeLDR starting\n" );
-}
+ 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;
+ }
+ }
-void FrLdrSetupPageDirectory() {
+ printf( "FreeLDR starting (boot partition: %s)\n", BootPart );
}
+/* Compatibility functions that don't do much */
void beep() {
}
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();
+}