/** This function initialize basic context for FRM. **/ VOID InitBasicContext ( VOID ) { UINT32 RegEax; mHostContextCommon.CpuNum = GetCpuNumFromAcpi (); GetPciExpressInfoFromAcpi (&mHostContextCommon.PciExpressBaseAddress, &mHostContextCommon.PciExpressLength); PcdSet64 (PcdPciExpressBaseAddress, mHostContextCommon.PciExpressBaseAddress); if (mHostContextCommon.PciExpressBaseAddress == 0) { CpuDeadLoop (); } mHostContextCommon.AcpiTimerIoPortBaseAddress = GetAcpiTimerPort (&mHostContextCommon.AcpiTimerWidth); PcdSet16 (PcdAcpiTimerIoPortBaseAddress, mHostContextCommon.AcpiTimerIoPortBaseAddress); PcdSet8 (PcdAcpiTimerWidth, mHostContextCommon.AcpiTimerWidth); if (mHostContextCommon.AcpiTimerIoPortBaseAddress == 0) { CpuDeadLoop (); } mHostContextCommon.ResetIoPortBaseAddress = GetAcpiResetPort (); mHostContextCommon.AcpiPmControlIoPortBaseAddress = GetAcpiPmControlPort (); if (mHostContextCommon.AcpiPmControlIoPortBaseAddress == 0) { CpuDeadLoop (); } mHostContextCommon.HostContextPerCpu = AllocatePages (FRM_SIZE_TO_PAGES(sizeof(FRM_HOST_CONTEXT_PER_CPU)) * mHostContextCommon.CpuNum); mGuestContextCommon.GuestContextPerCpu = AllocatePages (FRM_SIZE_TO_PAGES(sizeof(FRM_GUEST_CONTEXT_PER_CPU)) * mHostContextCommon.CpuNum); mHostContextCommon.LowMemoryBase = mCommunicationData.LowMemoryBase; mHostContextCommon.LowMemorySize = mCommunicationData.LowMemorySize; mHostContextCommon.LowMemoryBackupBase = (UINT64)(UINTN)AllocatePages (FRM_SIZE_TO_PAGES ((UINTN)mCommunicationData.LowMemorySize)); // // Save current context // mBspIndex = ApicToIndex (ReadLocalApicId ()); mGuestContextCommon.GuestContextPerCpu[mBspIndex].Cr0 = AsmReadCr0 (); mGuestContextCommon.GuestContextPerCpu[mBspIndex].Cr3 = AsmReadCr3 (); mGuestContextCommon.GuestContextPerCpu[mBspIndex].Cr4 = AsmReadCr4 (); AsmReadGdtr (&mGuestContextCommon.GuestContextPerCpu[mBspIndex].Gdtr); AsmReadIdtr (&mGuestContextCommon.GuestContextPerCpu[mBspIndex].Idtr); AsmCpuid (CPUID_EXTENDED_INFORMATION, &RegEax, NULL, NULL, NULL); if (RegEax >= CPUID_EXTENDED_ADDRESS_SIZE) { AsmCpuid (CPUID_EXTENDED_ADDRESS_SIZE, &RegEax, NULL, NULL, NULL); mHostContextCommon.PhysicalAddressBits = (UINT8)RegEax; } else { mHostContextCommon.PhysicalAddressBits = 36; } }
/** Do the platform init, can be customized by OEM/IBV Possible things that can be done in PlatformBootManagerBeforeConsole: > Update console variable: 1. include hot-plug devices; > 2. Clear ConIn and add SOL for AMT > Register new Driver#### or Boot#### > Register new Key####: e.g.: F12 > Signal ReadyToLock event > Authentication action: 1. connect Auth devices; > 2. Identify auto logon user. **/ VOID EFIAPI PlatformBootManagerBeforeConsole ( VOID ) { // // Signal EndOfDxe PI Event // EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid); // // Locate the PCI root bridges and make the PCI bus driver connect each, // non-recursively. This will produce a number of child handles with PciIo on // them. // FilterAndProcess (&gEfiPciRootBridgeIoProtocolGuid, NULL, Connect); // // Signal the ACPI platform driver that it can download QEMU ACPI tables. // EfiEventGroupSignal (&gRootBridgesConnectedEventGroupGuid); // // Find all display class PCI devices (using the handles from the previous // step), and connect them non-recursively. This should produce a number of // child handles with GOPs on them. // FilterAndProcess (&gEfiPciIoProtocolGuid, IsPciDisplay, Connect); // // Now add the device path of all handles with GOP on them to ConOut and // ErrOut. // FilterAndProcess (&gEfiGraphicsOutputProtocolGuid, NULL, AddOutput); // // Add the hardcoded short-form USB keyboard device path to ConIn. // EfiBootManagerUpdateConsoleVariable (ConIn, (EFI_DEVICE_PATH_PROTOCOL *)&mUsbKeyboard, NULL); // // Add the hardcoded serial console device path to ConIn, ConOut, ErrOut. // CopyGuid (&mSerialConsole.TermType.Guid, PcdGetPtr (PcdTerminalTypeGuidBuffer)); EfiBootManagerUpdateConsoleVariable (ConIn, (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL); EfiBootManagerUpdateConsoleVariable (ConOut, (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL); EfiBootManagerUpdateConsoleVariable (ErrOut, (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL); // // Set the front page timeout from the QEMU configuration. // PcdSet16 (PcdPlatformBootTimeOut, GetFrontPageTimeoutFromQemu ()); // // Register platform-specific boot options and keyboard shortcuts. // PlatformRegisterOptionsAndKeys (); }
VOID MiscInitialization ( VOID ) { UINTN PmCmd; UINTN Pmba; UINTN AcpiCtlReg; UINT8 AcpiEnBit; // // Disable A20 Mask // IoOr8 (0x92, BIT1); // // Build the CPU HOB with guest RAM size dependent address width and 16-bits // of IO space. (Side note: unlike other HOBs, the CPU HOB is needed during // S3 resume as well, so we build it unconditionally.) // BuildCpuHob (mPhysMemAddressWidth, 16); // // Determine platform type and save Host Bridge DID to PCD // switch (mHostBridgeDevId) { case INTEL_82441_DEVICE_ID: PmCmd = POWER_MGMT_REGISTER_PIIX4 (PCI_COMMAND_OFFSET); Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA); AcpiCtlReg = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMREGMISC); AcpiEnBit = PIIX4_PMREGMISC_PMIOSE; break; case INTEL_Q35_MCH_DEVICE_ID: PmCmd = POWER_MGMT_REGISTER_Q35 (PCI_COMMAND_OFFSET); Pmba = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE); AcpiCtlReg = POWER_MGMT_REGISTER_Q35 (ICH9_ACPI_CNTL); AcpiEnBit = ICH9_ACPI_CNTL_ACPI_EN; break; default: DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n", __FUNCTION__, mHostBridgeDevId)); ASSERT (FALSE); return; } PcdSet16 (PcdOvmfHostBridgePciDevId, mHostBridgeDevId); // // If the appropriate IOspace enable bit is set, assume the ACPI PMBA // has been configured (e.g., by Xen) and skip the setup here. // This matches the logic in AcpiTimerLibConstructor (). // if ((PciRead8 (AcpiCtlReg) & AcpiEnBit) == 0) { // // The PEI phase should be exited with fully accessibe ACPI PM IO space: // 1. set PMBA // PciAndThenOr32 (Pmba, (UINT32) ~0xFFC0, PcdGet16 (PcdAcpiPmBaseAddress)); // // 2. set PCICMD/IOSE // PciOr8 (PmCmd, EFI_PCI_COMMAND_IO_SPACE); // // 3. set ACPI PM IO enable bit (PMREGMISC:PMIOSE or ACPI_CNTL:ACPI_EN) // PciOr8 (AcpiCtlReg, AcpiEnBit); } if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) { // // Set Root Complex Register Block BAR // PciWrite32 ( POWER_MGMT_REGISTER_Q35 (ICH9_RCBA), ICH9_ROOT_COMPLEX_BASE | ICH9_RCBA_EN ); // // Set PCI Express Register Range Base Address // PciExBarInitialization (); } }
/** Function handling request to apply changes for BMM pages. @param Private Pointer to callback data buffer. @param CurrentFakeNVMap Pointer to buffer holding data of various values used by BMM @param FormId ID of the form which has sent the request to apply change. @retval EFI_SUCCESS Change successfully applied. @retval Other Error occurs while trying to apply changes. **/ EFI_STATUS ApplyChangeHandler ( IN BMM_CALLBACK_DATA *Private, IN BMM_FAKE_NV_DATA *CurrentFakeNVMap, IN EFI_FORM_ID FormId ) { BM_CONSOLE_CONTEXT *NewConsoleContext; BM_TERMINAL_CONTEXT *NewTerminalContext; BM_LOAD_CONTEXT *NewLoadContext; BM_MENU_ENTRY *NewMenuEntry; EFI_STATUS Status; UINT16 Index; Status = EFI_SUCCESS; switch (FormId) { case FORM_SET_FD_ORDER_ID: case FORM_SET_HD_ORDER_ID: case FORM_SET_CD_ORDER_ID: case FORM_SET_NET_ORDER_ID: case FORM_SET_BEV_ORDER_ID: Var_UpdateBBSOption (Private); break; case FORM_BOOT_DEL_ID: for (Index = 0; ((Index < BootOptionMenu.MenuNumber) && (Index < (sizeof (CurrentFakeNVMap->BootOptionDel) / sizeof (UINT8)))); Index ++) { NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index); NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext; NewLoadContext->Deleted = CurrentFakeNVMap->BootOptionDel[Index]; } Var_DelBootOption (); break; case FORM_DRV_DEL_ID: for (Index = 0; ((Index < DriverOptionMenu.MenuNumber) && (Index < (sizeof (CurrentFakeNVMap->DriverOptionDel) / sizeof (UINT8)))); Index++) { NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index); NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext; NewLoadContext->Deleted = CurrentFakeNVMap->DriverOptionDel[Index]; } Var_DelDriverOption (); break; case FORM_BOOT_CHG_ID: Status = Var_UpdateBootOrder (Private); break; case FORM_DRV_CHG_ID: Status = Var_UpdateDriverOrder (Private); break; case FORM_TIME_OUT_ID: PcdSet16 (PcdPlatformBootTimeOut, CurrentFakeNVMap->BootTimeOut); Private->BmmOldFakeNVData.BootTimeOut = CurrentFakeNVMap->BootTimeOut; break; case FORM_BOOT_NEXT_ID: Status = Var_UpdateBootNext (Private); break; case FORM_CON_MODE_ID: Status = Var_UpdateConMode (Private); break; case FORM_CON_COM_SETUP_ID: NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Private->CurrentTerminal); ASSERT (NewMenuEntry != NULL); NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext; NewTerminalContext->BaudRateIndex = CurrentFakeNVMap->COMBaudRate; ASSERT (CurrentFakeNVMap->COMBaudRate < (sizeof (BaudRateList) / sizeof (BaudRateList[0]))); NewTerminalContext->BaudRate = BaudRateList[CurrentFakeNVMap->COMBaudRate].Value; NewTerminalContext->DataBitsIndex = CurrentFakeNVMap->COMDataRate; ASSERT (CurrentFakeNVMap->COMDataRate < (sizeof (DataBitsList) / sizeof (DataBitsList[0]))); NewTerminalContext->DataBits = (UINT8) DataBitsList[CurrentFakeNVMap->COMDataRate].Value; NewTerminalContext->StopBitsIndex = CurrentFakeNVMap->COMStopBits; ASSERT (CurrentFakeNVMap->COMStopBits < (sizeof (StopBitsList) / sizeof (StopBitsList[0]))); NewTerminalContext->StopBits = (UINT8) StopBitsList[CurrentFakeNVMap->COMStopBits].Value; NewTerminalContext->ParityIndex = CurrentFakeNVMap->COMParity; ASSERT (CurrentFakeNVMap->COMParity < (sizeof (ParityList) / sizeof (ParityList[0]))); NewTerminalContext->Parity = (UINT8) ParityList[CurrentFakeNVMap->COMParity].Value; NewTerminalContext->TerminalType = CurrentFakeNVMap->COMTerminalType; ChangeTerminalDevicePath ( NewTerminalContext->DevicePath, FALSE ); Var_UpdateConsoleInpOption (); Var_UpdateConsoleOutOption (); Var_UpdateErrorOutOption (); break; case FORM_CON_IN_ID: for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) { NewMenuEntry = BOpt_GetMenuEntry (&ConsoleInpMenu, Index); NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext; ASSERT (Index < MAX_MENU_NUMBER); NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index]; } for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) { NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index); NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext; ASSERT (Index + ConsoleInpMenu.MenuNumber < MAX_MENU_NUMBER); NewTerminalContext->IsConIn = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleInpMenu.MenuNumber]; } Var_UpdateConsoleInpOption (); break; case FORM_CON_OUT_ID: for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) { NewMenuEntry = BOpt_GetMenuEntry (&ConsoleOutMenu, Index); NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext; ASSERT (Index < MAX_MENU_NUMBER); NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index]; } for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) { NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index); NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext; ASSERT (Index + ConsoleOutMenu.MenuNumber < MAX_MENU_NUMBER); NewTerminalContext->IsConOut = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleOutMenu.MenuNumber]; } Var_UpdateConsoleOutOption (); break; case FORM_CON_ERR_ID: for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) { NewMenuEntry = BOpt_GetMenuEntry (&ConsoleErrMenu, Index); NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext; ASSERT (Index < MAX_MENU_NUMBER); NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index]; } for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) { NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index); NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext; ASSERT (Index + ConsoleErrMenu.MenuNumber < MAX_MENU_NUMBER); NewTerminalContext->IsStdErr = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleErrMenu.MenuNumber]; } Var_UpdateErrorOutOption (); break; case FORM_DRV_ADD_HANDLE_DESC_ID: Status = Var_UpdateDriverOption ( Private, Private->BmmHiiHandle, CurrentFakeNVMap->DriverAddHandleDesc, CurrentFakeNVMap->DriverAddHandleOptionalData, CurrentFakeNVMap->DriverAddForceReconnect ); if (EFI_ERROR (Status)) { goto Error; } BOpt_GetDriverOptions (Private); CreateMenuStringToken (Private, Private->BmmHiiHandle, &DriverOptionMenu); break; default: break; } Error: return Status; }