2 * FreeLoader PowerPC Part
3 * Copyright (C) 2005 Art Yerkes
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 extern void BootMain( char * );
24 extern char *GetFreeLoaderVersionString();
26 void *PageDirectoryStart
, *PageDirectoryEnd
;
27 static int chosen_package
, stdin_handle
, part_handle
= -1;
28 BOOLEAN AcpiPresent
= FALSE
;
29 char BootPath
[0x100] = { 0 }, BootPart
[0x100] = { 0 }, CmdLine
[0x100] = { 0 };
32 void le_swap( void *start_addr_v
,
34 void *target_addr_v
) {
35 long *start_addr
= (long *)ROUND_DOWN((long)start_addr_v
,8),
36 *end_addr
= (long *)ROUND_UP((long)end_addr_v
,8),
37 *target_addr
= (long *)ROUND_DOWN((long)target_addr_v
,8);
39 while( start_addr
<= end_addr
) {
41 target_addr
[0] = REV(start_addr
[1]);
42 target_addr
[1] = REV(tmp
);
48 void PpcPutChar( int ch
) {
50 if( ch
== 0x0a ) { buf
[0] = 0x0d; buf
[1] = 0x0a; }
51 else { buf
[0] = ch
; buf
[1] = 0; }
53 ofw_print_string( buf
);
56 int PpcFindDevice( int depth
, int parent
, char *devname
, int *nth
) {
63 next
= ofw_child( parent
);
65 //printf( "next = %x\n", next );
67 gotname
= ofw_getprop(parent
, "name", buf
, 256);
69 //printf( "gotname = %d\n", gotname );
71 match
= !strncmp(buf
, devname
, strlen(devname
));
73 if( !nth
&& match
) return parent
;
75 for( i
= 0; i
< depth
; i
++ ) PpcPutChar( ' ' );
79 printf( "%c Name: %s\n", match
? '*' : ' ', buf
);
81 printf( "- No name attribute for %x\n", parent
);
85 while( !match
&& next
) {
86 i
= PpcFindDevice( depth
+1, next
, devname
, nth
);
88 next
= ofw_peer( next
);
94 BOOLEAN
PpcConsKbHit() {
100 ofw_read( stdin_handle
, &buf
, 1 );
104 void PpcVideoClearScreen( UCHAR Attr
) {
105 ofw_print_string("ClearScreen\n");
108 VIDEODISPLAYMODE
PpcVideoSetDisplayMode( char *DisplayMode
, BOOLEAN Init
) {
109 printf( "DisplayMode: %s %s\n", DisplayMode
, Init
? "true" : "false" );
110 return VideoGraphicsMode
;
114 VOID
PpcVideoGetDisplaySize( PULONG Width
, PULONG Height
, PULONG Depth
) {
115 ofw_print_string("GetDisplaySize\n");
121 ULONG
PpcVideoGetBufferSize() {
122 ULONG Width
, Height
, Depth
;
123 ofw_print_string("PpcVideoGetBufferSize\n");
124 PpcVideoGetDisplaySize( &Width
, &Height
, &Depth
);
125 return Width
* Height
* Depth
/ 8;
128 VOID
PpcVideoSetTextCursorPosition( ULONG X
, ULONG Y
) {
129 printf("SetTextCursorPosition(%d,%d)\n", X
,Y
);
132 VOID
PpcVideoHideShowTextCursor( BOOLEAN Show
) {
133 printf("HideShowTextCursor(%s)\n", Show
? "true" : "false");
136 VOID
PpcVideoPutChar( int Ch
, UCHAR Attr
, unsigned X
, unsigned Y
) {
137 printf( "\033[%d;%dH%c", Y
, X
, Ch
);
140 VOID
PpcVideoCopyOffScreenBufferToVRAM( PVOID Buffer
) {
141 printf( "CopyOffScreenBufferToVRAM(%x)\n", Buffer
);
144 BOOLEAN
PpcVideoIsPaletteFixed() {
148 VOID
PpcVideoSetPaletteColor( UCHAR Color
,
149 UCHAR Red
, UCHAR Green
, UCHAR Blue
) {
150 printf( "SetPaletteColor(%x,%x,%x,%x)\n", Color
, Red
, Green
, Blue
);
153 VOID
PpcVideoGetPaletteColor( UCHAR Color
,
154 UCHAR
*Red
, UCHAR
*Green
, UCHAR
*Blue
) {
155 printf( "GetPaletteColor(%x)\n", Color
);
158 VOID
PpcVideoSync() {
162 VOID
PpcVideoPrepareForReactOS() {
163 printf( "PrepareForReactOS\n");
166 * According to the linux people (this is backed up by my own experience),
167 * the memory object in older ofw does not do getprop right.
169 * The "right" way is to probe the pci bridge. *sigh*
171 ULONG
PpcGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap
,
172 ULONG MaxMemoryMapSize
) {
173 printf("GetMemoryMap(chosen=%x)\n", chosen_package
);
175 BiosMemoryMap
[0].Type
= MEMTYPE_USABLE
;
176 BiosMemoryMap
[0].BaseAddress
= 0;
177 BiosMemoryMap
[0].Length
= 32 * 1024 * 1024; /* Assume 32 meg for now */
179 printf( "Returning memory map (%dk total)\n",
180 (int)BiosMemoryMap
[0].Length
/ 1024 );
187 * For now, it'll be easy enough to use the boot command line as our boot path.
188 * Treat it as the path of a disk partition. We might even be able to get
189 * away with grabbing a partition image by tftp in this scenario.
192 BOOLEAN
PpcDiskGetBootVolume( PULONG DriveNumber
, PULONGLONG StartSector
, PULONGLONG SectorCount
, int *FsType
) {
200 BOOLEAN
PpcDiskGetSystemVolume( char *SystemPath
,
204 PULONGLONG StartSector
,
205 PULONGLONG SectorCount
,
210 BOOLEAN
PpcDiskGetBootPath( char *OutBootPath
, unsigned Size
) {
211 strncpy( OutBootPath
, BootPath
, Size
);
215 VOID
PpcDiskGetBootDevice( PULONG BootDevice
) {
216 BootDevice
[0] = BootDevice
[1] = 0;
219 BOOLEAN
PpcDiskBootingFromFloppy(VOID
) {
223 BOOLEAN
PpcDiskReadLogicalSectors( ULONG DriveNumber
, ULONGLONG SectorNumber
,
224 ULONG SectorCount
, PVOID Buffer
) {
227 if( part_handle
== -1 ) {
228 part_handle
= ofw_open( BootPart
);
230 if( part_handle
== -1 ) {
231 printf("Could not open any disk devices we know about\n");
236 if( part_handle
== -1 ) {
237 printf("Got partition handle %x\n", part_handle
);
241 if( ofw_seek( part_handle
, SectorNumber
* 512 ) ) {
242 printf("Seek to %x failed\n", SectorNumber
* 512);
245 rlen
= ofw_read( part_handle
, Buffer
, SectorCount
* 512 );
249 BOOLEAN
PpcDiskGetPartitionEntry( ULONG DriveNumber
, ULONG PartitionNumber
,
250 PPARTITION_TABLE_ENTRY PartitionTableEntry
) {
251 printf("GetPartitionEntry(%d,%d)\n", DriveNumber
, PartitionNumber
);
255 BOOLEAN
PpcDiskGetDriveGeometry( ULONG DriveNumber
, PGEOMETRY DriveGeometry
) {
256 printf("GetGeometry(%d)\n", DriveNumber
);
257 DriveGeometry
->BytesPerSector
= 512;
258 DriveGeometry
->Heads
= 16;
259 DriveGeometry
->Sectors
= 63;
263 ULONG
PpcDiskGetCacheableBlockCount( ULONG DriveNumber
) {
264 printf("GetCacheableBlockCount\n");
268 VOID
PpcRTCGetCurrentDateTime( PULONG Hear
, PULONG Month
, PULONG Day
,
269 PULONG Hour
, PULONG Minute
, PULONG Second
) {
270 printf("RTCGeturrentDateTime\n");
274 printf("PpcHwDetect\n");
277 typedef unsigned int uint32_t;
279 void PpcInit( of_proxy the_ofproxy
) {
281 ofproxy
= the_ofproxy
;
283 ofw_print_string("Made it into freeldr LE code ... bootstrap complete\n");
285 chosen_package
= ofw_finddevice( "/chosen" );
287 ofw_print_string("Chosen package: ");
288 ofw_print_number(chosen_package
);
289 ofw_print_string("\n");
291 ofw_getprop( chosen_package
, "stdin",
292 (char *)&stdin_handle
, sizeof(stdin_handle
) );
294 ofw_print_string("ofw_getprop done\n");
296 /* stdin_handle = REV(stdin_handle); */
298 ofw_print_string("Populating MachVtbl: ");
299 ofw_print_number((int)&MachVtbl
);
300 ofw_print_string("\n");
302 MachVtbl
.ConsPutChar
= PpcPutChar
;
303 MachVtbl
.ConsKbHit
= PpcConsKbHit
;
304 MachVtbl
.ConsGetCh
= PpcConsGetCh
;
306 ofw_print_string("About to do printf\n");
308 printf( "stdin_handle is %x\n", stdin_handle
);
310 MachVtbl
.VideoClearScreen
= PpcVideoClearScreen
;
311 MachVtbl
.VideoSetDisplayMode
= PpcVideoSetDisplayMode
;
312 MachVtbl
.VideoGetDisplaySize
= PpcVideoGetDisplaySize
;
313 MachVtbl
.VideoGetBufferSize
= PpcVideoGetBufferSize
;
314 MachVtbl
.VideoSetTextCursorPosition
= PpcVideoSetTextCursorPosition
;
315 MachVtbl
.VideoHideShowTextCursor
= PpcVideoHideShowTextCursor
;
316 MachVtbl
.VideoPutChar
= PpcVideoPutChar
;
317 MachVtbl
.VideoCopyOffScreenBufferToVRAM
=
318 PpcVideoCopyOffScreenBufferToVRAM
;
319 MachVtbl
.VideoIsPaletteFixed
= PpcVideoIsPaletteFixed
;
320 MachVtbl
.VideoSetPaletteColor
= PpcVideoSetPaletteColor
;
321 MachVtbl
.VideoGetPaletteColor
= PpcVideoGetPaletteColor
;
322 MachVtbl
.VideoSync
= PpcVideoSync
;
323 MachVtbl
.VideoPrepareForReactOS
= PpcVideoPrepareForReactOS
;
325 MachVtbl
.GetMemoryMap
= PpcGetMemoryMap
;
327 MachVtbl
.DiskGetBootVolume
= PpcDiskGetBootVolume
;
328 MachVtbl
.DiskGetSystemVolume
= PpcDiskGetSystemVolume
;
329 MachVtbl
.DiskGetBootPath
= PpcDiskGetBootPath
;
330 MachVtbl
.DiskGetBootDevice
= PpcDiskGetBootDevice
;
331 MachVtbl
.DiskBootingFromFloppy
= PpcDiskBootingFromFloppy
;
332 MachVtbl
.DiskReadLogicalSectors
= PpcDiskReadLogicalSectors
;
333 MachVtbl
.DiskGetPartitionEntry
= PpcDiskGetPartitionEntry
;
334 MachVtbl
.DiskGetDriveGeometry
= PpcDiskGetDriveGeometry
;
335 MachVtbl
.DiskGetCacheableBlockCount
= PpcDiskGetCacheableBlockCount
;
337 MachVtbl
.RTCGetCurrentDateTime
= PpcRTCGetCurrentDateTime
;
339 MachVtbl
.HwDetect
= PpcHwDetect
;
341 printf( "FreeLDR version [%s]\n", GetFreeLoaderVersionString() );
343 len
= ofw_getprop(chosen_package
, "bootargs",
344 CmdLine
, sizeof(CmdLine
));
346 if( len
< 0 ) len
= 0;
352 void MachInit(const char *CmdLine
) {
359 printf( "Determining boot device: [%s]\n", CmdLine
);
361 printf( "Boot Args: %s\n", CmdLine
);
363 for( i
= 0; i
< strlen(CmdLine
); i
++ ) {
364 if( strncmp(CmdLine
+ i
, "boot=", 5) == 0) {
365 strcpy(BootPart
, CmdLine
+ i
+ 5);
366 sep
= strchr(BootPart
, ' ');
373 if( strlen(BootPart
) == 0 ) {
374 len
= ofw_getprop(chosen_package
, "bootpath",
375 BootPath
, sizeof(BootPath
));
377 if( len
< 0 ) len
= 0;
379 printf( "Boot Path: %s\n", BootPath
);
381 sep
= strrchr(BootPath
, ',');
383 strcpy(BootPart
, BootPath
);
385 BootPart
[sep
- BootPath
] = 0;
389 printf( "FreeLDR starting (boot partition: %s)\n", BootPart
);
392 /* Compatibility functions that don't do much */
396 UCHAR NTAPI
READ_PORT_UCHAR(PUCHAR Address
) {
400 void WRITE_PORT_UCHAR(PUCHAR Address
, UCHAR Value
) {
403 void DiskStopFloppyMotor() {
406 void BootOldLinuxKernel( unsigned long size
) {
410 void BootNewLinuxKernel() {
414 void ChainLoadBiosBootSectorCode() {