Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmach.c
Go to the documentation of this file.
00001 /* 00002 * FreeLoader PowerPC Part 00003 * Copyright (C) 2005 Art Yerkes 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, write to the Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 */ 00019 #include "freeldr.h" 00020 #include "machine.h" 00021 #include "ppcmmu/mmu.h" 00022 #include "of.h" 00023 #include "prep.h" 00024 #include "compat.h" 00025 00026 extern void BootMain( LPSTR CmdLine ); 00027 extern PCHAR GetFreeLoaderVersionString(); 00028 extern ULONG CacheSizeLimit; 00029 of_proxy ofproxy; 00030 void *PageDirectoryStart, *PageDirectoryEnd; 00031 static int chosen_package, stdin_handle, stdout_handle, part_handle = -1; 00032 int mmu_handle = 0; 00033 int claimed[4]; 00034 BOOLEAN AcpiPresent = FALSE; 00035 char BootPath[0x100] = { 0 }, BootPart[0x100] = { 0 }, CmdLine[0x100] = { "bootprep" }; 00036 jmp_buf jmp; 00037 volatile char *video_mem = 0; 00038 00039 void PpcOfwPutChar( int ch ) { 00040 char buf[3]; 00041 if( ch == 0x0a ) { buf[0] = 0x0d; buf[1] = 0x0a; } 00042 else { buf[0] = ch; buf[1] = 0; } 00043 buf[2] = 0; 00044 ofw_write(stdout_handle, buf, strlen(buf)); 00045 } 00046 00047 int PpcFindDevice( int depth, int parent, char *devname, int *nth ) { 00048 static char buf[256]; 00049 int next = 0; 00050 int gotname = 0; 00051 int match = 0; 00052 int i; 00053 00054 next = ofw_child( parent ); 00055 00056 //printf( "next = %x\n", next ); 00057 00058 gotname = ofw_getprop(parent, "name", buf, 256); 00059 00060 //printf( "gotname = %d\n", gotname ); 00061 00062 match = !strncmp(buf, devname, strlen(devname)); 00063 00064 if( !nth && match ) return parent; 00065 00066 for( i = 0; i < depth; i++ ) PpcOfwPutChar( ' ' ); 00067 00068 if( depth == 1 ) { 00069 if( gotname > 0 ) { 00070 printf( "%c Name: %s\n", match ? '*' : ' ', buf ); 00071 } else { 00072 printf( "- No name attribute for %x\n", parent ); 00073 } 00074 } 00075 00076 while( !match && next ) { 00077 i = PpcFindDevice( depth+1, next, devname, nth ); 00078 if( i ) return i; 00079 next = ofw_peer( next ); 00080 } 00081 00082 return 0; 00083 } 00084 00085 BOOLEAN PpcConsKbHit() { 00086 return FALSE; 00087 } 00088 00089 int PpcConsGetCh() { 00090 char buf; 00091 ofw_read( stdin_handle, &buf, 1 ); 00092 return buf; 00093 } 00094 00095 void PpcVideoClearScreen( UCHAR Attr ) { 00096 } 00097 00098 VOID PpcVideoGetDisplaySize( PULONG Width, PULONG Height, PULONG Depth ) { 00099 *Width = 80; 00100 *Height = 25; 00101 *Depth = 16; 00102 } 00103 00104 ULONG PpcVideoGetBufferSize() { 00105 ULONG Width, Height, Depth; 00106 MachVideoGetDisplaySize( &Width, &Height, &Depth ); 00107 return Width * Height * Depth / 8; 00108 } 00109 00110 VIDEODISPLAYMODE PpcVideoSetDisplayMode( char *DisplayMode, BOOLEAN Init ) { 00111 //printf( "DisplayMode: %s %s\n", DisplayMode, Init ? "true" : "false" ); 00112 if( Init && !video_mem ) { 00113 video_mem = MmAllocateMemory( PpcVideoGetBufferSize() ); 00114 } 00115 return VideoTextMode; 00116 } 00117 00118 VOID PpcVideoSetTextCursorPosition( ULONG X, ULONG Y ) { 00119 printf("SetTextCursorPosition(%d,%d)\n", X,Y); 00120 } 00121 00122 VOID PpcVideoHideShowTextCursor( BOOLEAN Show ) { 00123 printf("HideShowTextCursor(%s)\n", Show ? "true" : "false"); 00124 } 00125 00126 VOID PpcVideoPutChar( int Ch, UCHAR Attr, unsigned X, unsigned Y ) { 00127 printf( "\033[%d;%dH%c", Y, X, Ch ); 00128 } 00129 00130 VOID PpcVideoCopyOffScreenBufferToVRAM( PVOID Buffer ) { 00131 int i,j; 00132 ULONG w,h,d; 00133 PCHAR ChBuf = Buffer; 00134 int offset = 0; 00135 00136 MachVideoGetDisplaySize( &w, &h, &d ); 00137 00138 for( i = 0; i < h; i++ ) { 00139 for( j = 0; j < w; j++ ) { 00140 offset = (j * 2) + (i * w * 2); 00141 if( ChBuf[offset] != video_mem[offset] ) { 00142 video_mem[offset] = ChBuf[offset]; 00143 MachVideoPutChar(ChBuf[offset],0,j+1,i+1); 00144 } 00145 } 00146 } 00147 } 00148 00149 BOOLEAN PpcVideoIsPaletteFixed() { 00150 return FALSE; 00151 } 00152 00153 VOID PpcVideoSetPaletteColor( UCHAR Color, 00154 UCHAR Red, UCHAR Green, UCHAR Blue ) { 00155 printf( "SetPaletteColor(%x,%x,%x,%x)\n", Color, Red, Green, Blue ); 00156 } 00157 00158 VOID PpcVideoGetPaletteColor( UCHAR Color, 00159 UCHAR *Red, UCHAR *Green, UCHAR *Blue ) { 00160 printf( "GetPaletteColor(%x)\n", Color); 00161 } 00162 00163 VOID PpcVideoSync() { 00164 printf( "Sync\n" ); 00165 } 00166 00167 int mmu_initialized = 0; 00168 int mem_range_end; 00169 VOID PpcInitializeMmu() 00170 { 00171 if(!mmu_initialized) 00172 { 00173 MmuInit(); 00174 MmuDbgInit(0, 0x800003f8); 00175 MmuSetMemorySize(mem_range_end); 00176 //MmuDbgEnter(0x20); 00177 mmu_initialized = 1; 00178 } 00179 } 00180 00181 ULONG PpcPrepGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap, 00182 ULONG MaxMemoryMapSize ); 00183 00184 /* 00185 * Get memory the proper openfirmware way 00186 */ 00187 ULONG PpcGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap, 00188 ULONG MaxMemoryMapSize ) { 00189 int i, memhandle, total = 0, slots = 0, last = 0x40000, allocstart = 0x1000000; 00190 int regdata[0x40]; 00191 00192 printf("PpcGetMemoryMap(%d)\n", MaxMemoryMapSize); 00193 00194 memhandle = ofw_finddevice("/memory"); 00195 00196 ofw_getprop(memhandle, "reg", (char *)regdata, sizeof(regdata)); 00197 00198 /* Try to claim some memory in usable blocks. Try to get some 8mb bits */ 00199 for( i = 0; i < sizeof(claimed) / sizeof(claimed[0]); ) { 00200 if (!claimed[i]) 00201 claimed[i] = ofw_claim(allocstart, 8 * 1024 * 1024, 0x1000); 00202 00203 allocstart += 8 * 1024 * 1024; 00204 00205 if (claimed[i]) { 00206 if (last < claimed[i]) { 00207 BiosMemoryMap[slots].Type = BiosMemoryAcpiReclaim; 00208 BiosMemoryMap[slots].BaseAddress = last; 00209 BiosMemoryMap[slots].Length = claimed[i] - last; 00210 slots++; 00211 } 00212 00213 BiosMemoryMap[slots].Type = BiosMemoryUsable; 00214 BiosMemoryMap[slots].BaseAddress = claimed[i]; 00215 BiosMemoryMap[slots].Length = 8 * 1024 * 1024; 00216 00217 total += BiosMemoryMap[slots].Length; 00218 last = 00219 BiosMemoryMap[slots].BaseAddress + 00220 BiosMemoryMap[slots].Length; 00221 slots++; 00222 i++; 00223 } 00224 } 00225 00226 /* Get the rest until the end of the memory object as we see it */ 00227 if (last < regdata[1]) { 00228 BiosMemoryMap[slots].Type = BiosMemoryAcpiReclaim; 00229 BiosMemoryMap[slots].BaseAddress = last; 00230 BiosMemoryMap[slots].Length = regdata[1] - last; 00231 slots++; 00232 } 00233 00234 for (i = 0; i < slots; i++) { 00235 printf("MemoryMap[%d] = (%x:%x)\n", 00236 i, 00237 (int)BiosMemoryMap[i].BaseAddress, 00238 (int)BiosMemoryMap[i].Length); 00239 00240 } 00241 00242 mem_range_end = regdata[1]; 00243 00244 printf( "Returning memory map (%d entries, %dk free, %dk total ram)\n", 00245 slots, total / 1024, regdata[1] / 1024 ); 00246 00247 return slots; 00248 } 00249 00250 BOOLEAN PpcDiskGetBootPath( char *OutBootPath, unsigned Size ) { 00251 strncpy( OutBootPath, BootPath, Size ); 00252 return TRUE; 00253 } 00254 00255 BOOLEAN PpcDiskReadLogicalSectors( ULONG DriveNumber, ULONGLONG SectorNumber, 00256 ULONG SectorCount, PVOID Buffer ) { 00257 int rlen = 0; 00258 00259 if( part_handle == -1 ) { 00260 part_handle = ofw_open( BootPart ); 00261 00262 if( part_handle == -1 ) { 00263 printf("Could not open any disk devices we know about\n"); 00264 return FALSE; 00265 } 00266 } 00267 00268 if( part_handle == -1 ) { 00269 printf("Got partition handle %x\n", part_handle); 00270 return FALSE; 00271 } 00272 00273 if( ofw_seek( part_handle, 00274 (ULONG)(SectorNumber >> 25), 00275 (ULONG)((SectorNumber * 512) & 0xffffffff) ) ) { 00276 printf("Seek to %x failed\n", (ULONG)(SectorNumber * 512)); 00277 return FALSE; 00278 } 00279 00280 rlen = ofw_read( part_handle, Buffer, (ULONG)(SectorCount * 512) ); 00281 return rlen > 0; 00282 } 00283 00284 BOOLEAN PpcDiskGetDriveGeometry( ULONG DriveNumber, PGEOMETRY DriveGeometry ) { 00285 printf("GetGeometry(%d)\n", DriveNumber); 00286 DriveGeometry->BytesPerSector = 512; 00287 DriveGeometry->Heads = 16; 00288 DriveGeometry->Sectors = 63; 00289 return TRUE; 00290 } 00291 00292 ULONG PpcDiskGetCacheableBlockCount( ULONG DriveNumber ) { 00293 printf("GetCacheableBlockCount\n"); 00294 return 1; 00295 } 00296 00297 TIMEINFO* 00298 PpcGetTime(VOID) 00299 { 00300 static TIMEINFO TimeInfo; 00301 //printf("PpcGetTime\n"); 00302 return &TimeInfo; 00303 } 00304 00305 VOID NarrowToWide(WCHAR *wide_name, char *name) 00306 { 00307 char *copy_name; 00308 WCHAR *wide_name_ptr; 00309 for (wide_name_ptr = wide_name, copy_name = name; 00310 (*wide_name_ptr = *copy_name); 00311 wide_name_ptr++, copy_name++); 00312 } 00313 00314 /* Recursively copy the device tree into our representation 00315 * It'll be passed to HAL. 00316 * 00317 * When NT was first done on PPC, it was on PReP hardware, which is very 00318 * like PC hardware (really, just a PPC on a PC motherboard). HAL can guess 00319 * the addresses of needed resources in this scheme as it can on x86. 00320 * 00321 * Most PPC hardware doesn't assign fixed addresses to hardware, which is 00322 * the problem that open firmware partially solves. It allows hardware makers 00323 * much more leeway in building PPC systems. Unfortunately, because 00324 * openfirmware as originally specified neither captures nor standardizes 00325 * all possible information, and also because of bugs, most OSs use a hybrid 00326 * configuration scheme that relies both on verification of devices and 00327 * recording information from openfirmware to be treated as hints. 00328 */ 00329 VOID OfwCopyDeviceTree 00330 (PCONFIGURATION_COMPONENT_DATA ParentKey, 00331 char *name, 00332 int innode, 00333 ULONG *BusNumber, 00334 ULONG *DiskController, 00335 ULONG *DiskNumber) 00336 { 00337 int proplen = 0, node = innode; 00338 char *prev_name, cur_name[64], data[256], *slash, devtype[64]; 00339 wchar_t wide_name[64]; 00340 PCONFIGURATION_COMPONENT_DATA NewKey; 00341 00342 NarrowToWide(wide_name, name); 00343 00344 /* Create a key for this device */ 00345 FldrCreateComponentKey 00346 (ParentKey, 00347 AdapterClass, 00348 MultiFunctionAdapter, 00349 0, 00350 0, 00351 (ULONG)-1, 00352 NULL, 00353 NULL, 00354 0, 00355 &NewKey); 00356 00357 /* Add properties */ 00358 for (prev_name = ""; ofw_nextprop(node, prev_name, cur_name) == 1; ) 00359 { 00360 proplen = ofw_getproplen(node, cur_name); 00361 if (proplen > 256 || proplen < 0) 00362 { 00363 printf("Warning: not getting prop %s (too long: %d)\n", 00364 cur_name, proplen); 00365 continue; 00366 } 00367 ofw_getprop(node, cur_name, data, sizeof(data)); 00368 00369 /* Get device type so we can examine it */ 00370 if (!strcmp(cur_name, "device_type")) 00371 strcpy(devtype, (char *)data); 00372 00373 NarrowToWide(wide_name, cur_name); 00374 //RegSetValue(NewKey, wide_name, REG_BINARY, data, proplen); 00375 00376 strcpy(data, cur_name); 00377 prev_name = data; 00378 } 00379 00380 #if 0 00381 /* Special device handling */ 00382 if (!strcmp(devtype, "ata")) 00383 { 00384 OfwHandleDiskController(NewKey, node, *DiskController); 00385 (*DiskController)++; 00386 *DiskNumber = 0; 00387 } 00388 else if (!strcmp(devtype, "disk")) 00389 { 00390 OfwHandleDiskObject(NewKey, node, *DiskController, *DiskNumber); 00391 (*DiskNumber)++; 00392 } 00393 #endif 00394 00395 /* Subdevices */ 00396 for (node = ofw_child(node); node; node = ofw_peer(node)) 00397 { 00398 ofw_package_to_path(node, data, sizeof(data)); 00399 slash = strrchr(data, '/'); 00400 if (slash) slash++; else continue; 00401 OfwCopyDeviceTree 00402 (NewKey, slash, node, BusNumber, DiskController, DiskNumber); 00403 } 00404 } 00405 00406 PCONFIGURATION_COMPONENT_DATA PpcHwDetect() { 00407 PCONFIGURATION_COMPONENT_DATA RootKey; 00408 ULONG BusNumber = 0, DiskController = 0, DiskNumber = 0; 00409 int node = ofw_finddevice("/"); 00410 00411 FldrCreateSystemKey(&RootKey); 00412 00413 OfwCopyDeviceTree(RootKey,"/",node,&BusNumber,&DiskController,&DiskNumber); 00414 return RootKey; 00415 } 00416 00417 VOID 00418 PpcHwIdle(VOID) 00419 { 00420 /* UNIMPLEMENTED */ 00421 } 00422 00423 /* Compatibility functions that don't do much */ 00424 VOID PpcVideoPrepareForReactOS(BOOLEAN Setup) { 00425 } 00426 00427 void PpcDefaultMachVtbl() 00428 { 00429 MachVtbl.ConsPutChar = PpcOfwPutChar; 00430 MachVtbl.ConsKbHit = PpcConsKbHit; 00431 MachVtbl.ConsGetCh = PpcConsGetCh; 00432 MachVtbl.VideoClearScreen = PpcVideoClearScreen; 00433 MachVtbl.VideoSetDisplayMode = PpcVideoSetDisplayMode; 00434 MachVtbl.VideoGetDisplaySize = PpcVideoGetDisplaySize; 00435 MachVtbl.VideoGetBufferSize = PpcVideoGetBufferSize; 00436 MachVtbl.VideoSetTextCursorPosition = PpcVideoSetTextCursorPosition; 00437 MachVtbl.VideoHideShowTextCursor = PpcVideoHideShowTextCursor; 00438 MachVtbl.VideoPutChar = PpcVideoPutChar; 00439 MachVtbl.VideoCopyOffScreenBufferToVRAM = 00440 PpcVideoCopyOffScreenBufferToVRAM; 00441 MachVtbl.VideoIsPaletteFixed = PpcVideoIsPaletteFixed; 00442 MachVtbl.VideoSetPaletteColor = PpcVideoSetPaletteColor; 00443 MachVtbl.VideoGetPaletteColor = PpcVideoGetPaletteColor; 00444 MachVtbl.VideoSync = PpcVideoSync; 00445 MachVtbl.VideoPrepareForReactOS = PpcVideoPrepareForReactOS; 00446 00447 MachVtbl.GetMemoryMap = PpcGetMemoryMap; 00448 00449 MachVtbl.DiskGetBootPath = PpcDiskGetBootPath; 00450 MachVtbl.DiskReadLogicalSectors = PpcDiskReadLogicalSectors; 00451 MachVtbl.DiskGetDriveGeometry = PpcDiskGetDriveGeometry; 00452 MachVtbl.DiskGetCacheableBlockCount = PpcDiskGetCacheableBlockCount; 00453 00454 MachVtbl.GetTime = PpcGetTime; 00455 00456 MachVtbl.HwDetect = PpcHwDetect; 00457 MachVtbl.HwIdle = PpcHwIdle; 00458 } 00459 00460 void PpcOfwInit() 00461 { 00462 chosen_package = ofw_finddevice( "/chosen" ); 00463 00464 ofw_getprop(chosen_package, "bootargs", 00465 CmdLine, sizeof(CmdLine)); 00466 ofw_getprop( chosen_package, "stdin", 00467 (char *)&stdin_handle, sizeof(stdin_handle) ); 00468 ofw_getprop( chosen_package, "stdout", 00469 (char *)&stdout_handle, sizeof(stdout_handle) ); 00470 ofw_getprop( chosen_package, "mmu", 00471 (char *)&mmu_handle, sizeof(mmu_handle) ); 00472 00473 // Allow forcing prep for broken OFW 00474 if(!strncmp(CmdLine, "bootprep", 8)) 00475 { 00476 printf("Going to PREP init...\n"); 00477 ofproxy = NULL; 00478 PpcPrepInit(); 00479 return; 00480 } 00481 00482 printf( "FreeLDR version [%s]\n", GetFreeLoaderVersionString() ); 00483 00484 BootMain( CmdLine ); 00485 } 00486 00487 void PpcInit( of_proxy the_ofproxy ) { 00488 // Hack to be a bit easier on ram 00489 CacheSizeLimit = 64 * 1024; 00490 ofproxy = the_ofproxy; 00491 PpcDefaultMachVtbl(); 00492 if(ofproxy) PpcOfwInit(); 00493 else PpcPrepInit(); 00494 } 00495 00496 void MachInit(const char *CmdLine) { 00497 int i, len; 00498 char *sep; 00499 00500 BootPart[0] = 0; 00501 BootPath[0] = 0; 00502 00503 printf( "Determining boot device: [%s]\n", CmdLine ); 00504 00505 sep = NULL; 00506 for( i = 0; i < strlen(CmdLine); i++ ) { 00507 if( strncmp(CmdLine + i, "boot=", 5) == 0) { 00508 strcpy(BootPart, CmdLine + i + 5); 00509 sep = strchr(BootPart, ','); 00510 if( sep ) 00511 *sep = 0; 00512 while(CmdLine[i] && CmdLine[i]!=',') i++; 00513 } 00514 } 00515 00516 if( strlen(BootPart) == 0 ) { 00517 if (ofproxy) 00518 len = ofw_getprop(chosen_package, "bootpath", 00519 BootPath, sizeof(BootPath)); 00520 else 00521 len = 0; 00522 if( len < 0 ) len = 0; 00523 BootPath[len] = 0; 00524 printf( "Boot Path: %s\n", BootPath ); 00525 00526 sep = strrchr(BootPath, ','); 00527 00528 strcpy(BootPart, BootPath); 00529 if( sep ) { 00530 BootPart[sep - BootPath] = 0; 00531 } 00532 } 00533 00534 printf( "FreeLDR starting (boot partition: %s)\n", BootPart ); 00535 } 00536 00537 void beep() { 00538 } 00539 00540 UCHAR NTAPI READ_PORT_UCHAR(PUCHAR Address) { 00541 return GetPhysByte(((ULONG)Address)+0x80000000); 00542 } 00543 00544 void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value) { 00545 SetPhysByte(((ULONG)Address)+0x80000000, Value); 00546 } 00547 00548 void DiskStopFloppyMotor() { 00549 } 00550 00551 void BootOldLinuxKernel( unsigned long size ) { 00552 ofw_exit(); 00553 } 00554 00555 void BootNewLinuxKernel() { 00556 ofw_exit(); 00557 } 00558 00559 void ChainLoadBiosBootSectorCode() { 00560 ofw_exit(); 00561 } 00562 00563 void DbgBreakPoint() { 00564 __asm__("twi 31,0,0"); 00565 } Generated on Fri May 25 2012 04:17:10 for ReactOS by
1.7.6.1
|