ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

mach.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.