/*++ Copyright (c) 1992 Microsoft Corporation Module Name: entry.c Abstract: EFI specific startup for os loaders Author: John Vert (jvert) 14-Oct-1993 Revision History: --*/ #if defined(_IA64_) #include "bootia64.h" #endif #include "biosdrv.h" #include "efi.h" #include "stdio.h" #include "flop.h" #if 0 #define DBGOUT(x) BlPrint x #define DBGPAUSE while(!GET_KEY()); #else #define DBGOUT(x) #define DBGPAUSE #endif extern VOID AEInitializeStall(); // // Externals // extern EFI_HANDLE EfiImageHandle; extern EFI_SYSTEM_TABLE *EfiST; extern EFI_BOOT_SERVICES *EfiBS; extern EFI_RUNTIME_SERVICES *EfiRS; BOOLEAN GoneVirtual = FALSE; // // Prototypes for Internal Routines // VOID DoGlobalInitialization( PBOOT_CONTEXT ); #if defined(ELTORITO) BOOLEAN ElToritoCDBoot = FALSE; #endif extern CHAR NetBootPath[]; // // Global context pointers. These are passed to us by the SU module or // the bootstrap code. // PCONFIGURATION_COMPONENT_DATA FwConfigurationTree = NULL; PEXTERNAL_SERVICES_TABLE ExternalServicesTable; UCHAR BootPartitionName[129]; ULONG FwHeapUsed = 0; #if defined(NEC_98) ULONG Key; int ArrayDiskStartOrdinal = -1; BOOLEAN BootedFromArrayDisk = FALSE; BOOLEAN HyperScsiAvalable = FALSE; #endif //NEC_98 ULONG MachineType = 0; LONG_PTR OsLoaderBase; LONG_PTR OsLoaderExports; extern PUCHAR BlpResourceDirectory; extern PUCHAR BlpResourceFileOffset; #if DBG extern EFI_SYSTEM_TABLE *EfiST; #define DBG_TRACE(_X) EfiST->ConOut->OutputString(EfiST->ConOut, (_X)) #else #define DBG_TRACE(_X) #endif // for FORCE_CD_BOOT VOID NtProcessStartup( IN PBOOT_CONTEXT BootContextRecord ) /*++ Routine Description: Main entry point for setup loader. Control is transferred here by the start-up (SU) module. Arguments: BootContextRecord - Supplies the boot context, particularly the ExternalServicesTable. Returns: Does not return. Control eventually passed to the kernel. --*/ { PBOOT_DEVICE_ATAPI BootDeviceAtapi; PBOOT_DEVICE_SCSI BootDeviceScsi; PBOOT_DEVICE_FLOPPY BootDeviceFloppy; PBOOT_DEVICE_UNKNOWN BootDeviceUnknown; ARC_STATUS Status; DBG_TRACE(L"NtProcessStart: Entry\r\n"); // // Initialize the boot loader's video // DoGlobalInitialization(BootContextRecord); BlFillInSystemParameters(BootContextRecord); // // Initialize the memory descriptor list, the OS loader heap, and the // OS loader parameter block. // DBG_TRACE( L"NtProcessStartup:about to BlMemoryInitialize\r\n"); Status = BlMemoryInitialize(); if (Status != ESUCCESS) { DBG_TRACE(TEXT("Couldn't initialize memory\r\n")); EfiBS->Exit(EfiImageHandle, Status, 0, 0); } #ifdef FORCE_CD_BOOT DBG_TRACE(L"Forcing BootMediaCdrom\r\n"); BootContextRecord->MediaType = BootMediaCdrom; #endif // for FORCE_CD_BOOT if (BootContextRecord->MediaType == BootMediaFloppyDisk) { // // Boot was from A: // BootDeviceFloppy = (PBOOT_DEVICE_FLOPPY) &(BootContextRecord->BootDevice); sprintf(BootPartitionName, "multi(0)disk(0)fdisk(%u)", BootDeviceFloppy->DriveNumber); } else if (BootContextRecord->MediaType == BootMediaTcpip) { // // Boot was from the net // strcpy(BootPartitionName,"net(0)"); BlBootingFromNet = TRUE; #if defined(ELTORITO) } else if (BootContextRecord->MediaType == BootMediaCdrom) { #ifdef FORCE_CD_BOOT sprintf(BootPartitionName, "multi(0)disk(0)cdrom(%u)", 0 ); ElToritoCDBoot = TRUE; #else // // Boot was from El Torito CD // if( BootContextRecord->BusType == BootBusAtapi ) { BootDeviceAtapi = (PBOOT_DEVICE_ATAPI) &(BootContextRecord->BootDevice); sprintf(BootPartitionName, "multi(0)disk(0)cdrom(%u)", BootDeviceAtapi->Lun); } else if( BootContextRecord->BusType == BootBusScsi ) { BootDeviceScsi = (PBOOT_DEVICE_SCSI) &(BootContextRecord->BootDevice); sprintf(BootPartitionName, "multi(0)disk(0)cdrom(%u)", BootDeviceScsi->Lun); } else if( BootContextRecord->BusType == BootBusVendor ) { BootDeviceUnknown = (PBOOT_DEVICE_UNKNOWN) &(BootContextRecord->BootDevice); sprintf(BootPartitionName, "multi(0)disk(0)cdrom(%u)", 0 ); } ElToritoCDBoot = TRUE; #endif // for FORCE_CD_BOOT #endif // for ELTORITO } else { // // Find the partition we have been booted from. Note that this // is *NOT* necessarily the active partition. If the system has // Boot Mangler installed, it will be the active partition, and // we have to go figure out what partition we are actually on. // if (BootContextRecord->BusType == BootBusAtapi) { BootDeviceAtapi = (PBOOT_DEVICE_ATAPI) &(BootContextRecord->BootDevice); sprintf(BootPartitionName, "multi(0)disk(0)rdisk(%u)partition(%u)", BlGetDriveId(BL_DISKTYPE_ATAPI, (PBOOT_DEVICE)BootDeviceAtapi), // BootDeviceAtapi->Lun, BootContextRecord->PartitionNumber); } else if (BootContextRecord->BusType == BootBusScsi) { BootDeviceScsi = (PBOOT_DEVICE_SCSI) &(BootContextRecord->BootDevice); sprintf(BootPartitionName, "scsi(0)disk(0)rdisk(%u)partition(%u)", BlGetDriveId(BL_DISKTYPE_SCSI, (PBOOT_DEVICE)BootDeviceScsi), //BootDeviceScsi->Pun, BootContextRecord->PartitionNumber); } else if (BootContextRecord->BusType == BootBusVendor) { BootDeviceUnknown = (PBOOT_DEVICE_UNKNOWN) &(BootContextRecord->BootDevice); sprintf(BootPartitionName, "multi(0)disk(0)rdisk(%u)partition(%u)", BlGetDriveId(BL_DISKTYPE_UNKNOWN, (PBOOT_DEVICE)BootDeviceUnknown), //BootDeviceUnknown->LegacyDriveLetter & 0x7F, BootContextRecord->PartitionNumber); } } // // Initialize the OS loader I/O system. // AEInitializeStall(); FlipToPhysical(); DBG_TRACE( L"NtProcessStartup:about to Init I/O\r\n"); FlipToVirtual(); Status = BlIoInitialize(); if (Status != ESUCCESS) { #if DBG BlPrint(TEXT("Couldn't initialize I/O\r\n")); #endif EfiBS->Exit(EfiImageHandle, Status, 0, 0); } // // Call off to regular startup code // FlipToPhysical(); DBG_TRACE( L"NtProcessStartup:about to call BlStartup\r\n"); FlipToVirtual(); BlStartup(BootPartitionName); // // we should never get here! // do { GET_KEY(); } while ( 1 ); } VOID DoGlobalInitialization( IN PBOOT_CONTEXT BootContextRecord ) /*++ Routine Description This routine calls all of the subsytem initialization routines. Arguments: None Returns: Nothing --*/ { ARC_STATUS Status; // // Set base address of OS Loader image for the debugger. // OsLoaderBase = BootContextRecord->OsLoaderBase; OsLoaderExports = BootContextRecord->OsLoaderExports; // // Initialize memory. // Status = InitializeMemorySubsystem(BootContextRecord); if (Status != ESUCCESS) { #if DBG BlPrint(TEXT("InitializeMemory failed %lx\r\n"),Status); #endif EfiBS->Exit(EfiImageHandle, Status, 0, 0); } ExternalServicesTable=BootContextRecord->ExternalServicesTable; MachineType = (ULONG) BootContextRecord->MachineType; // // Turn the cursor off // // bugbug EFI //HW_CURSOR(0,127); FlipToPhysical(); DBG_TRACE( L"DoGlobalInitialization: cursor off\r\n"); EfiST->ConOut->EnableCursor(EfiST->ConOut, FALSE); FlipToVirtual(); BlpResourceDirectory = (PUCHAR)(BootContextRecord->ResourceDirectory); BlpResourceFileOffset = (PUCHAR)(BootContextRecord->ResourceOffset); OsLoaderBase = BootContextRecord->OsLoaderBase; OsLoaderExports = BootContextRecord->OsLoaderExports; }