Woot. We're deep into freeldr. Printf is working, etc.
[reactos.git] / reactos / boot / freeldr / freeldr / arch / powerpc / mach.c
1 /*
2 * FreeLoader PowerPC Part
3 * Copyright (C) 2005 Art Yerkes
4 *
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.
9 *
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.
14 *
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.
18 */
19 #include "freeldr.h"
20 #include "machine.h"
21 #include "of.h"
22
23 extern void BootMain( char * );
24 extern char *GetFreeLoaderVersionString();
25 of_proxy ofproxy;
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 };
30 jmp_buf jmp;
31
32 void le_swap( void *start_addr_v,
33 void *end_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);
38 long tmp;
39 while( start_addr <= end_addr ) {
40 tmp = start_addr[0];
41 target_addr[0] = REV(start_addr[1]);
42 target_addr[1] = REV(tmp);
43 start_addr += 2;
44 target_addr += 2;
45 }
46 }
47
48 void PpcPutChar( int ch ) {
49 char buf[3];
50 if( ch == 0x0a ) { buf[0] = 0x0d; buf[1] = 0x0a; }
51 else { buf[0] = ch; buf[1] = 0; }
52 buf[2] = 0;
53 ofw_print_string( buf );
54 }
55
56 int PpcFindDevice( int depth, int parent, char *devname, int *nth ) {
57 static char buf[256];
58 int next = 0;
59 int gotname = 0;
60 int match = 0;
61 int i;
62
63 next = ofw_child( parent );
64
65 //printf( "next = %x\n", next );
66
67 gotname = ofw_getprop(parent, "name", buf, 256);
68
69 //printf( "gotname = %d\n", gotname );
70
71 match = !strncmp(buf, devname, strlen(devname));
72
73 if( !nth && match ) return parent;
74
75 for( i = 0; i < depth; i++ ) PpcPutChar( ' ' );
76
77 if( depth == 1 ) {
78 if( gotname > 0 ) {
79 printf( "%c Name: %s\n", match ? '*' : ' ', buf );
80 } else {
81 printf( "- No name attribute for %x\n", parent );
82 }
83 }
84
85 while( !match && next ) {
86 i = PpcFindDevice( depth+1, next, devname, nth );
87 if( i ) return i;
88 next = ofw_peer( next );
89 }
90
91 return 0;
92 }
93
94 BOOLEAN PpcConsKbHit() {
95 return TRUE;
96 }
97
98 int PpcConsGetCh() {
99 char buf;
100 ofw_read( stdin_handle, &buf, 1 );
101 return buf;
102 }
103
104 void PpcVideoClearScreen( UCHAR Attr ) {
105 ofw_print_string("ClearScreen\n");
106 }
107
108 VIDEODISPLAYMODE PpcVideoSetDisplayMode( char *DisplayMode, BOOLEAN Init ) {
109 printf( "DisplayMode: %s %s\n", DisplayMode, Init ? "true" : "false" );
110 return VideoGraphicsMode;
111 }
112
113 /* FIXME: Query */
114 VOID PpcVideoGetDisplaySize( PULONG Width, PULONG Height, PULONG Depth ) {
115 ofw_print_string("GetDisplaySize\n");
116 *Width = 640;
117 *Height = 480;
118 *Depth = 8;
119 }
120
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;
126 }
127
128 VOID PpcVideoSetTextCursorPosition( ULONG X, ULONG Y ) {
129 printf("SetTextCursorPosition(%d,%d)\n", X,Y);
130 }
131
132 VOID PpcVideoHideShowTextCursor( BOOLEAN Show ) {
133 printf("HideShowTextCursor(%s)\n", Show ? "true" : "false");
134 }
135
136 VOID PpcVideoPutChar( int Ch, UCHAR Attr, unsigned X, unsigned Y ) {
137 printf( "\033[%d;%dH%c", Y, X, Ch );
138 }
139
140 VOID PpcVideoCopyOffScreenBufferToVRAM( PVOID Buffer ) {
141 printf( "CopyOffScreenBufferToVRAM(%x)\n", Buffer );
142 }
143
144 BOOLEAN PpcVideoIsPaletteFixed() {
145 return FALSE;
146 }
147
148 VOID PpcVideoSetPaletteColor( UCHAR Color,
149 UCHAR Red, UCHAR Green, UCHAR Blue ) {
150 printf( "SetPaletteColor(%x,%x,%x,%x)\n", Color, Red, Green, Blue );
151 }
152
153 VOID PpcVideoGetPaletteColor( UCHAR Color,
154 UCHAR *Red, UCHAR *Green, UCHAR *Blue ) {
155 printf( "GetPaletteColor(%x)\n", Color);
156 }
157
158 VOID PpcVideoSync() {
159 printf( "Sync\n" );
160 }
161
162 VOID PpcVideoPrepareForReactOS() {
163 printf( "PrepareForReactOS\n");
164 }
165 /* XXX FIXME:
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.
168 *
169 * The "right" way is to probe the pci bridge. *sigh*
170 */
171 ULONG PpcGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap,
172 ULONG MaxMemoryMapSize ) {
173 printf("GetMemoryMap(chosen=%x)\n", chosen_package);
174
175 BiosMemoryMap[0].Type = MEMTYPE_USABLE;
176 BiosMemoryMap[0].BaseAddress = 0;
177 BiosMemoryMap[0].Length = 32 * 1024 * 1024; /* Assume 32 meg for now */
178
179 printf( "Returning memory map (%dk total)\n",
180 (int)BiosMemoryMap[0].Length / 1024 );
181
182 return 1;
183 }
184
185 /* Strategy:
186 *
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.
190 */
191
192 BOOLEAN PpcDiskGetBootVolume( PULONG DriveNumber, PULONGLONG StartSector, PULONGLONG SectorCount, int *FsType ) {
193 *DriveNumber = 0;
194 *StartSector = 0;
195 *SectorCount = 0;
196 *FsType = FS_FAT;
197 return TRUE;
198 }
199
200 BOOLEAN PpcDiskGetSystemVolume( char *SystemPath,
201 char *RemainingPath,
202 PULONG Device,
203 PULONG DriveNumber,
204 PULONGLONG StartSector,
205 PULONGLONG SectorCount,
206 int *FsType ) {
207 return FALSE;
208 }
209
210 BOOLEAN PpcDiskGetBootPath( char *OutBootPath, unsigned Size ) {
211 strncpy( OutBootPath, BootPath, Size );
212 return TRUE;
213 }
214
215 VOID PpcDiskGetBootDevice( PULONG BootDevice ) {
216 BootDevice[0] = BootDevice[1] = 0;
217 }
218
219 BOOLEAN PpcDiskBootingFromFloppy(VOID) {
220 return FALSE;
221 }
222
223 BOOLEAN PpcDiskReadLogicalSectors( ULONG DriveNumber, ULONGLONG SectorNumber,
224 ULONG SectorCount, PVOID Buffer ) {
225 int rlen = 0;
226
227 if( part_handle == -1 ) {
228 part_handle = ofw_open( BootPart );
229
230 if( part_handle == -1 ) {
231 printf("Could not open any disk devices we know about\n");
232 return FALSE;
233 }
234 }
235
236 if( part_handle == -1 ) {
237 printf("Got partition handle %x\n", part_handle);
238 return FALSE;
239 }
240
241 if( ofw_seek( part_handle, SectorNumber * 512 ) ) {
242 printf("Seek to %x failed\n", SectorNumber * 512);
243 return FALSE;
244 }
245 rlen = ofw_read( part_handle, Buffer, SectorCount * 512 );
246 return rlen > 0;
247 }
248
249 BOOLEAN PpcDiskGetPartitionEntry( ULONG DriveNumber, ULONG PartitionNumber,
250 PPARTITION_TABLE_ENTRY PartitionTableEntry ) {
251 printf("GetPartitionEntry(%d,%d)\n", DriveNumber, PartitionNumber);
252 return FALSE;
253 }
254
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;
260 return TRUE;
261 }
262
263 ULONG PpcDiskGetCacheableBlockCount( ULONG DriveNumber ) {
264 printf("GetCacheableBlockCount\n");
265 return 1;
266 }
267
268 VOID PpcRTCGetCurrentDateTime( PULONG Hear, PULONG Month, PULONG Day,
269 PULONG Hour, PULONG Minute, PULONG Second ) {
270 printf("RTCGeturrentDateTime\n");
271 }
272
273 VOID PpcHwDetect() {
274 printf("PpcHwDetect\n");
275 }
276
277 typedef unsigned int uint32_t;
278
279 void PpcInit( of_proxy the_ofproxy ) {
280 int len;
281 ofproxy = the_ofproxy;
282
283 ofw_print_string("Made it into freeldr LE code ... bootstrap complete\n");
284
285 chosen_package = ofw_finddevice( "/chosen" );
286
287 ofw_print_string("Chosen package: ");
288 ofw_print_number(chosen_package);
289 ofw_print_string("\n");
290
291 ofw_getprop( chosen_package, "stdin",
292 (char *)&stdin_handle, sizeof(stdin_handle) );
293
294 ofw_print_string("ofw_getprop done\n");
295
296 /* stdin_handle = REV(stdin_handle); */
297
298 ofw_print_string("Populating MachVtbl: ");
299 ofw_print_number((int)&MachVtbl);
300 ofw_print_string("\n");
301
302 MachVtbl.ConsPutChar = PpcPutChar;
303 MachVtbl.ConsKbHit = PpcConsKbHit;
304 MachVtbl.ConsGetCh = PpcConsGetCh;
305
306 ofw_print_string("About to do printf\n");
307
308 printf( "stdin_handle is %x\n", stdin_handle );
309
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;
324
325 MachVtbl.GetMemoryMap = PpcGetMemoryMap;
326
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;
336
337 MachVtbl.RTCGetCurrentDateTime = PpcRTCGetCurrentDateTime;
338
339 MachVtbl.HwDetect = PpcHwDetect;
340
341 printf( "FreeLDR version [%s]\n", GetFreeLoaderVersionString() );
342
343 len = ofw_getprop(chosen_package, "bootargs",
344 CmdLine, sizeof(CmdLine));
345
346 if( len < 0 ) len = 0;
347 CmdLine[len] = 0;
348
349 BootMain( CmdLine );
350 }
351
352 void MachInit(const char *CmdLine) {
353 int len, i;
354 char *sep;
355
356 BootPart[0] = 0;
357 BootPath[0] = 0;
358
359 printf( "Determining boot device: [%s]\n", CmdLine );
360
361 printf( "Boot Args: %s\n", CmdLine );
362 sep = NULL;
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, ' ');
367 if( sep )
368 *sep = 0;
369 break;
370 }
371 }
372
373 if( strlen(BootPart) == 0 ) {
374 len = ofw_getprop(chosen_package, "bootpath",
375 BootPath, sizeof(BootPath));
376
377 if( len < 0 ) len = 0;
378 BootPath[len] = 0;
379 printf( "Boot Path: %s\n", BootPath );
380
381 sep = strrchr(BootPath, ',');
382
383 strcpy(BootPart, BootPath);
384 if( sep ) {
385 BootPart[sep - BootPath] = 0;
386 }
387 }
388
389 printf( "FreeLDR starting (boot partition: %s)\n", BootPart );
390 }
391
392 /* Compatibility functions that don't do much */
393 void beep() {
394 }
395
396 UCHAR NTAPI READ_PORT_UCHAR(PUCHAR Address) {
397 return 0xff;
398 }
399
400 void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value) {
401 }
402
403 void DiskStopFloppyMotor() {
404 }
405
406 void BootOldLinuxKernel( unsigned long size ) {
407 ofw_exit();
408 }
409
410 void BootNewLinuxKernel() {
411 ofw_exit();
412 }
413
414 void ChainLoadBiosBootSectorCode() {
415 ofw_exit();
416 }