#include "freeldr.h"
#include "machine.h"
#include "of.h"
+#include "mmu.h"
-extern void BootMain( char * );
-extern char *GetFreeLoaderVersionString();
+#define TOTAL_HEAP_NEEDED (32 * 1024 * 1024) /* 32 megs */
+
+extern void BootMain( LPSTR CmdLine );
+extern PCHAR GetFreeLoaderVersionString();
+extern ULONG CacheSizeLimit;
of_proxy ofproxy;
-void *PageDirectoryStart, *PageDirectoryEnd;
+void *PageDirectoryStart, *PageDirectoryEnd, *mem_base = 0;
static int chosen_package, stdin_handle, part_handle = -1;
BOOLEAN AcpiPresent = FALSE;
char BootPath[0x100] = { 0 }, BootPart[0x100] = { 0 }, CmdLine[0x100] = { 0 };
jmp_buf jmp;
+volatile char *video_mem = 0;
-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),
+void le_swap( void *start_addr_v,
+ void *end_addr_v,
+ 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),
*target_addr = (long *)ROUND_DOWN((long)target_addr_v,8);
long tmp;
}
}
-int ofw_finddevice( const char *name ) {
- int ret, len;
-
- len = strlen(name);
- le_swap( name, name + len, name );
- ret = ofproxy( 0, (char *)name, NULL, NULL, NULL );
- le_swap( name, name + len, name );
- return ret;
-}
-
-int ofw_getprop( int package, const char *name, void *buffer, int buflen ) {
- int ret, len = strlen(name);
- le_swap( name, name + len, name );
- le_swap( buffer, (char *)buffer + buflen, buffer );
- ret = ofproxy
- ( 4, (void *)package, (char *)name, buffer, (void *)buflen );
- le_swap( buffer, (char *)buffer + buflen, buffer );
- le_swap( name, name + len, name );
- 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 );
- ret = ofproxy
- ( 8, (void *)handle, (char *)data, (void *)len, NULL );
- 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;
-}
-
-void ofw_exit() {
- ofproxy( 16, NULL, NULL, NULL, NULL );
-}
-
-void ofw_dumpregs() {
- ofproxy( 20, NULL, NULL, NULL, NULL );
-}
-
-void ofw_print_string( const char *str ) {
- int len = strlen(str);
- le_swap( (char *)str, str + len, (char *)str );
- ofproxy( 24, (void *)str, NULL, NULL, NULL );
- le_swap( (char *)str, str + len, (char *)str );
-}
-
-void ofw_print_number( int num ) {
- 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; }
}
BOOLEAN PpcConsKbHit() {
- return TRUE;
+ return FALSE;
}
int PpcConsGetCh() {
ofw_print_string("ClearScreen\n");
}
-VIDEODISPLAYMODE PpcVideoSetDisplayMode( char *DisplayMode, BOOLEAN Init ) {
- printf( "DisplayMode: %s %s\n", DisplayMode, Init ? "true" : "false" );
- return VideoGraphicsMode;
-}
-
-/* FIXME: Query */
VOID PpcVideoGetDisplaySize( PULONG Width, PULONG Height, PULONG Depth ) {
- ofw_print_string("GetDisplaySize\n");
- *Width = 640;
- *Height = 480;
- *Depth = 8;
+ //ofw_print_string("GetDisplaySize\n");
+ *Width = 80;
+ *Height = 25;
+ *Depth = 16;
+ //printf("GetDisplaySize(%d,%d,%d)\n", *Width, *Height, *Depth);
}
ULONG PpcVideoGetBufferSize() {
ULONG Width, Height, Depth;
- ofw_print_string("PpcVideoGetBufferSize\n");
+ //ofw_print_string("PpcVideoGetBufferSize\n");
PpcVideoGetDisplaySize( &Width, &Height, &Depth );
return Width * Height * Depth / 8;
}
+VIDEODISPLAYMODE PpcVideoSetDisplayMode( char *DisplayMode, BOOLEAN Init ) {
+ //printf( "DisplayMode: %s %s\n", DisplayMode, Init ? "true" : "false" );
+ if( Init && !video_mem ) {
+ video_mem = MmAllocateMemory( PpcVideoGetBufferSize() );
+ }
+ return VideoTextMode;
+}
+
VOID PpcVideoSetTextCursorPosition( ULONG X, ULONG Y ) {
printf("SetTextCursorPosition(%d,%d)\n", X,Y);
}
}
VOID PpcVideoCopyOffScreenBufferToVRAM( PVOID Buffer ) {
- printf( "CopyOffScreenBufferToVRAM(%x)\n", Buffer );
+ int i,j;
+ ULONG w,h,d;
+ PCHAR ChBuf = Buffer;
+ int offset = 0;
+
+ PpcVideoGetDisplaySize( &w, &h, &d );
+
+ for( i = 0; i < h; i++ ) {
+ for( j = 0; j < w; j++ ) {
+ offset = (j * 2) + (i * w * 2);
+ if( ChBuf[offset] != video_mem[offset] ) {
+ video_mem[offset] = ChBuf[offset];
+ PpcVideoPutChar(ChBuf[offset],0,j+1,i+1);
+ }
+ }
+ }
}
BOOLEAN PpcVideoIsPaletteFixed() {
VOID PpcVideoPrepareForReactOS() {
printf( "PrepareForReactOS\n");
}
-/* XXX FIXME:
- * According to the linux people (this is backed up by my own experience),
- * the memory object in older ofw does not do getprop right.
- *
- * The "right" way is to probe the pci bridge. *sigh*
+/*
+ * Get memory the proper openfirmware way
*/
ULONG PpcGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap,
ULONG MaxMemoryMapSize ) {
- printf("GetMemoryMap(chosen=%x)\n", chosen_package);
+ int i, memhandle, mmuhandle, returned, total = 0, num_mem = 0;
+ int memdata[256];
- BiosMemoryMap[0].Type = MEMTYPE_USABLE;
- BiosMemoryMap[0].BaseAddress = 0;
- BiosMemoryMap[0].Length = 32 * 1024 * 1024; /* Assume 32 meg for now */
+ printf("PpcGetMemoryMap(%d)\n", MaxMemoryMapSize);
- printf( "Returning memory map (%dk total)\n",
- (int)BiosMemoryMap[0].Length / 1024 );
+ if( mem_base ) {
+ BiosMemoryMap[0].Type = MEMTYPE_USABLE;
+ BiosMemoryMap[0].BaseAddress = (ULONG)mem_base;
+ BiosMemoryMap[0].Length = TOTAL_HEAP_NEEDED;
+ printf("[cached] returning 1 element\n");
+ return 1;
+ }
- return 1;
+ ofw_getprop(chosen_package, "memory",
+ (char *)&memhandle, sizeof(memhandle));
+ ofw_getprop(chosen_package, "mmu",
+ (char *)&mmuhandle, sizeof(mmuhandle));
+
+ returned = ofw_getprop(memhandle, "available",
+ (char *)memdata, sizeof(memdata));
+
+ /* We need to leave some for open firmware. Let's claim up to 16 megs
+ * for now */
+
+ for( i = 0; i < returned / sizeof(int) && !num_mem; i += 2 ) {
+ BiosMemoryMap[num_mem].Type = MEMTYPE_USABLE;
+ BiosMemoryMap[num_mem].BaseAddress = memdata[i];
+ mem_base = (void *)memdata[i];
+ BiosMemoryMap[num_mem].Length = memdata[i+1];
+ if( BiosMemoryMap[num_mem].Length >= TOTAL_HEAP_NEEDED &&
+ total < TOTAL_HEAP_NEEDED ) {
+ BiosMemoryMap[num_mem].Length = TOTAL_HEAP_NEEDED;
+ ofw_claim(BiosMemoryMap[num_mem].BaseAddress,
+ BiosMemoryMap[num_mem].Length, 0x1000); /* claim it */
+ total += BiosMemoryMap[0].Length;
+ num_mem++;
+ }
+ }
+
+ printf( "Returning memory map (%dk total)\n", total / 1024 );
+
+ return num_mem;
}
/* Strategy:
PULONGLONG StartSector,
PULONGLONG SectorCount,
int *FsType ) {
- return FALSE;
+ char *remain = strchr(SystemPath, '\\');
+ if( remain ) {
+ strcpy( RemainingPath, remain+1 );
+ } else {
+ RemainingPath[0] = 0;
+ }
+ *Device = 0;
+ return PpcDiskGetBootVolume(DriveNumber, StartSector, SectorCount, FsType);
}
BOOLEAN PpcDiskGetBootPath( char *OutBootPath, unsigned Size ) {
}
BOOLEAN PpcDiskReadLogicalSectors( ULONG DriveNumber, ULONGLONG SectorNumber,
- ULONG SectorCount, PVOID Buffer ) {
+ ULONG SectorCount, PVOID Buffer ) {
int rlen = 0;
if( part_handle == -1 ) {
return FALSE;
}
- if( ofw_seek( part_handle, SectorNumber * 512 ) ) {
- printf("Seek to %x failed\n", SectorNumber * 512);
+ if( ofw_seek( part_handle,
+ (ULONG)(SectorNumber >> 25),
+ (ULONG)((SectorNumber * 512) & 0xffffffff) ) ) {
+ printf("Seek to %x failed\n", (ULONG)(SectorNumber * 512));
return FALSE;
}
- rlen = ofw_read( part_handle, Buffer, SectorCount * 512 );
+ rlen = ofw_read( part_handle, Buffer, (ULONG)(SectorCount * 512) );
return rlen > 0;
}
VOID PpcRTCGetCurrentDateTime( PULONG Hear, PULONG Month, PULONG Day,
PULONG Hour, PULONG Minute, PULONG Second ) {
- printf("RTCGeturrentDateTime\n");
+ //printf("RTCGeturrentDateTime\n");
}
VOID PpcHwDetect() {
printf("PpcHwDetect\n");
}
+BOOLEAN PpcDiskNormalizeSystemPath(char *SystemPath, unsigned Size) {
+ CHAR BootPath[256];
+ ULONG PartitionNumber;
+ ULONG DriveNumber;
+ PARTITION_TABLE_ENTRY PartEntry;
+ char *p;
+
+ if (!DissectArcPath(SystemPath, BootPath, &DriveNumber, &PartitionNumber))
+ {
+ return FALSE;
+ }
+
+ if (0 != PartitionNumber)
+ {
+ return TRUE;
+ }
+
+ if (! DiskGetActivePartitionEntry(DriveNumber,
+ &PartEntry,
+ &PartitionNumber) ||
+ PartitionNumber < 1 || 9 < PartitionNumber)
+ {
+ return FALSE;
+ }
+
+ p = SystemPath;
+ while ('\0' != *p && 0 != _strnicmp(p, "partition(", 10)) {
+ p++;
+ }
+ p = strchr(p, ')');
+ if (NULL == p || '0' != *(p - 1)) {
+ return FALSE;
+ }
+ *(p - 1) = '0' + PartitionNumber;
+
+ return TRUE;
+}
+
typedef unsigned int uint32_t;
void PpcInit( of_proxy the_ofproxy ) {
- int len;
+ int len, stdin_handle_chosen;
ofproxy = the_ofproxy;
+ ofw_print_string("Freeldr PowerPC Init\n");
+
chosen_package = ofw_finddevice( "/chosen" );
+ ofw_print_string("Freeldr: chosen_package is ");
+ ofw_print_number(chosen_package);
+ ofw_print_string("\n");
+
ofw_getprop( chosen_package, "stdin",
- &stdin_handle, sizeof(stdin_handle) );
+ (char *)&stdin_handle_chosen, sizeof(stdin_handle_chosen) );
- stdin_handle = REV(stdin_handle);
+ ofw_print_string("Freeldr: stdin_handle is ");
+ ofw_print_number(stdin_handle_chosen);
+ ofw_print_string("\n");
+
+ stdin_handle = stdin_handle_chosen;
+
+ /* stdin_handle = REV(stdin_handle); */
MachVtbl.ConsPutChar = PpcPutChar;
MachVtbl.ConsKbHit = PpcConsKbHit;
MachVtbl.ConsGetCh = PpcConsGetCh;
-
+
printf( "stdin_handle is %x\n", stdin_handle );
+ printf("virt2phys (0xe00000,D) -> %x\n", PpcVirt2phys(0xe00000,0));
+ printf("virt2phys (0xe01000,D) -> %x\n", PpcVirt2phys(0xe01000,0));
MachVtbl.VideoClearScreen = PpcVideoClearScreen;
MachVtbl.VideoSetDisplayMode = PpcVideoSetDisplayMode;
MachVtbl.GetMemoryMap = PpcGetMemoryMap;
+ MachVtbl.DiskNormalizeSystemPath = PpcDiskNormalizeSystemPath;
MachVtbl.DiskGetBootVolume = PpcDiskGetBootVolume;
MachVtbl.DiskGetSystemVolume = PpcDiskGetSystemVolume;
MachVtbl.DiskGetBootPath = PpcDiskGetBootPath;