Move BdsDxe and GenericBdsLib to IntelFrameworkModulePkg, these modules need dependent on gEfiLegacyBiosProtocol to provide legacy boot support. But legacy boot is not described by PI/UEFI specification.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@7354 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
klu2 2009-01-23 07:24:55 +00:00
parent c516c7178a
commit 5c08e11737
51 changed files with 23764 additions and 2 deletions

View File

@ -56,6 +56,15 @@
S3Lib|IntelFrameworkModulePkg/Library/PeiS3Lib/PeiS3Lib.inf
RecoveryLib|IntelFrameworkModulePkg/Library/PeiRecoveryLib/PeiRecoveryLib.inf
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
IfrSupportLib|MdeModulePkg/Library/UefiIfrSupportLib/UefiIfrSupportLib.inf
ExtendedIfrSupportLib|MdeModulePkg/Library/ExtendedIfrSupportLib/ExtendedIfrSupportLib.inf
GenericBdsLib|IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
ExtendedHiiLib|MdeModulePkg/Library/ExtendedHiiLib/ExtendedHiiLib.inf
PlatformBdsLib|MdeModulePkg/Library/PlatformBdsLibNull/PlatformBdsLibNull.inf
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
[LibraryClasses.common.PEIM]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
@ -190,7 +199,8 @@
IntelFrameworkModulePkg/Library/SmmRuntimeDxeReportStatusCodeLibFramework/SmmRuntimeDxeReportStatusCodeLibFramework.inf
IntelFrameworkModulePkg/Library/BaseReportStatusCodeLib/BaseReportStatusCodeLib.inf
IntelFrameworkModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf
IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBusDxe.inf
IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBusDxe.inf
@ -209,7 +219,8 @@
IntelFrameworkModulePkg/Universal/PcatSingleSegmentPciCfgPei/PcatSingleSegmentPciCfgPei.inf
IntelFrameworkModulePkg/Universal/VariablePei/VariablePei.inf
IntelFrameworkModulePkg/Universal/Legacy8259Dxe/8259.inf
IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf
[Components.IA32]
IntelFrameworkModulePkg/Universal/StatusCode/Dxe/DxeStatusCode.inf

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,415 @@
/** @file
BDS Lib functions which relate with connect the device
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "InternalBdsLib.h"
/**
This function will connect all the system driver to controller
first, and then special connect the default console, this make
sure all the system controller available and the platform default
console connected.
**/
VOID
EFIAPI
BdsLibConnectAll (
VOID
)
{
//
// Connect the platform console first
//
BdsLibConnectAllDefaultConsoles ();
//
// Generic way to connect all the drivers
//
BdsLibConnectAllDriversToAllControllers ();
//
// Here we have the assumption that we have already had
// platform default console
//
BdsLibConnectAllDefaultConsoles ();
}
/**
This function will connect all the system drivers to all controllers
first, and then connect all the console devices the system current
have. After this we should get all the device work and console available
if the system have console device.
**/
VOID
BdsLibGenericConnectAll (
VOID
)
{
//
// Most generic way to connect all the drivers
//
BdsLibConnectAllDriversToAllControllers ();
BdsLibConnectAllConsoles ();
}
/**
This function will create all handles associate with every device
path node. If the handle associate with one device path node can not
be created success, then still give one chance to do the dispatch,
which load the missing drivers if possible.
@param DevicePathToConnect The device path which will be connected, it can be
a multi-instance device path
@retval EFI_SUCCESS All handles associate with every device path node
have been created
@retval EFI_OUT_OF_RESOURCES There is no resource to create new handles
@retval EFI_NOT_FOUND Create the handle associate with one device path
node failed
**/
EFI_STATUS
EFIAPI
BdsLibConnectDevicePath (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePathToConnect
)
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath;
EFI_DEVICE_PATH_PROTOCOL *Instance;
EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;
EFI_DEVICE_PATH_PROTOCOL *Next;
EFI_HANDLE Handle;
EFI_HANDLE PreviousHandle;
UINTN Size;
if (DevicePathToConnect == NULL) {
return EFI_SUCCESS;
}
DevicePath = DuplicateDevicePath (DevicePathToConnect);
if (DevicePath == NULL) {
return EFI_OUT_OF_RESOURCES;
}
CopyOfDevicePath = DevicePath;
do {
//
// The outer loop handles multi instance device paths.
// Only console variables contain multiple instance device paths.
//
// After this call DevicePath points to the next Instance
//
Instance = GetNextDevicePathInstance (&DevicePath, &Size);
if (Instance == NULL) {
FreePool (CopyOfDevicePath);
return EFI_OUT_OF_RESOURCES;
}
Next = Instance;
while (!IsDevicePathEndType (Next)) {
Next = NextDevicePathNode (Next);
}
SetDevicePathEndNode (Next);
//
// Start the real work of connect with RemainingDevicePath
//
PreviousHandle = NULL;
do {
//
// Find the handle that best matches the Device Path. If it is only a
// partial match the remaining part of the device path is returned in
// RemainingDevicePath.
//
RemainingDevicePath = Instance;
Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &Handle);
if (!EFI_ERROR (Status)) {
if (Handle == PreviousHandle) {
//
// If no forward progress is made try invoking the Dispatcher.
// A new FV may have been added to the system an new drivers
// may now be found.
// Status == EFI_SUCCESS means a driver was dispatched
// Status == EFI_NOT_FOUND means no new drivers were dispatched
//
Status = gDS->Dispatch ();
}
if (!EFI_ERROR (Status)) {
PreviousHandle = Handle;
//
// Connect all drivers that apply to Handle and RemainingDevicePath,
// the Recursive flag is FALSE so only one level will be expanded.
//
// Do not check the connect status here, if the connect controller fail,
// then still give the chance to do dispatch, because partial
// RemainingDevicepath may be in the new FV
//
// 1. If the connect fail, RemainingDevicepath and handle will not
// change, so next time will do the dispatch, then dispatch's status
// will take effect
// 2. If the connect success, the RemainingDevicepath and handle will
// change, then avoid the dispatch, we have chance to continue the
// next connection
//
gBS->ConnectController (Handle, NULL, RemainingDevicePath, FALSE);
}
}
//
// Loop until RemainingDevicePath is an empty device path
//
} while (!EFI_ERROR (Status) && !IsDevicePathEnd (RemainingDevicePath));
} while (DevicePath != NULL);
if (CopyOfDevicePath != NULL) {
FreePool (CopyOfDevicePath);
}
//
// All handle with DevicePath exists in the handle database
//
return Status;
}
/**
This function will connect all current system handles recursively. The
connection will finish until every handle's child handle created if it have.
@retval EFI_SUCCESS All handles and it's child handle have been
connected
@retval EFI_STATUS Return the status of gBS->LocateHandleBuffer().
**/
EFI_STATUS
EFIAPI
BdsLibConnectAllEfi (
VOID
)
{
EFI_STATUS Status;
UINTN HandleCount;
EFI_HANDLE *HandleBuffer;
UINTN Index;
Status = gBS->LocateHandleBuffer (
AllHandles,
NULL,
NULL,
&HandleCount,
&HandleBuffer
);
if (EFI_ERROR (Status)) {
return Status;
}
for (Index = 0; Index < HandleCount; Index++) {
Status = gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
}
if (HandleBuffer != NULL) {
FreePool (HandleBuffer);
}
return EFI_SUCCESS;
}
/**
This function will disconnect all current system handles. The disconnection
will finish until every handle have been disconnected.
@retval EFI_SUCCESS All handles have been disconnected
@retval EFI_STATUS Return the status of gBS->LocateHandleBuffer().
**/
EFI_STATUS
EFIAPI
BdsLibDisconnectAllEfi (
VOID
)
{
EFI_STATUS Status;
UINTN HandleCount;
EFI_HANDLE *HandleBuffer;
UINTN Index;
//
// Disconnect all
//
Status = gBS->LocateHandleBuffer (
AllHandles,
NULL,
NULL,
&HandleCount,
&HandleBuffer
);
if (EFI_ERROR (Status)) {
return Status;
}
for (Index = 0; Index < HandleCount; Index++) {
Status = gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
}
if (HandleBuffer != NULL) {
FreePool (HandleBuffer);
}
return EFI_SUCCESS;
}
/**
Connects all drivers to all controllers.
This function make sure all the current system driver will manage
the correspoinding controllers if have. And at the same time, make
sure all the system controllers have driver to manage it if have.
**/
VOID
EFIAPI
BdsLibConnectAllDriversToAllControllers (
VOID
)
{
EFI_STATUS Status;
do {
//
// Connect All EFI 1.10 drivers following EFI 1.10 algorithm
//
BdsLibConnectAllEfi ();
//
// Check to see if it's possible to dispatch an more DXE drivers.
// The BdsLibConnectAllEfi () may have made new DXE drivers show up.
// If anything is Dispatched Status == EFI_SUCCESS and we will try
// the connect again.
//
Status = gDS->Dispatch ();
} while (!EFI_ERROR (Status));
}
/**
Connect the specific Usb device which match the short form device path,
and whose bus is determined by Host Controller (Uhci or Ehci).
@param HostControllerPI Uhci (0x00) or Ehci (0x20) or Both uhci and ehci
(0xFF)
@param RemainingDevicePath a short-form device path that starts with the first
element being a USB WWID or a USB Class device
path
@return EFI_INVALID_PARAMETER RemainingDevicePath is NULL pointer.
RemainingDevicePath is not a USB device path.
Invalid HostControllerPI type.
@return EFI_SUCCESS Success to connect USB device
@return EFI_NOT_FOUND Fail to find handle for USB controller to connect.
**/
EFI_STATUS
EFIAPI
BdsLibConnectUsbDevByShortFormDP(
IN UINT8 HostControllerPI,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
{
EFI_STATUS Status;
EFI_HANDLE *HandleArray;
UINTN HandleArrayCount;
UINTN Index;
EFI_PCI_IO_PROTOCOL *PciIo;
UINT8 Class[3];
BOOLEAN AtLeastOneConnected;
//
// Check the passed in parameters
//
if (RemainingDevicePath == NULL) {
return EFI_INVALID_PARAMETER;
}
if ((DevicePathType (RemainingDevicePath) != MESSAGING_DEVICE_PATH) ||
((DevicePathSubType (RemainingDevicePath) != MSG_USB_CLASS_DP)
&& (DevicePathSubType (RemainingDevicePath) != MSG_USB_WWID_DP)
)) {
return EFI_INVALID_PARAMETER;
}
if (HostControllerPI != 0xFF &&
HostControllerPI != 0x00 &&
HostControllerPI != 0x20) {
return EFI_INVALID_PARAMETER;
}
//
// Find the usb host controller firstly, then connect with the remaining device path
//
AtLeastOneConnected = FALSE;
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiPciIoProtocolGuid,
NULL,
&HandleArrayCount,
&HandleArray
);
if (!EFI_ERROR (Status)) {
for (Index = 0; Index < HandleArrayCount; Index++) {
Status = gBS->HandleProtocol (
HandleArray[Index],
&gEfiPciIoProtocolGuid,
(VOID **)&PciIo
);
if (!EFI_ERROR (Status)) {
//
// Check whether the Pci device is the wanted usb host controller
//
Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x09, 3, &Class);
if (!EFI_ERROR (Status)) {
if ((PCI_CLASS_SERIAL == Class[2]) &&
(PCI_CLASS_SERIAL_USB == Class[1])) {
if (HostControllerPI == Class[0] || HostControllerPI == 0xFF) {
Status = gBS->ConnectController (
HandleArray[Index],
NULL,
RemainingDevicePath,
FALSE
);
if (!EFI_ERROR(Status)) {
AtLeastOneConnected = TRUE;
}
}
}
}
}
}
if (AtLeastOneConnected) {
return EFI_SUCCESS;
}
}
return EFI_NOT_FOUND;
}

View File

@ -0,0 +1,901 @@
/** @file
BDS Lib functions which contain all the code to connect console device
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "InternalBdsLib.h"
/**
Check if we need to save the EFI variable with "ConVarName" as name
as NV type
@param ConVarName The name of the EFI variable.
@retval TRUE Set the EFI variable as NV type.
@retval FALSE EFI variable as NV type can be set NonNV.
**/
BOOLEAN
IsNvNeed (
IN CHAR16 *ConVarName
)
{
CHAR16 *Ptr;
Ptr = ConVarName;
//
// If the variable includes "Dev" at last, we consider
// it does not support NV attribute.
//
while (*Ptr != L'\0') {
Ptr++;
}
if ((*(Ptr - 3) == 'D') && (*(Ptr - 2) == 'e') && (*(Ptr - 1) == 'v')) {
return FALSE;
} else {
return TRUE;
}
}
/**
This function update console variable based on ConVarName, it can
add or remove one specific console device path from the variable
@param ConVarName Console related variable name, ConIn, ConOut,
ErrOut.
@param CustomizedConDevicePath The console device path which will be added to
the console variable ConVarName, this parameter
can not be multi-instance.
@param ExclusiveDevicePath The console device path which will be removed
from the console variable ConVarName, this
parameter can not be multi-instance.
@retval EFI_UNSUPPORTED The added device path is same to the removed one.
@retval EFI_SUCCESS Success add or remove the device path from the
console variable.
**/
EFI_STATUS
EFIAPI
BdsLibUpdateConsoleVariable (
IN CHAR16 *ConVarName,
IN EFI_DEVICE_PATH_PROTOCOL *CustomizedConDevicePath,
IN EFI_DEVICE_PATH_PROTOCOL *ExclusiveDevicePath
)
{
EFI_DEVICE_PATH_PROTOCOL *VarConsole;
UINTN DevicePathSize;
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath;
UINT32 Attributes;
VarConsole = NULL;
DevicePathSize = 0;
//
// Notes: check the device path point, here should check
// with compare memory
//
if (CustomizedConDevicePath == ExclusiveDevicePath) {
return EFI_UNSUPPORTED;
}
//
// Delete the ExclusiveDevicePath from current default console
//
VarConsole = BdsLibGetVariableAndSize (
ConVarName,
&gEfiGlobalVariableGuid,
&DevicePathSize
);
//
// Initialize NewDevicePath
//
NewDevicePath = VarConsole;
//
// If ExclusiveDevicePath is even the part of the instance in VarConsole, delete it.
// In the end, NewDevicePath is the final device path.
//
if (ExclusiveDevicePath != NULL && VarConsole != NULL) {
NewDevicePath = BdsLibDelPartMatchInstance (VarConsole, ExclusiveDevicePath);
}
//
// Try to append customized device path to NewDevicePath.
//
if (CustomizedConDevicePath != NULL) {
if (!BdsLibMatchDevicePaths (NewDevicePath, CustomizedConDevicePath)) {
//
// Check if there is part of CustomizedConDevicePath in NewDevicePath, delete it.
//
NewDevicePath = BdsLibDelPartMatchInstance (NewDevicePath, CustomizedConDevicePath);
//
// In the first check, the default console variable will be _ModuleEntryPoint,
// just append current customized device path
//
TempNewDevicePath = NewDevicePath;
NewDevicePath = AppendDevicePathInstance (NewDevicePath, CustomizedConDevicePath);
if (TempNewDevicePath != NULL) {
FreePool(TempNewDevicePath);
}
}
}
//
// The attribute for ConInDev, ConOutDev and ErrOutDev does not include NV.
//
if (IsNvNeed(ConVarName)) {
//
// ConVarName has NV attribute.
//
Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;
} else {
//
// ConVarName does not have NV attribute.
//
Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
}
//
// Finally, Update the variable of the default console by NewDevicePath
//
gRT->SetVariable (
ConVarName,
&gEfiGlobalVariableGuid,
Attributes,
GetDevicePathSize (NewDevicePath),
NewDevicePath
);
if (VarConsole == NewDevicePath) {
if (VarConsole != NULL) {
FreePool(VarConsole);
}
} else {
if (VarConsole != NULL) {
FreePool(VarConsole);
}
if (NewDevicePath != NULL) {
FreePool(NewDevicePath);
}
}
return EFI_SUCCESS;
}
/**
Connect the console device base on the variable ConVarName, if
device path of the ConVarName is multi-instance device path, if
anyone of the instances is connected success, then this function
will return success.
@param ConVarName Console related variable name, ConIn, ConOut,
ErrOut.
@retval EFI_NOT_FOUND There is not any console devices connected
success
@retval EFI_SUCCESS Success connect any one instance of the console
device path base on the variable ConVarName.
**/
EFI_STATUS
EFIAPI
BdsLibConnectConsoleVariable (
IN CHAR16 *ConVarName
)
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *StartDevicePath;
UINTN VariableSize;
EFI_DEVICE_PATH_PROTOCOL *Instance;
EFI_DEVICE_PATH_PROTOCOL *Next;
EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath;
UINTN Size;
BOOLEAN DeviceExist;
Status = EFI_SUCCESS;
DeviceExist = FALSE;
//
// Check if the console variable exist
//
StartDevicePath = BdsLibGetVariableAndSize (
ConVarName,
&gEfiGlobalVariableGuid,
&VariableSize
);
if (StartDevicePath == NULL) {
return EFI_UNSUPPORTED;
}
CopyOfDevicePath = StartDevicePath;
do {
//
// Check every instance of the console variable
//
Instance = GetNextDevicePathInstance (&CopyOfDevicePath, &Size);
if (Instance == NULL) {
FreePool (StartDevicePath);
return EFI_UNSUPPORTED;
}
Next = Instance;
while (!IsDevicePathEndType (Next)) {
Next = NextDevicePathNode (Next);
}
SetDevicePathEndNode (Next);
//
// Check USB1.1 console
//
if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) &&
((DevicePathSubType (Instance) == MSG_USB_CLASS_DP)
|| (DevicePathSubType (Instance) == MSG_USB_WWID_DP)
)) {
//
// Check the Usb console in Usb2.0 bus firstly, then Usb1.1 bus
//
Status = BdsLibConnectUsbDevByShortFormDP (PCI_CLASSC_PI_EHCI, Instance);
if (!EFI_ERROR (Status)) {
DeviceExist = TRUE;
}
Status = BdsLibConnectUsbDevByShortFormDP (PCI_CLASSC_PI_UHCI, Instance);
if (!EFI_ERROR (Status)) {
DeviceExist = TRUE;
}
} else {
//
// Connect the instance device path
//
Status = BdsLibConnectDevicePath (Instance);
if (EFI_ERROR (Status)) {
//
// Delete the instance from the console varialbe
//
BdsLibUpdateConsoleVariable (ConVarName, NULL, Instance);
} else {
DeviceExist = TRUE;
}
}
FreePool(Instance);
} while (CopyOfDevicePath != NULL);
FreePool (StartDevicePath);
if (!DeviceExist) {
return EFI_NOT_FOUND;
}
return EFI_SUCCESS;
}
/**
This function will search every simpletext device in current system,
and make every simpletext device as pertantial console device.
**/
VOID
EFIAPI
BdsLibConnectAllConsoles (
VOID
)
{
UINTN Index;
EFI_DEVICE_PATH_PROTOCOL *ConDevicePath;
UINTN HandleCount;
EFI_HANDLE *HandleBuffer;
Index = 0;
HandleCount = 0;
HandleBuffer = NULL;
ConDevicePath = NULL;
//
// Update all the console variables
//
gBS->LocateHandleBuffer (
ByProtocol,
&gEfiSimpleTextInProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer
);
for (Index = 0; Index < HandleCount; Index++) {
gBS->HandleProtocol (
HandleBuffer[Index],
&gEfiDevicePathProtocolGuid,
(VOID **) &ConDevicePath
);
BdsLibUpdateConsoleVariable (L"ConIn", ConDevicePath, NULL);
}
if (HandleBuffer != NULL) {
FreePool(HandleBuffer);
HandleBuffer = NULL;
}
gBS->LocateHandleBuffer (
ByProtocol,
&gEfiSimpleTextOutProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer
);
for (Index = 0; Index < HandleCount; Index++) {
gBS->HandleProtocol (
HandleBuffer[Index],
&gEfiDevicePathProtocolGuid,
(VOID **) &ConDevicePath
);
BdsLibUpdateConsoleVariable (L"ConOut", ConDevicePath, NULL);
BdsLibUpdateConsoleVariable (L"ErrOut", ConDevicePath, NULL);
}
if (HandleBuffer != NULL) {
FreePool(HandleBuffer);
}
//
// Connect all console variables
//
BdsLibConnectAllDefaultConsoles ();
}
/**
This function will connect console device base on the console
device variable ConIn, ConOut and ErrOut.
@retval EFI_SUCCESS At least one of the ConIn and ConOut device have
been connected success.
@retval EFI_STATUS Return the status of BdsLibConnectConsoleVariable ().
**/
EFI_STATUS
EFIAPI
BdsLibConnectAllDefaultConsoles (
VOID
)
{
EFI_STATUS Status;
//
// Connect all default console variables
//
//
// It seems impossible not to have any ConOut device on platform,
// so we check the status here.
//
Status = BdsLibConnectConsoleVariable (L"ConOut");
if (EFI_ERROR (Status)) {
return Status;
}
//
// Insert the performance probe for Console Out
//
PERF_START (NULL, "ConOut", "BDS", 1);
PERF_END (NULL, "ConOut", "BDS", 0);
//
// Because possibly the platform is legacy free, in such case,
// ConIn devices (Serial Port and PS2 Keyboard ) does not exist,
// so we need not check the status.
//
BdsLibConnectConsoleVariable (L"ConIn");
//
// The _ModuleEntryPoint err out var is legal.
//
BdsLibConnectConsoleVariable (L"ErrOut");
return EFI_SUCCESS;
}
/**
Convert a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer
is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt
buffer is passed in it will be used if it is big enough.
@param BmpImage Pointer to BMP file
@param BmpImageSize Number of bytes in BmpImage
@param GopBlt Buffer containing GOP version of BmpImage.
@param GopBltSize Size of GopBlt in bytes.
@param PixelHeight Height of GopBlt/BmpImage in pixels
@param PixelWidth Width of GopBlt/BmpImage in pixels
@retval EFI_SUCCESS GopBlt and GopBltSize are returned.
@retval EFI_UNSUPPORTED BmpImage is not a valid *.BMP image
@retval EFI_BUFFER_TOO_SMALL The passed in GopBlt buffer is not big enough.
GopBltSize will contain the required size.
@retval EFI_OUT_OF_RESOURCES No enough buffer to allocate.
**/
EFI_STATUS
ConvertBmpToGopBlt (
IN VOID *BmpImage,
IN UINTN BmpImageSize,
IN OUT VOID **GopBlt,
IN OUT UINTN *GopBltSize,
OUT UINTN *PixelHeight,
OUT UINTN *PixelWidth
)
{
UINT8 *Image;
UINT8 *ImageHeader;
BMP_IMAGE_HEADER *BmpHeader;
BMP_COLOR_MAP *BmpColorMap;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
UINTN BltBufferSize;
UINTN Index;
UINTN Height;
UINTN Width;
UINTN ImageIndex;
BOOLEAN IsAllocated;
BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;
if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {
return EFI_UNSUPPORTED;
}
//
// Doesn't support compress.
//
if (BmpHeader->CompressionType != 0) {
return EFI_UNSUPPORTED;
}
//
// Calculate Color Map offset in the image.
//
Image = BmpImage;
BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));
//
// Calculate graphics image data address in the image
//
Image = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;
ImageHeader = Image;
//
// Calculate the BltBuffer needed size.
//
BltBufferSize = BmpHeader->PixelWidth * BmpHeader->PixelHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
IsAllocated = FALSE;
if (*GopBlt == NULL) {
//
// GopBlt is not allocated by caller.
//
*GopBltSize = BltBufferSize;
*GopBlt = AllocatePool (*GopBltSize);
IsAllocated = TRUE;
if (*GopBlt == NULL) {
return EFI_OUT_OF_RESOURCES;
}
} else {
//
// GopBlt has been allocated by caller.
//
if (*GopBltSize < BltBufferSize) {
*GopBltSize = BltBufferSize;
return EFI_BUFFER_TOO_SMALL;
}
}
*PixelWidth = BmpHeader->PixelWidth;
*PixelHeight = BmpHeader->PixelHeight;
//
// Convert image from BMP to Blt buffer format
//
BltBuffer = *GopBlt;
for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {
Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];
for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {
switch (BmpHeader->BitPerPixel) {
case 1:
//
// Convert 1-bit (2 colors) BMP to 24-bit color
//
for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {
Blt->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;
Blt->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;
Blt->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;
Blt++;
Width++;
}
Blt--;
Width--;
break;
case 4:
//
// Convert 4-bit (16 colors) BMP Palette to 24-bit color
//
Index = (*Image) >> 4;
Blt->Red = BmpColorMap[Index].Red;
Blt->Green = BmpColorMap[Index].Green;
Blt->Blue = BmpColorMap[Index].Blue;
if (Width < (BmpHeader->PixelWidth - 1)) {
Blt++;
Width++;
Index = (*Image) & 0x0f;
Blt->Red = BmpColorMap[Index].Red;
Blt->Green = BmpColorMap[Index].Green;
Blt->Blue = BmpColorMap[Index].Blue;
}
break;
case 8:
//
// Convert 8-bit (256 colors) BMP Palette to 24-bit color
//
Blt->Red = BmpColorMap[*Image].Red;
Blt->Green = BmpColorMap[*Image].Green;
Blt->Blue = BmpColorMap[*Image].Blue;
break;
case 24:
//
// It is 24-bit BMP.
//
Blt->Blue = *Image++;
Blt->Green = *Image++;
Blt->Red = *Image;
break;
default:
//
// Other bit format BMP is not supported.
//
if (IsAllocated) {
FreePool (*GopBlt);
*GopBlt = NULL;
}
return EFI_UNSUPPORTED;
break;
};
}
ImageIndex = (UINTN) (Image - ImageHeader);
if ((ImageIndex % 4) != 0) {
//
// Bmp Image starts each row on a 32-bit boundary!
//
Image = Image + (4 - (ImageIndex % 4));
}
}
return EFI_SUCCESS;
}
/**
Use Console Control Protocol to lock the Console In Spliter virtual handle.
This is the ConInHandle and ConIn handle in the EFI system table. All key
presses will be ignored until the Password is typed in. The only way to
disable the password is to type it in to a ConIn device.
@param Password Password used to lock ConIn device.
@retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.
@retval EFI_UNSUPPORTED Password not found
**/
EFI_STATUS
EFIAPI
LockKeyboards (
IN CHAR16 *Password
)
{
EFI_STATUS Status;
EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;
Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
Status = ConsoleControl->LockStdIn (ConsoleControl, Password);
return Status;
}
/**
Use Console Control to turn off UGA based Simple Text Out consoles from going
to the UGA device. Put up LogoFile on every UGA device that is a console
@param[in] LogoFile File name of logo to display on the center of the screen.
@retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo displayed.
@retval EFI_UNSUPPORTED Logo not found
**/
EFI_STATUS
EFIAPI
EnableQuietBoot (
IN EFI_GUID *LogoFile
)
{
EFI_STATUS Status;
EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;
EFI_OEM_BADGING_PROTOCOL *Badging;
UINT32 SizeOfX;
UINT32 SizeOfY;
INTN DestX;
INTN DestY;
UINT8 *ImageData;
UINTN ImageSize;
UINTN BltSize;
UINT32 Instance;
EFI_BADGING_FORMAT Format;
EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;
UINTN CoordinateX;
UINTN CoordinateY;
UINTN Height;
UINTN Width;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
EFI_UGA_DRAW_PROTOCOL *UgaDraw;
UINT32 ColorDepth;
UINT32 RefreshRate;
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
UgaDraw = NULL;
//
// Try to open GOP first
//
Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);
if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
GraphicsOutput = NULL;
//
// Open GOP failed, try to open UGA
//
Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);
}
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
Badging = NULL;
Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);
//
// Set console control to graphics mode.
//
Status = ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
if (GraphicsOutput != NULL) {
SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;
SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;
} else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
} else {
return EFI_UNSUPPORTED;
}
Instance = 0;
while (1) {
ImageData = NULL;
ImageSize = 0;
if (Badging != NULL) {
//
// Get image from OEMBadging protocol.
//
Status = Badging->GetImage (
Badging,
&Instance,
&Format,
&ImageData,
&ImageSize,
&Attribute,
&CoordinateX,
&CoordinateY
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Currently only support BMP format.
//
if (Format != EfiBadgingFormatBMP) {
if (ImageData != NULL) {
FreePool (ImageData);
}
continue;
}
} else {
//
// Get the specified image from FV.
//
Status = GetSectionFromAnyFv (LogoFile, EFI_SECTION_RAW, 0, (VOID **) &ImageData, &ImageSize);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
CoordinateX = 0;
CoordinateY = 0;
Attribute = EfiBadgingDisplayAttributeCenter;
}
Blt = NULL;
Status = ConvertBmpToGopBlt (
ImageData,
ImageSize,
(VOID **) &Blt,
&BltSize,
&Height,
&Width
);
if (EFI_ERROR (Status)) {
FreePool (ImageData);
if (Badging == NULL) {
return Status;
} else {
continue;
}
}
//
// Calculate the display position according to Attribute.
//
switch (Attribute) {
case EfiBadgingDisplayAttributeLeftTop:
DestX = CoordinateX;
DestY = CoordinateY;
break;
case EfiBadgingDisplayAttributeCenterTop:
DestX = (SizeOfX - Width) / 2;
DestY = CoordinateY;
break;
case EfiBadgingDisplayAttributeRightTop:
DestX = (SizeOfX - Width - CoordinateX);
DestY = CoordinateY;;
break;
case EfiBadgingDisplayAttributeCenterRight:
DestX = (SizeOfX - Width - CoordinateX);
DestY = (SizeOfY - Height) / 2;
break;
case EfiBadgingDisplayAttributeRightBottom:
DestX = (SizeOfX - Width - CoordinateX);
DestY = (SizeOfY - Height - CoordinateY);
break;
case EfiBadgingDisplayAttributeCenterBottom:
DestX = (SizeOfX - Width) / 2;
DestY = (SizeOfY - Height - CoordinateY);
break;
case EfiBadgingDisplayAttributeLeftBottom:
DestX = CoordinateX;
DestY = (SizeOfY - Height - CoordinateY);
break;
case EfiBadgingDisplayAttributeCenterLeft:
DestX = CoordinateX;
DestY = (SizeOfY - Height) / 2;
break;
case EfiBadgingDisplayAttributeCenter:
DestX = (SizeOfX - Width) / 2;
DestY = (SizeOfY - Height) / 2;
break;
default:
DestX = CoordinateX;
DestY = CoordinateY;
break;
}
if ((DestX >= 0) && (DestY >= 0)) {
if (GraphicsOutput != NULL) {
Status = GraphicsOutput->Blt (
GraphicsOutput,
Blt,
EfiBltBufferToVideo,
0,
0,
(UINTN) DestX,
(UINTN) DestY,
Width,
Height,
Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
);
} else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
Status = UgaDraw->Blt (
UgaDraw,
(EFI_UGA_PIXEL *) Blt,
EfiUgaBltBufferToVideo,
0,
0,
(UINTN) DestX,
(UINTN) DestY,
Width,
Height,
Width * sizeof (EFI_UGA_PIXEL)
);
} else {
Status = EFI_UNSUPPORTED;
}
}
FreePool (ImageData);
if (Blt != NULL) {
FreePool (Blt);
}
if (Badging == NULL) {
break;
}
}
return Status;
}
/**
Use Console Control to turn on UGA based Simple Text Out consoles. The UGA
Simple Text Out screens will now be synced up with all non UGA output devices
@retval EFI_SUCCESS UGA devices are back in text mode and synced up.
**/
EFI_STATUS
EFIAPI
DisableQuietBoot (
VOID
)
{
EFI_STATUS Status;
EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;
Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
//
// Set console control to text mode.
//
return ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,114 @@
#/** @file
#
# General BDS defines and produce general interfaces for platform BDS driver including:
# 1) BDS boot policy interface;
# 2) BDS boot device connect interface;
# 3) BDS Misc interfaces for mainting boot variable, ouput string, etc.
#
# Copyright (c) 2007 - 2008, Intel Corporation. <BR>
# All rights reserved. This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#**/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = GenericBdsLib
FILE_GUID = e405ec31-ccaa-4dd4-83e8-0aec01703f7e
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = GenericBdsLib|DXE_DRIVER UEFI_APPLICATION
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources.common]
DevicePath.c
Performance.c
BdsConnect.c
BdsMisc.c
BdsConsole.c
BdsBoot.c
InternalBdsLib.h
[Sources.IPF]
Ipf/ShadowRom.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
#
#This dependency is because of gEfiLegacyBiosProtocolGuid. It may be removed if a Library class is created to
#abstract away definition in Framework specification or PI spec incorporates the Legacy Booting Protocols.
#
IntelFrameworkPkg/IntelFrameworkPkg.dec
[LibraryClasses]
DevicePathLib
PeCoffGetEntryPointLib
BaseLib
HobLib
UefiRuntimeServicesTableLib
DxeServicesTableLib
MemoryAllocationLib
UefiLib
UefiBootServicesTableLib
BaseMemoryLib
DebugLib
PrintLib
PcdLib
PerformanceLib
TimerLib
PcdLib
DxeServicesLib
[Guids]
gEfiVT100PlusGuid # ALWAYS_CONSUMED
gEfiMemoryTypeInformationGuid # ALWAYS_CONSUMED
gEfiVTUTF8Guid # ALWAYS_CONSUMED
gEfiShellFileGuid # ALWAYS_CONSUMED
gEfiGlobalVariableGuid # ALWAYS_CONSUMED
gEfiVT100Guid # ALWAYS_CONSUMED
gEfiFileInfoGuid # ALWAYS_CONSUMED
gEfiPcAnsiGuid # ALWAYS_CONSUMED
gEfiGenericPlatformVariableGuid # ALWAYS_CONSUMED
gEfiUartDevicePathGuid # ALWAYS_CONSUMED
gEfiSasDevicePathGuid # ALWAYS_CONSUMED
[Protocols]
gEfiSimpleFileSystemProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiSimpleTextOutProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiPciIoProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiLoadedImageProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiDevicePathToTextProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiSimpleNetworkProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiDebugPortProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiSimpleTextInProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiBlockIoProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiFirmwareVolume2ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiLegacyBiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiCpuArchProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiFirmwareVolumeDispatchProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiAcpiS3SaveProtocolGuid
gEfiGraphicsOutputProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiUgaDrawProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiConsoleControlProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiOEMBadgingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiHiiFontProtocolGuid # PROTOCOL ALWAYS_CONSUMED
[FeaturePcd.common]
gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdPlatformBootTimeOutDefault
gEfiMdeModulePkgTokenSpaceGuid.PcdDefaultBootFileName

View File

@ -0,0 +1,106 @@
/** @file
BDS library definition, include the file and data structure
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _INTERNAL_BDS_LIB_H_
#define _INTERNAL_BDS_LIB_H_
#include <PiDxe.h>
#include <IndustryStandard/Pci22.h>
#include <Protocol/BlockIo.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/Cpu.h>
#include <Protocol/SimpleFileSystem.h>
#include <Protocol/DebugPort.h>
#include <Protocol/DevicePath.h>
#include <Protocol/SimpleTextIn.h>
#include <Protocol/LegacyBios.h>
#include <Protocol/SimpleTextOut.h>
#include <Protocol/SimpleNetwork.h>
#include <Protocol/DevicePathToText.h>
#include <Protocol/FirmwareVolume2.h>
#include <Protocol/PciIo.h>
#include <Protocol/AcpiS3Save.h>
#include <Protocol/Performance.h>
#include <Protocol/FirmwareVolumeDispatch.h>
#include <Protocol/OEMBadging.h>
#include <Protocol/ConsoleControl.h>
#include <Protocol/GraphicsOutput.h>
#include <Protocol/UgaDraw.h>
#include <Protocol/HiiFont.h>
#include <Protocol/HiiImage.h>
#include <Guid/MemoryTypeInformation.h>
#include <Guid/FileInfo.h>
#include <Guid/GlobalVariable.h>
#include <Guid/PcAnsi.h>
#include <Guid/ShellFile.h>
#include <Guid/GenericPlatformVariable.h>
#include <Guid/Bmp.h>
#include <Library/PrintLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/HobLib.h>
#include <Library/BaseLib.h>
#include <Library/DevicePathLib.h>
#include <Library/PerformanceLib.h>
#include <Library/PcdLib.h>
#include <Library/IfrSupportLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/GenericBdsLib.h>
#include <Library/TimerLib.h>
#include <Library/PcdLib.h>
#include <Library/DxeServicesLib.h>
#define PERFORMANCE_SIGNATURE SIGNATURE_32 ('P', 'e', 'r', 'f')
#define PERF_TOKEN_SIZE 28
#define PERF_TOKEN_LENGTH (PERF_TOKEN_SIZE - 1)
#define PERF_PEI_ENTRY_MAX_NUM 50
typedef struct {
CHAR8 Token[PERF_TOKEN_SIZE];
UINT32 Duration;
} PERF_DATA;
typedef struct {
UINT64 BootToOs;
UINT64 S3Resume;
UINT32 S3EntryNum;
PERF_DATA S3Entry[PERF_PEI_ENTRY_MAX_NUM];
UINT64 CpuFreq;
UINT64 BDSRaw;
UINT32 Count;
UINT32 Signiture;
} PERF_HEADER;
/**
Allocates a block of memory and writes performance data of booting into it.
OS can processing these record.
**/
VOID
WriteBootToOsPerformanceData (
VOID
);
#endif // _BDS_LIB_H_

View File

@ -0,0 +1,46 @@
/** @file
Shadow all option rom
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "InternalBdsLib.h"
UINT8 mShadowRomFlag = 0;
/**
Shadow all opton ROM if the it is not done.
**/
VOID
ShadowAllOptionRom(
VOID
)
{
EFI_STATUS Status;
EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
//
// Rom shadow only do once.
//
if (mShadowRomFlag == 0) {
Status = gBS->LocateProtocol (
&gEfiLegacyBiosProtocolGuid,
NULL,
(VOID **) &LegacyBios
);
if (!EFI_ERROR (Status)) {
LegacyBios->PrepareToBootEfi (LegacyBios, NULL, NULL);
}
mShadowRomFlag = 1;
}
return ;
}

View File

@ -0,0 +1,316 @@
/** @file
This file include the file which can help to get the system
performance, all the function will only include if the performance
switch is set.
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "InternalBdsLib.h"
PERF_HEADER mPerfHeader;
PERF_DATA mPerfData;
/**
Get the short verion of PDB file name to be
used in performance data logging.
@param PdbFileName The long PDB file name.
@param GaugeString The output string to be logged by performance logger.
**/
VOID
GetShortPdbFileName (
IN CONST CHAR8 *PdbFileName,
OUT CHAR8 *GaugeString
)
{
UINTN Index;
UINTN Index1;
UINTN StartIndex;
UINTN EndIndex;
if (PdbFileName == NULL) {
AsciiStrCpy (GaugeString, " ");
} else {
StartIndex = 0;
for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++)
;
for (Index = 0; PdbFileName[Index] != 0; Index++) {
if (PdbFileName[Index] == '\\') {
StartIndex = Index + 1;
}
if (PdbFileName[Index] == '.') {
EndIndex = Index;
}
}
Index1 = 0;
for (Index = StartIndex; Index < EndIndex; Index++) {
GaugeString[Index1] = PdbFileName[Index];
Index1++;
if (Index1 == PERF_TOKEN_LENGTH - 1) {
break;
}
}
GaugeString[Index1] = 0;
}
return ;
}
/**
Get the name from the Driver handle, which can be a handle with
EFI_LOADED_IMAGE_PROTOCOL or EFI_DRIVER_BINDING_PROTOCOL installed.
This name can be used in performance data logging.
@param Handle Driver handle.
@param GaugeString The output string to be logged by performance logger.
**/
VOID
GetNameFromHandle (
IN EFI_HANDLE Handle,
OUT CHAR8 *GaugeString
)
{
EFI_STATUS Status;
EFI_LOADED_IMAGE_PROTOCOL *Image;
CHAR8 *PdbFileName;
EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
AsciiStrCpy (GaugeString, " ");
//
// Get handle name from image protocol
//
Status = gBS->HandleProtocol (
Handle,
&gEfiLoadedImageProtocolGuid,
(VOID **) &Image
);
if (EFI_ERROR (Status)) {
Status = gBS->OpenProtocol (
Handle,
&gEfiDriverBindingProtocolGuid,
(VOID **) &DriverBinding,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return ;
}
//
// Get handle name from image protocol
//
Status = gBS->HandleProtocol (
DriverBinding->ImageHandle,
&gEfiLoadedImageProtocolGuid,
(VOID **) &Image
);
}
PdbFileName = PeCoffLoaderGetPdbPointer (Image->ImageBase);
if (PdbFileName != NULL) {
GetShortPdbFileName (PdbFileName, GaugeString);
}
return ;
}
/**
Allocates a block of memory and writes performance data of booting into it.
OS can processing these record.
**/
VOID
WriteBootToOsPerformanceData (
VOID
)
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS AcpiLowMemoryBase;
UINT32 AcpiLowMemoryLength;
UINT32 LimitCount;
EFI_HANDLE *Handles;
UINTN NoHandles;
CHAR8 GaugeString[PERF_TOKEN_LENGTH];
UINT8 *Ptr;
UINT32 Index;
UINT64 Ticker;
UINT64 Freq;
UINT32 Duration;
UINTN LogEntryKey;
CONST VOID *Handle;
CONST CHAR8 *Token;
CONST CHAR8 *Module;
UINT64 StartTicker;
UINT64 EndTicker;
UINT64 StartValue;
UINT64 EndValue;
BOOLEAN CountUp;
//
// Retrive time stamp count as early as possilbe
//
Ticker = GetPerformanceCounter ();
Freq = GetPerformanceCounterProperties (&StartValue, &EndValue);
Freq = DivU64x32 (Freq, 1000);
mPerfHeader.CpuFreq = Freq;
//
// Record BDS raw performance data
//
if (EndValue >= StartValue) {
mPerfHeader.BDSRaw = Ticker - StartValue;
CountUp = TRUE;
} else {
mPerfHeader.BDSRaw = StartValue - Ticker;
CountUp = FALSE;
}
AcpiLowMemoryLength = 0x2000;
//
// Allocate a block of memory that contain performance data to OS
//
Status = gBS->AllocatePages (
AllocateAnyPages,
EfiACPIReclaimMemory,
EFI_SIZE_TO_PAGES (AcpiLowMemoryLength),
&AcpiLowMemoryBase
);
if (EFI_ERROR (Status)) {
return ;
}
Ptr = (UINT8 *) ((UINT32) AcpiLowMemoryBase + sizeof (PERF_HEADER));
LimitCount = (AcpiLowMemoryLength - sizeof (PERF_HEADER)) / sizeof (PERF_DATA);
//
// Put Detailed performance data into memory
//
Handles = NULL;
Status = gBS->LocateHandleBuffer (
AllHandles,
NULL,
NULL,
&NoHandles,
&Handles
);
if (EFI_ERROR (Status)) {
gBS->FreePages (AcpiLowMemoryBase, 1);
return ;
}
//
// Get DXE drivers performance
//
for (Index = 0; Index < NoHandles; Index++) {
Ticker = 0;
LogEntryKey = 0;
while ((LogEntryKey = GetPerformanceMeasurement (
LogEntryKey,
&Handle,
&Token,
&Module,
&StartTicker,
&EndTicker)) != 0) {
if ((Handle == Handles[Index]) && (EndTicker != 0)) {
Ticker += CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker);
}
}
Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq);
if (Duration > 0) {
GetNameFromHandle (Handles[Index], GaugeString);
AsciiStrCpy (mPerfData.Token, GaugeString);
mPerfData.Duration = Duration;
CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));
Ptr += sizeof (PERF_DATA);
mPerfHeader.Count++;
if (mPerfHeader.Count == LimitCount) {
goto Done;
}
}
}
FreePool (Handles);
//
// Get inserted performance data
//
LogEntryKey = 0;
while ((LogEntryKey = GetPerformanceMeasurement (
LogEntryKey,
&Handle,
&Token,
&Module,
&StartTicker,
&EndTicker)) != 0) {
if (Handle == NULL && EndTicker != 0) {
ZeroMem (&mPerfData, sizeof (PERF_DATA));
AsciiStrnCpy (mPerfData.Token, Token, PERF_TOKEN_LENGTH);
Ticker = CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker);
mPerfData.Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq);
CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));
Ptr += sizeof (PERF_DATA);
mPerfHeader.Count++;
if (mPerfHeader.Count == LimitCount) {
goto Done;
}
}
}
Done:
mPerfHeader.Signiture = PERFORMANCE_SIGNATURE;
//
// Put performance data to ACPI memory
//
CopyMem (
(UINTN *) (UINTN) AcpiLowMemoryBase,
&mPerfHeader,
sizeof (PERF_HEADER)
);
gRT->SetVariable (
L"PerfDataMemAddr",
&gEfiGenericPlatformVariableGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
sizeof (EFI_PHYSICAL_ADDRESS),
&AcpiLowMemoryBase
);
return ;
}

View File

@ -0,0 +1,141 @@
/** @file
Head file for BDS Architectural Protocol implementation
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _BDS_MODULE_H_
#define _BDS_MODULE_H_
#include <PiDxe.h>
#include <MdeModuleHii.h>
#include <Guid/FileSystemVolumeLabelInfo.h>
#include <Protocol/DevicePath.h>
#include <Guid/BootState.h>
#include <Guid/DataHubRecords.h>
#include <Protocol/LoadFile.h>
#include <Protocol/CpuIo.h>
#include <Guid/FileInfo.h>
#include <Protocol/HiiConfigRouting.h>
#include <Protocol/Bds.h>
#include <Protocol/DataHub.h>
#include <Protocol/UgaDraw.h>
#include <Protocol/BlockIo.h>
#include <Guid/GlobalVariable.h>
#include <Guid/GenericPlatformVariable.h>
#include <Guid/CapsuleVendor.h>
#include <Protocol/ConsoleControl.h>
#include <Protocol/GenericMemoryTest.h>
#include <Protocol/FormBrowser2.h>
#include <Protocol/HiiConfigAccess.h>
#include <Protocol/GraphicsOutput.h>
#include <Protocol/SimpleFileSystem.h>
#include <Protocol/HiiDatabase.h>
#include <Protocol/HiiString.h>
#include <Protocol/SerialIo.h>
#include <Protocol/LegacyBios.h>
#include <Protocol/SimpleTextInEx.h>
#include <Protocol/Performance.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/PrintLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PerformanceLib.h>
#include <Library/ReportStatusCodeLib.h>
#include <Library/IfrSupportLib.h>
#include <Library/ExtendedIfrSupportLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/HobLib.h>
#include <Library/BaseLib.h>
#include <Library/DevicePathLib.h>
#include <Library/PcdLib.h>
#include <Library/CapsuleLib.h>
#include <Library/HiiLib.h>
#include <Library/ExtendedHiiLib.h>
#include <Library/GenericBdsLib.h>
#include <Library/PlatformBdsLib.h>
#define EFI_BDS_ARCH_PROTOCOL_INSTANCE_FROM_THIS(_this) \
CR ((_this), \
EFI_BDS_ARCH_PROTOCOL_INSTANCE, \
Bds, \
EFI_BDS_ARCH_PROTOCOL_INSTANCE_SIGNATURE \
)
/**
Show progress bar with title above it. It only works in Graphics mode.
@param TitleForeground Foreground color for Title.
@param TitleBackground Background color for Title.
@param Title Title above progress bar.
@param ProgressColor Progress bar color.
@param Progress Progress (0-100)
@param PreviousValue The previous value of the progress.
@retval EFI_STATUS Success update the progress bar
**/
EFI_STATUS
PlatformBdsShowProgress (
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground,
IN CHAR16 *Title,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor,
IN UINTN Progress,
IN UINTN PreviousValue
);
//
// Prototypes
//
/**
Install Boot Device Selection Protocol
@param ImageHandle The image handle.
@param SystemTable The system table.
@retval EFI_SUCEESS BDS has finished initializing.
Return the dispatcher and recall BDS.Entry
@retval Other Return status from AllocatePool() or gBS->InstallProtocolInterface
**/
EFI_STATUS
EFIAPI
BdsInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
/**
Service routine for BdsInstance->Entry(). Devices are connected, the
consoles are initialized, and the boot options are tried.
@param This Protocol Instance structure.
**/
VOID
EFIAPI
BdsEntry (
IN EFI_BDS_ARCH_PROTOCOL *This
);
#endif

View File

@ -0,0 +1,164 @@
#/** @file
#
# BDSDxe module is core driver for BDS phase.
# When DxeCore dispatching all DXE driver, this module will produce architecture protocol
# gEfiBdsArchProtocolGuid. After DxeCore finish dispatching, DxeCore will invoke Entry
# interface of protocol gEfiBdsArchProtocolGuid, then BDS phase is entered.
#
# Generally, this module take reposiblity to connect all necessary devices for platform boot,
# these boot device path are hold in PlatformBdsLib library instance produced by platform.
# For legacy boot, BDS will transfer control to legacy BIOS after legacy boot device is select.
# For EFI boot, BDS will load boot loader file EFI\BOOT\BOOTIA32.EFI, EFI\BOOT\BOOTX64.EFI,
# EFI\BOOT\BOOTIA64.EFI file from selected boot device and transfer control to boot loader.
#
# BDSDxe also maintain the UI for "Boot Manager, Boot Maintaince Manager, Device Manager" which
# is used for user to configure boot option or maintain hardware device.
#
# Copyright (c) 2008, Intel Corporation. <BR>
# All rights reserved. This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#**/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = BdsDxe
FILE_GUID = FC5C7020-1A48-4198-9BE2-EAD5ABC8CF2F
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
EFI_SPECIFICATION_VERSION = 0x00020000
ENTRY_POINT = BdsInitialize
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources.common]
FrontPage.h
Language.h
Bds.h
Hotkey.h
BootMaint/BBSsupport.h
BootMngr/BootManager.h
BootMaint/BootMaint.h
String.h
BootMaint/FormGuid.h
HwErrRecSupport.c
HwErrRecSupport.h
DeviceMngr/DeviceManager.h
DeviceMngr/DeviceManagerVfr.Vfr
DeviceMngr/DeviceManagerStrings.uni
DeviceMngr/DeviceManager.c
BootMngr/BootManagerVfr.Vfr
BootMngr/BootManagerStrings.uni
BootMngr/BootManager.c
BootMaint/FE.vfr
BootMaint/FileExplorer.c
BootMaint/BootMaint.c
BootMaint/BBSsupport.c
BootMaint/UpdatePage.c
BootMaint/Variable.c
BootMaint/Data.c
BootMaint/ConsoleOption.c
BootMaint/BootOption.c
BootMaint/BmLib.c
BootMaint/Bm.vfr
BootMaint/Bmstring.uni
Hotkey.c
MemoryTest.c
Capsules.c
Strings.uni
String.c
Language.c
FrontPageVfr.Vfr
FrontPageStrings.uni
FrontPage.c
BdsEntry.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
#
#This dependency is because of gEfiLegacyBiosProtocolGuid and gEfiDataHubProtocolGuid. It may be removed if a Library class is created to
#abstract away definition in Framework specification or PI spec incorporates the Legacy Booting Protocols and Data Hub Protocols.
#
IntelFrameworkPkg/IntelFrameworkPkg.dec
[LibraryClasses]
DevicePathLib
BaseLib
HobLib
UefiRuntimeServicesTableLib
IfrSupportLib
ExtendedIfrSupportLib
GenericBdsLib
ReportStatusCodeLib
PerformanceLib
MemoryAllocationLib
UefiLib
UefiBootServicesTableLib
BaseMemoryLib
DebugLib
PrintLib
HiiLib
ExtendedHiiLib
UefiDriverEntryPoint
PlatformBdsLib
CapsuleLib
[Guids]
gEfiGlobalVariableGuid # ALWAYS_CONSUMED
gEfiBootStateGuid # ALWAYS_CONSUMED
gEfiFileSystemVolumeLabelInfoIdGuid # ALWAYS_CONSUMED
gEfiFileInfoGuid # ALWAYS_CONSUMED
gEfiGenericPlatformVariableGuid
gEfiMiscSubClassGuid
gEfiMemorySubClassGuid
gEfiProcessorSubClassGuid
gEfiCapsuleVendorGuid
[Protocols]
gEfiHiiStringProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiSimpleFileSystemProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiLoadFileProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiBdsArchProtocolGuid # PROTOCOL ALWAYS_PRODUCED
gEfiDataHubProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiGenericMemTestProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiLegacyBiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiConsoleControlProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiHiiDatabaseProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiUgaDrawProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiBlockIoProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiGraphicsOutputProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiSimpleTextInputExProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiHiiConfigRoutingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiHiiConfigAccessProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiFormBrowser2ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiSerialIoProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED
[FeaturePcd.common]
gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate
gEfiMdeModulePkgTokenSpaceGuid.PcdSupportHardwareErrorRecord
gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport
[Pcd.common]
gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangCodes
gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLang
gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLangCodes
gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang
gEfiMdeModulePkgTokenSpaceGuid.PcdHardwareErrorRecordLevel
[Depex]
gEfiHiiDatabaseProtocolGuid

View File

@ -0,0 +1,363 @@
/** @file
This module produce main entry for BDS phase - BdsEntry.
When this module was dispatched by DxeCore, gEfiBdsArchProtocolGuid will be installed
which contains interface of BdsEntry.
After DxeCore finish DXE phase, gEfiBdsArchProtocolGuid->BdsEntry will be invoked
to enter BDS phase.
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Bds.h"
#include "Language.h"
#include "FrontPage.h"
#include "Hotkey.h"
#include "HwErrRecSupport.h"
///
/// BDS arch protocol instance initial value.
///
/// Note: Current BDS not directly get the BootMode, DefaultBoot,
/// TimeoutDefault, MemoryTestLevel value from the BDS arch protocol.
/// Please refer to the library useage of BdsLibGetBootMode, BdsLibGetTimeout
/// and PlatformBdsDiagnostics in BdsPlatform.c
///
EFI_BDS_ARCH_PROTOCOL_INSTANCE gBdsInstanceTemplate = {
EFI_BDS_ARCH_PROTOCOL_INSTANCE_SIGNATURE,
NULL,
{BdsEntry},
0xFFFF,
TRUE,
0,
EXTENSIVE
};
UINT16 *mBootNext = NULL;
EFI_HANDLE mBdsImageHandle;
/**
Install Boot Device Selection Protocol
@param ImageHandle The image handle.
@param SystemTable The system table.
@retval EFI_SUCEESS BDS has finished initializing.
Return the dispatcher and recall BDS.Entry
@retval Other Return status from AllocatePool() or gBS->InstallProtocolInterface
**/
EFI_STATUS
EFIAPI
BdsInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
mBdsImageHandle = ImageHandle;
//
// Install protocol interface
//
Status = gBS->InstallProtocolInterface (
&gBdsInstanceTemplate.Handle,
&gEfiBdsArchProtocolGuid,
EFI_NATIVE_INTERFACE,
&gBdsInstanceTemplate.Bds
);
ASSERT_EFI_ERROR (Status);
return Status;
}
/**
This function attempts to boot for the boot order specified
by platform policy.
**/
VOID
BdsBootDeviceSelect (
VOID
)
{
EFI_STATUS Status;
LIST_ENTRY *Link;
BDS_COMMON_OPTION *BootOption;
UINTN ExitDataSize;
CHAR16 *ExitData;
UINT16 Timeout;
LIST_ENTRY BootLists;
CHAR16 Buffer[20];
BOOLEAN BootNextExist;
LIST_ENTRY *LinkBootNext;
//
// Got the latest boot option
//
BootNextExist = FALSE;
LinkBootNext = NULL;
InitializeListHead (&BootLists);
//
// First check the boot next option
//
ZeroMem (Buffer, sizeof (Buffer));
if (mBootNext != NULL) {
//
// Indicate we have the boot next variable, so this time
// boot will always have this boot option
//
BootNextExist = TRUE;
//
// Clear the this variable so it's only exist in this time boot
//
gRT->SetVariable (
L"BootNext",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
0,
mBootNext
);
//
// Add the boot next boot option
//
UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", *mBootNext);
BootOption = BdsLibVariableToOption (&BootLists, Buffer);
//
// If fail to get boot option from variable, just return and do nothing.
//
if (BootOption == NULL) {
return;
}
BootOption->BootCurrent = *mBootNext;
}
//
// Parse the boot order to get boot option
//
BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");
Link = BootLists.ForwardLink;
//
// Parameter check, make sure the loop will be valid
//
if (Link == NULL) {
return ;
}
//
// Here we make the boot in a loop, every boot success will
// return to the front page
//
for (;;) {
//
// Check the boot option list first
//
if (Link == &BootLists) {
//
// There are two ways to enter here:
// 1. There is no active boot option, give user chance to
// add new boot option
// 2. All the active boot option processed, and there is no
// one is success to boot, then we back here to allow user
// add new active boot option
//
Timeout = 0xffff;
PlatformBdsEnterFrontPage (Timeout, FALSE);
InitializeListHead (&BootLists);
BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");
Link = BootLists.ForwardLink;
continue;
}
//
// Get the boot option from the link list
//
BootOption = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
//
// According to EFI Specification, if a load option is not marked
// as LOAD_OPTION_ACTIVE, the boot manager will not automatically
// load the option.
//
if (!IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE)) {
//
// skip the header of the link list, becuase it has no boot option
//
Link = Link->ForwardLink;
continue;
}
//
// Make sure the boot option device path connected,
// but ignore the BBS device path
//
if (DevicePathType (BootOption->DevicePath) != BBS_DEVICE_PATH) {
//
// Notes: the internal shell can not been connected with device path
// so we do not check the status here
//
BdsLibConnectDevicePath (BootOption->DevicePath);
}
//
// All the driver options should have been processed since
// now boot will be performed.
//
Status = BdsLibBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData);
if (EFI_ERROR (Status)) {
//
// Call platform action to indicate the boot fail
//
BootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_FAILED));
PlatformBdsBootFail (BootOption, Status, ExitData, ExitDataSize);
//
// Check the next boot option
//
Link = Link->ForwardLink;
} else {
//
// Call platform action to indicate the boot success
//
BootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED));
PlatformBdsBootSuccess (BootOption);
//
// Boot success, then stop process the boot order, and
// present the boot manager menu, front page
//
Timeout = 0xffff;
PlatformBdsEnterFrontPage (Timeout, FALSE);
//
// Rescan the boot option list, avoid pertential risk of the boot
// option change in front page
//
if (BootNextExist) {
LinkBootNext = BootLists.ForwardLink;
}
InitializeListHead (&BootLists);
if (LinkBootNext != NULL) {
//
// Reserve the boot next option
//
InsertTailList (&BootLists, LinkBootNext);
}
BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");
Link = BootLists.ForwardLink;
}
}
}
/**
Service routine for BdsInstance->Entry(). Devices are connected, the
consoles are initialized, and the boot options are tried.
@param This Protocol Instance structure.
**/
VOID
EFIAPI
BdsEntry (
IN EFI_BDS_ARCH_PROTOCOL *This
)
{
EFI_BDS_ARCH_PROTOCOL_INSTANCE *PrivateData;
LIST_ENTRY DriverOptionList;
LIST_ENTRY BootOptionList;
UINTN BootNextSize;
//
// Insert the performance probe
//
PERF_END (0, DXE_TOK, NULL, 0);
PERF_START (0, BDS_TOK, NULL, 0);
//
// Initialize the global system boot option and driver option
//
InitializeListHead (&DriverOptionList);
InitializeListHead (&BootOptionList);
//
// Initialize hotkey service
//
InitializeHotkeyService ();
//
// Get the BDS private data
//
PrivateData = EFI_BDS_ARCH_PROTOCOL_INSTANCE_FROM_THIS (This);
//
// Do the platform init, can be customized by OEM/IBV
//
PERF_START (0, "PlatformBds", "BDS", 0);
PlatformBdsInit (PrivateData);
if (FeaturePcdGet (PcdSupportHardwareErrorRecord)) {
InitializeHwErrRecSupport (PcdGet16 (PcdHardwareErrorRecordLevel));
}
//
// bugbug: platform specific code
// Initialize the platform specific string and language
//
InitializeStringSupport ();
InitializeLanguage (TRUE);
InitializeFrontPage (TRUE);
//
// Set up the device list based on EFI 1.1 variables
// process Driver#### and Load the driver's in the
// driver option list
//
BdsLibBuildOptionFromVar (&DriverOptionList, L"DriverOrder");
if (!IsListEmpty (&DriverOptionList)) {
BdsLibLoadDrivers (&DriverOptionList);
}
//
// Check if we have the boot next option
//
mBootNext = BdsLibGetVariableAndSize (
L"BootNext",
&gEfiGlobalVariableGuid,
&BootNextSize
);
//
// Setup some platform policy here
//
PlatformBdsPolicyBehavior (PrivateData, &DriverOptionList, &BootOptionList);
PERF_END (0, "PlatformBds", "BDS", 0);
//
// BDS select the boot device to load OS
//
BdsBootDeviceSelect ();
//
// Only assert here since this is the right behavior, we should never
// return back to DxeCore.
//
ASSERT (FALSE);
return ;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,94 @@
/** @file
declares interface functions
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _EFI_BDS_BBS_SUPPORT_H_
#define _EFI_BDS_BBS_SUPPORT_H_
#include "BootMaint.h"
#define MAX_BBS_ENTRIES 0x100
/**
Build Legacy Device Name String according.
@param CurBBSEntry BBS Table.
@param Index Index.
@param BufSize The buffer size.
@param BootString The output string.
@return VOID No output.
**/
VOID
BdsBuildLegacyDevNameString (
IN BBS_TABLE *CurBBSEntry,
IN UINTN Index,
IN UINTN BufSize,
OUT CHAR16 *BootString
);
/**
Delete all the invalid legacy boot options.
@retval EFI_SUCCESS All invalide legacy boot options are deleted.
@retval EFI_OUT_OF_RESOURCES Fail to allocate necessary memory.
@retval EFI_NOT_FOUND Fail to retrive variable of boot order.
**/
EFI_STATUS
BdsDeleteAllInvalidLegacyBootOptions (
VOID
);
/**
Add the legacy boot options from BBS table if they do not exist.
@retval EFI_SUCCESS The boot options are added successfully or they are already in boot options.
@retval others An error occurred when creating legacy boot options.
**/
EFI_STATUS
BdsAddNonExistingLegacyBootOptions (
VOID
);
/**
Add the legacy boot devices from BBS table into
the legacy device boot order.
@retval EFI_SUCCESS The boot devices are added successfully.
**/
EFI_STATUS
BdsUpdateLegacyDevOrder (
VOID
);
/**
Set the boot priority for BBS entries based on boot option entry and boot order.
@param Entry The boot option is to be checked for refresh BBS table.
@retval EFI_SUCCESS The boot priority for BBS entries is refreshed successfully.
@return status of BdsSetBootPriority4SameTypeDev()
**/
EFI_STATUS
BdsRefreshBbsTableForBoot (
IN BDS_COMMON_OPTION *Entry
);
#endif

View File

@ -0,0 +1,383 @@
///** @file
//
// Boot Maintenance Utility Formset
//
// Copyright (c) 2004 - 2008, Intel Corporation. <BR>
// All rights reserved. This program and the accompanying materials
// are licensed and made available under the terms and conditions of the BSD License
// which accompanies this distribution. The full text of the license may be found at
// http://opensource.org/licenses/bsd-license.php
//
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
//
//**/
#include "FormGuid.h"
#define LABEL_END 0xffff
formset
guid = BOOT_MAINT_FORMSET_GUID,
title = STRING_TOKEN(STR_FORM_MAIN_TITLE),
help = STRING_TOKEN(STR_NULL_STRING),
class = 0,
subclass = 0,
varstore BMM_FAKE_NV_DATA,
varid = VARSTORE_ID_BOOT_MAINT,
name = BmmData,
guid = BOOT_MAINT_FORMSET_GUID;
form formid = FORM_MAIN_ID,
title = STRING_TOKEN(STR_FORM_MAIN_TITLE);
goto FORM_BOOT_SETUP_ID,
prompt = STRING_TOKEN(STR_FORM_BOOT_SETUP_TITLE),
help = STRING_TOKEN(STR_FORM_BOOT_SETUP_HELP),
flags = INTERACTIVE,
key = FORM_BOOT_SETUP_ID;
subtitle text = STRING_TOKEN(STR_NULL_STRING);
goto FORM_DRIVER_SETUP_ID,
prompt = STRING_TOKEN(STR_FORM_DRIVER_SETUP_TITLE),
help = STRING_TOKEN(STR_FORM_DRIVER_SETUP_HELP),
flags = INTERACTIVE,
key = FORM_DRIVER_SETUP_ID;
subtitle text = STRING_TOKEN(STR_NULL_STRING);
goto FORM_CON_MAIN_ID,
prompt = STRING_TOKEN(STR_FORM_CON_MAIN_TITLE),
help = STRING_TOKEN(STR_FORM_CON_MAIN_HELP),
flags = INTERACTIVE,
key = FORM_CON_MAIN_ID;
subtitle text = STRING_TOKEN(STR_NULL_STRING);
text
help = STRING_TOKEN(STR_BOOT_FROM_FILE_HELP),
text = STRING_TOKEN(STR_BOOT_FROM_FILE),
text = STRING_TOKEN(STR_NULL_STRING),
flags = INTERACTIVE,
key = KEY_VALUE_BOOT_FROM_FILE;
subtitle text = STRING_TOKEN(STR_NULL_STRING);
// label FORM_MAIN_ID;
goto FORM_BOOT_NEXT_ID,
prompt = STRING_TOKEN(STR_FORM_BOOT_NEXT_TITLE),
help = STRING_TOKEN(STR_FORM_BOOT_NEXT_HELP),
flags = INTERACTIVE,
key = FORM_BOOT_NEXT_ID;
goto FORM_TIME_OUT_ID,
prompt = STRING_TOKEN(STR_FORM_TIME_OUT_TITLE),
help = STRING_TOKEN(STR_FORM_TIME_OUT_HELP),
flags = INTERACTIVE,
key = FORM_TIME_OUT_ID;
subtitle text = STRING_TOKEN(STR_NULL_STRING);
goto FORM_MAIN_ID,
prompt = STRING_TOKEN(STR_RESET),
help = STRING_TOKEN(STR_RESET),
flags = INTERACTIVE,
key = FORM_RESET;
endform;
form formid = FORM_BOOT_SETUP_ID,
title = STRING_TOKEN(STR_FORM_BOOT_SETUP_TITLE);
goto FORM_MAIN_ID,
prompt = STRING_TOKEN(STR_FORM_GOTO_MAIN),
help = STRING_TOKEN(STR_FORM_GOTO_MAIN);
//flags = INTERACTIVE,
//key = FORM_MAIN_ID;
goto FORM_BOOT_ADD_ID,
prompt = STRING_TOKEN(STR_FORM_BOOT_ADD_TITLE),
help = STRING_TOKEN(STR_FORM_BOOT_ADD_HELP),
flags = INTERACTIVE,
key = FORM_BOOT_ADD_ID;
goto FORM_BOOT_DEL_ID,
prompt = STRING_TOKEN(STR_FORM_BOOT_DEL_TITLE),
help = STRING_TOKEN(STR_FORM_NEXT_BOOT_HELP),
flags = INTERACTIVE,
key = FORM_BOOT_DEL_ID;
goto FORM_BOOT_CHG_ID,
prompt = STRING_TOKEN(STR_FORM_BOOT_CHG_TITLE),
help = STRING_TOKEN(STR_FORM_NEXT_BOOT_HELP),
flags = INTERACTIVE,
key = FORM_BOOT_CHG_ID;
subtitle text = STRING_TOKEN(STR_NULL_STRING);
//
// We will add "Select Legacy Boot Floppy Drive" and "Select Legacy Boot Hard Drive"
// here dynamically
//
label FORM_BOOT_LEGACY_DEVICE_ID;
label LABEL_END;
endform;
form formid = FORM_DRIVER_SETUP_ID,
title = STRING_TOKEN(STR_FORM_DRIVER_SETUP_TITLE);
goto FORM_MAIN_ID,
prompt = STRING_TOKEN(STR_FORM_GOTO_MAIN),
help = STRING_TOKEN(STR_FORM_GOTO_MAIN);
//help = STRING_TOKEN(STR_FORM_GOTO_MAIN),
//flags = INTERACTIVE,
//key = FORM_MAIN_ID;
goto FORM_DRV_ADD_ID,
prompt = STRING_TOKEN(STR_FORM_DRV_ADD_TITLE),
help = STRING_TOKEN(STR_FORM_DRV_ADD_HELP),
flags = INTERACTIVE,
key = FORM_DRV_ADD_ID;
goto FORM_DRV_DEL_ID,
prompt = STRING_TOKEN(STR_FORM_DRV_DEL_TITLE),
help = STRING_TOKEN(STR_FORM_NEXT_BOOT_HELP),
flags = INTERACTIVE,
key = FORM_DRV_DEL_ID;
goto FORM_DRV_CHG_ID,
prompt = STRING_TOKEN(STR_FORM_DRV_CHG_TITLE),
help = STRING_TOKEN(STR_FORM_NEXT_BOOT_HELP),
flags = INTERACTIVE,
key = FORM_DRV_CHG_ID;
endform;
form formid = FORM_BOOT_ADD_ID,
title = STRING_TOKEN(STR_FORM_BOOT_ADD_TITLE);
label FORM_BOOT_ADD_ID;
label LABEL_END;
endform;
form formid = FORM_BOOT_DEL_ID,
title = STRING_TOKEN(STR_FORM_BOOT_DEL_TITLE);
label FORM_BOOT_DEL_ID;
label LABEL_END;
endform;
form formid = FORM_BOOT_CHG_ID,
title = STRING_TOKEN(STR_FORM_BOOT_CHG_TITLE);
label FORM_BOOT_CHG_ID;
label LABEL_END;
endform;
form formid = FORM_BOOT_NEXT_ID,
title = STRING_TOKEN(STR_FORM_BOOT_NEXT_TITLE);
label FORM_BOOT_NEXT_ID;
label LABEL_END;
endform;
form formid = FORM_TIME_OUT_ID,
title = STRING_TOKEN(STR_FORM_TIME_OUT_TITLE);
label FORM_TIME_OUT_ID;
label LABEL_END;
endform;
form formid = FORM_DRV_ADD_ID,
title = STRING_TOKEN(STR_FORM_DRV_ADD_TITLE);
goto FORM_MAIN_ID,
prompt = STRING_TOKEN(STR_FORM_GOTO_MAIN),
help = STRING_TOKEN(STR_FORM_GOTO_MAIN);
//flags = INTERACTIVE,
//key = FORM_MAIN_ID;
goto FORM_DRV_ADD_FILE_ID,
prompt = STRING_TOKEN(STR_FORM_DRV_ADD_FILE_TITLE),
help = STRING_TOKEN(STR_FORM_DRV_ADD_FILE_TITLE),
flags = INTERACTIVE,
key = FORM_DRV_ADD_FILE_ID;
endform;
form formid = FORM_DRV_DEL_ID,
title = STRING_TOKEN(STR_FORM_DRV_DEL_TITLE);
label FORM_DRV_DEL_ID;
label LABEL_END;
endform;
form formid = FORM_DRV_CHG_ID,
title = STRING_TOKEN(STR_FORM_DRV_CHG_TITLE);
label FORM_DRV_CHG_ID;
label LABEL_END;
endform;
form formid = FORM_CON_MAIN_ID,
title = STRING_TOKEN(STR_FORM_CON_MAIN_TITLE);
goto FORM_MAIN_ID,
prompt = STRING_TOKEN(STR_FORM_GOTO_MAIN),
help = STRING_TOKEN(STR_FORM_GOTO_MAIN);
//flags = INTERACTIVE,
//key = FORM_MAIN_ID;
goto FORM_CON_IN_ID,
prompt = STRING_TOKEN(STR_FORM_CON_IN_TITLE),
help = STRING_TOKEN(STR_FORM_CON_IN_HELP),
flags = INTERACTIVE,
key = FORM_CON_IN_ID;
goto FORM_CON_OUT_ID,
prompt = STRING_TOKEN(STR_FORM_CON_OUT_TITLE),
help = STRING_TOKEN(STR_FORM_CON_OUT_HELP),
flags = INTERACTIVE,
key = FORM_CON_OUT_ID;
goto FORM_CON_ERR_ID,
prompt = STRING_TOKEN(STR_FORM_STD_ERR_TITLE),
help = STRING_TOKEN(STR_FORM_STD_ERR_HELP),
flags = INTERACTIVE,
key = FORM_CON_ERR_ID;
goto FORM_CON_MODE_ID,
prompt = STRING_TOKEN(STR_FORM_MODE_TITLE),
help = STRING_TOKEN(STR_FORM_MODE_HELP),
flags = INTERACTIVE,
key = FORM_CON_MODE_ID;
goto FORM_CON_COM_ID,
prompt = STRING_TOKEN(STR_FORM_COM_TITLE),
help = STRING_TOKEN(STR_FORM_COM_HELP),
flags = INTERACTIVE,
key = FORM_CON_COM_ID;
endform;
form formid = FORM_CON_MODE_ID,
title = STRING_TOKEN(STR_FORM_MODE_TITLE);
label FORM_CON_MODE_ID;
label LABEL_END;
endform;
form formid = FORM_CON_COM_ID,
title = STRING_TOKEN(STR_FORM_COM_TITLE);
label FORM_CON_COM_ID;
label LABEL_END;
endform;
form formid = FORM_CON_COM_SETUP_ID,
title = STRING_TOKEN(STR_CON_COM_SETUP);
label FORM_CON_COM_SETUP_ID;
label LABEL_END;
endform;
form formid = FORM_FILE_SEEK_ID,
title = STRING_TOKEN(STR_FORM_BOOT_ADD_TITLE);
label FORM_FILE_SEEK_ID;
label LABEL_END;
endform;
form formid = FORM_FILE_NEW_SEEK_ID,
title = STRING_TOKEN(STR_FORM_BOOT_ADD_TITLE);
label FORM_FILE_NEW_SEEK_ID;
label LABEL_END;
endform;
form formid = FORM_DRV_ADD_FILE_ID,
title = STRING_TOKEN(STR_FORM_DRV_ADD_FILE_TITLE);
label FORM_DRV_ADD_FILE_ID;
label LABEL_END;
endform;
form formid = FORM_DRV_ADD_HANDLE_ID,
title = STRING_TOKEN(STR_FORM_DRV_ADD_HANDLE_TITLE);
label FORM_DRV_ADD_HANDLE_ID;
label LABEL_END;
endform;
form formid = FORM_DRV_ADD_HANDLE_DESC_ID,
title = STRING_TOKEN(STR_FORM_DRV_ADD_DESC_TITLE);
label FORM_DRV_ADD_HANDLE_DESC_ID;
label LABEL_END;
endform;
form formid = FORM_CON_IN_ID,
title = STRING_TOKEN(STR_FORM_CON_IN_TITLE);
label FORM_CON_IN_ID;
label LABEL_END;
endform;
form formid = FORM_CON_OUT_ID,
title = STRING_TOKEN(STR_FORM_CON_OUT_TITLE);
label FORM_CON_OUT_ID;
label LABEL_END;
endform;
form formid = FORM_CON_ERR_ID,
title = STRING_TOKEN(STR_FORM_STD_ERR_TITLE);
label FORM_CON_ERR_ID;
label LABEL_END;
endform;
form formid = FORM_SET_FD_ORDER_ID,
title = STRING_TOKEN(STR_FORM_SET_FD_ORDER_TITLE);
label FORM_SET_FD_ORDER_ID;
label LABEL_END;
endform;
form formid = FORM_SET_HD_ORDER_ID,
title = STRING_TOKEN(STR_FORM_SET_HD_ORDER_TITLE);
label FORM_SET_HD_ORDER_ID;
label LABEL_END;
endform;
form formid = FORM_SET_CD_ORDER_ID,
title = STRING_TOKEN(STR_FORM_SET_CD_ORDER_TITLE);
label FORM_SET_CD_ORDER_ID;
label LABEL_END;
endform;
form formid = FORM_SET_NET_ORDER_ID,
title = STRING_TOKEN(STR_FORM_SET_NET_ORDER_TITLE);
label FORM_SET_NET_ORDER_ID;
label LABEL_END;
endform;
form formid = FORM_SET_BEV_ORDER_ID,
title = STRING_TOKEN(STR_FORM_SET_BEV_ORDER_TITLE);
label FORM_SET_BEV_ORDER_ID;
label LABEL_END;
endform;
endformset;

View File

@ -0,0 +1,494 @@
/** @file
Utility routines used by boot maintenance modules.
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "BootMaint.h"
/**
Find the first instance of this Protocol
in the system and return it's interface.
@param ProtocolGuid Provides the protocol to search for
@param Interface On return, a pointer to the first interface
that matches ProtocolGuid
@retval EFI_SUCCESS A protocol instance matching ProtocolGuid was found
@retval EFI_NOT_FOUND No protocol instances were found that match ProtocolGuid
**/
EFI_STATUS
EfiLibLocateProtocol (
IN EFI_GUID *ProtocolGuid,
OUT VOID **Interface
)
{
EFI_STATUS Status;
Status = gBS->LocateProtocol (
ProtocolGuid,
NULL,
(VOID **) Interface
);
return Status;
}
/**
Function opens and returns a file handle to the root directory of a volume.
@param DeviceHandle A handle for a device
@return A valid file handle or NULL is returned
**/
EFI_FILE_HANDLE
EfiLibOpenRoot (
IN EFI_HANDLE DeviceHandle
)
{
EFI_STATUS Status;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;
EFI_FILE_HANDLE File;
File = NULL;
//
// File the file system interface to the device
//
Status = gBS->HandleProtocol (
DeviceHandle,
&gEfiSimpleFileSystemProtocolGuid,
(VOID *) &Volume
);
//
// Open the root directory of the volume
//
if (!EFI_ERROR (Status)) {
Status = Volume->OpenVolume (
Volume,
&File
);
}
//
// Done
//
return EFI_ERROR (Status) ? NULL : File;
}
/**
Helper function called as part of the code needed
to allocate the proper sized buffer for various
EFI interfaces.
@param Status Current status
@param Buffer Current allocated buffer, or NULL
@param BufferSize Current buffer size needed
@retval TRUE if the buffer was reallocated and the caller
should try the API again.
@retval FALSE The caller should not call this function again.
**/
BOOLEAN
EfiGrowBuffer (
IN OUT EFI_STATUS *Status,
IN OUT VOID **Buffer,
IN UINTN BufferSize
)
{
BOOLEAN TryAgain;
//
// If this is an initial request, buffer will be null with a new buffer size
//
if ((*Buffer == NULL) && (BufferSize != 0)) {
*Status = EFI_BUFFER_TOO_SMALL;
}
//
// If the status code is "buffer too small", resize the buffer
//
TryAgain = FALSE;
if (*Status == EFI_BUFFER_TOO_SMALL) {
if (*Buffer != NULL) {
FreePool (*Buffer);
}
*Buffer = AllocateZeroPool (BufferSize);
if (*Buffer != NULL) {
TryAgain = TRUE;
} else {
*Status = EFI_OUT_OF_RESOURCES;
}
}
//
// If there's an error, free the buffer
//
if (!TryAgain && EFI_ERROR (*Status) && (*Buffer != NULL)) {
FreePool (*Buffer);
*Buffer = NULL;
}
return TryAgain;
}
/**
Function returns the value of the specified variable.
@param Name A Null-terminated Unicode string that is
the name of the vendor's variable.
@param VendorGuid A unique identifier for the vendor.
@return The payload of the variable.
@retval NULL If the variable can't be read.
**/
VOID *
EfiLibGetVariable (
IN CHAR16 *Name,
IN EFI_GUID *VendorGuid
)
{
UINTN VarSize;
return BdsLibGetVariableAndSize (Name, VendorGuid, &VarSize);
}
/**
Function deletes the variable specified by VarName and VarGuid.
@param VarName A Null-terminated Unicode string that is
the name of the vendor's variable.
@param VarGuid A unique identifier for the vendor.
@retval EFI_SUCCESS The variable was found and removed
@retval EFI_UNSUPPORTED The variable store was inaccessible
@retval EFI_OUT_OF_RESOURCES The temporary buffer was not available
@retval EFI_NOT_FOUND The variable was not found
**/
EFI_STATUS
EfiLibDeleteVariable (
IN CHAR16 *VarName,
IN EFI_GUID *VarGuid
)
{
VOID *VarBuf;
EFI_STATUS Status;
VarBuf = EfiLibGetVariable (VarName, VarGuid);
Status = EFI_NOT_FOUND;
if (VarBuf != NULL) {
//
// Delete variable from Storage
//
Status = gRT->SetVariable (VarName, VarGuid, VAR_FLAG, 0, NULL);
ASSERT (!EFI_ERROR (Status));
FreePool (VarBuf);
}
return Status;
}
/**
Function gets the file system information from an open file descriptor,
and stores it in a buffer allocated from pool.
@param FHand The file handle.
@return A pointer to a buffer with file information.
@retval NULL is returned if failed to get Vaolume Label Info.
**/
EFI_FILE_SYSTEM_VOLUME_LABEL *
EfiLibFileSystemVolumeLabelInfo (
IN EFI_FILE_HANDLE FHand
)
{
EFI_STATUS Status;
EFI_FILE_SYSTEM_VOLUME_LABEL *Buffer;
UINTN BufferSize;
//
// Initialize for GrowBuffer loop
//
Buffer = NULL;
BufferSize = SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL + 200;
//
// Call the real function
//
while (EfiGrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
Status = FHand->GetInfo (
FHand,
&gEfiFileSystemVolumeLabelInfoIdGuid,
&BufferSize,
Buffer
);
}
return Buffer;
}
/**
Duplicate a string.
@param Src The source.
@return A new string which is duplicated copy of the source.
@retval NULL If there is not enough memory.
**/
CHAR16 *
EfiStrDuplicate (
IN CHAR16 *Src
)
{
CHAR16 *Dest;
UINTN Size;
Size = StrSize (Src);
Dest = AllocateZeroPool (Size);
ASSERT (Dest != NULL);
if (Dest != NULL) {
CopyMem (Dest, Src, Size);
}
return Dest;
}
/**
Function gets the file information from an open file descriptor, and stores it
in a buffer allocated from pool.
@param FHand File Handle.
@return A pointer to a buffer with file information or NULL is returned
**/
EFI_FILE_INFO *
EfiLibFileInfo (
IN EFI_FILE_HANDLE FHand
)
{
EFI_STATUS Status;
EFI_FILE_INFO *Buffer;
UINTN BufferSize;
//
// Initialize for GrowBuffer loop
//
Buffer = NULL;
BufferSize = SIZE_OF_EFI_FILE_INFO + 200;
//
// Call the real function
//
while (EfiGrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
Status = FHand->GetInfo (
FHand,
&gEfiFileInfoGuid,
&BufferSize,
Buffer
);
}
return Buffer;
}
/**
Function is used to determine the number of device path instances
that exist in a device path.
@param DevicePath A pointer to a device path data structure.
@return This function counts and returns the number of device path instances
in DevicePath.
**/
UINTN
EfiDevicePathInstanceCount (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
{
UINTN Count;
UINTN Size;
Count = 0;
while (GetNextDevicePathInstance (&DevicePath, &Size)) {
Count += 1;
}
return Count;
}
/**
Adjusts the size of a previously allocated buffer.
@param OldPool - A pointer to the buffer whose size is being adjusted.
@param OldSize - The size of the current buffer.
@param NewSize - The size of the new buffer.
@return The newly allocated buffer.
@retval NULL Allocation failed.
**/
VOID *
EfiReallocatePool (
IN VOID *OldPool,
IN UINTN OldSize,
IN UINTN NewSize
)
{
VOID *NewPool;
NewPool = NULL;
if (NewSize != 0) {
NewPool = AllocateZeroPool (NewSize);
}
if (OldPool != NULL) {
if (NewPool != NULL) {
CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize);
}
FreePool (OldPool);
}
return NewPool;
}
/**
Compare two EFI_TIME data.
@param FirstTime - A pointer to the first EFI_TIME data.
@param SecondTime - A pointer to the second EFI_TIME data.
@retval TRUE The FirstTime is not later than the SecondTime.
@retval FALSE The FirstTime is later than the SecondTime.
**/
BOOLEAN
TimeCompare (
IN EFI_TIME *FirstTime,
IN EFI_TIME *SecondTime
)
{
if (FirstTime->Year != SecondTime->Year) {
return (BOOLEAN) (FirstTime->Year < SecondTime->Year);
} else if (FirstTime->Month != SecondTime->Month) {
return (BOOLEAN) (FirstTime->Month < SecondTime->Month);
} else if (FirstTime->Day != SecondTime->Day) {
return (BOOLEAN) (FirstTime->Day < SecondTime->Day);
} else if (FirstTime->Hour != SecondTime->Hour) {
return (BOOLEAN) (FirstTime->Hour < SecondTime->Hour);
} else if (FirstTime->Minute != SecondTime->Minute) {
return (BOOLEAN) (FirstTime->Minute < FirstTime->Minute);
} else if (FirstTime->Second != SecondTime->Second) {
return (BOOLEAN) (FirstTime->Second < SecondTime->Second);
}
return (BOOLEAN) (FirstTime->Nanosecond <= SecondTime->Nanosecond);
}
/**
Get a string from the Data Hub record based on
a device path.
@param DevPath The device Path.
@return A string located from the Data Hub records based on
the device path.
@retval NULL If failed to get the String from Data Hub.
**/
UINT16 *
EfiLibStrFromDatahub (
IN EFI_DEVICE_PATH_PROTOCOL *DevPath
)
{
EFI_STATUS Status;
UINT16 *Desc;
EFI_DATA_HUB_PROTOCOL *Datahub;
UINT64 Count;
EFI_DATA_RECORD_HEADER *Record;
EFI_SUBCLASS_TYPE1_HEADER *DataHdr;
EFI_GUID MiscGuid;
EFI_MISC_ONBOARD_DEVICE_DATA *Ob;
EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *Port;
EFI_TIME CurTime;
CopyGuid (&MiscGuid, &gEfiMiscSubClassGuid);
Status = gBS->LocateProtocol (
&gEfiDataHubProtocolGuid,
NULL,
(VOID **) &Datahub
);
if (EFI_ERROR (Status)) {
return NULL;
}
Status = gRT->GetTime (&CurTime, NULL);
if (EFI_ERROR (Status)) {
return NULL;
}
Count = 0;
do {
Status = Datahub->GetNextRecord (Datahub, &Count, NULL, &Record);
if (EFI_ERROR (Status)) {
break;
}
if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA && CompareGuid (&Record->DataRecordGuid, &MiscGuid)) {
//
// This record is what we need
//
DataHdr = (EFI_SUBCLASS_TYPE1_HEADER *) (Record + 1);
if (EFI_MISC_ONBOARD_DEVICE_RECORD_NUMBER == DataHdr->RecordType) {
Ob = (EFI_MISC_ONBOARD_DEVICE_DATA *) (DataHdr + 1);
if (BdsLibMatchDevicePaths ((EFI_DEVICE_PATH_PROTOCOL *) &Ob->OnBoardDevicePath, DevPath)) {
GetProducerString (&Record->ProducerName, Ob->OnBoardDeviceDescription, &Desc);
return Desc;
}
}
if (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_RECORD_NUMBER == DataHdr->RecordType) {
Port = (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *) (DataHdr + 1);
if (BdsLibMatchDevicePaths ((EFI_DEVICE_PATH_PROTOCOL *) &Port->PortPath, DevPath)) {
GetProducerString (&Record->ProducerName, Port->PortExternalConnectorDesignator, &Desc);
return Desc;
}
}
}
} while (TimeCompare (&Record->LogTime, &CurTime) && Count != 0);
return NULL;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,942 @@
/** @file
handles console redirection from boot manager
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "BootMaint.h"
/**
Update Com Ports attributes from DevicePath
@param DevicePath DevicePath that contains Com ports
@retval EFI_SUCCESS The update is successful.
**/
EFI_STATUS
UpdateComAttributeFromVariable (
EFI_DEVICE_PATH_PROTOCOL *DevicePath
);
/**
Update the multi-instance device path of Terminal Device based on
the global TerminalMenu. If ChangeTernimal is TRUE, the terminal
device path in the Terminal Device in TerminalMenu is also updated.
@param DevicePath The multi-instance device path.
@param ChangeTerminal TRUE, then device path in the Terminal Device
in TerminalMenu is also updated; FALSE, no update.
@return EFI_SUCCESS The function completes successfully.
**/
EFI_STATUS
ChangeTerminalDevicePath (
IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN BOOLEAN ChangeTerminal
)
{
EFI_DEVICE_PATH_PROTOCOL *Node;
EFI_DEVICE_PATH_PROTOCOL *Node1;
ACPI_HID_DEVICE_PATH *Acpi;
UART_DEVICE_PATH *Uart;
UART_DEVICE_PATH *Uart1;
UINTN Com;
UINT32 Match;
BM_TERMINAL_CONTEXT *NewTerminalContext;
BM_MENU_ENTRY *NewMenuEntry;
Match = EISA_PNP_ID (0x0501);
Node = DevicePath;
Node = NextDevicePathNode (Node);
Com = 0;
while (!IsDevicePathEnd (Node)) {
if ((DevicePathType (Node) == ACPI_DEVICE_PATH) && (DevicePathSubType (Node) == ACPI_DP)) {
Acpi = (ACPI_HID_DEVICE_PATH *) Node;
if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {
CopyMem (&Com, &Acpi->UID, sizeof (UINT32));
}
}
NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Com);
NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {
Uart = (UART_DEVICE_PATH *) Node;
CopyMem (
&Uart->BaudRate,
&NewTerminalContext->BaudRate,
sizeof (UINT64)
);
CopyMem (
&Uart->DataBits,
&NewTerminalContext->DataBits,
sizeof (UINT8)
);
CopyMem (
&Uart->Parity,
&NewTerminalContext->Parity,
sizeof (UINT8)
);
CopyMem (
&Uart->StopBits,
&NewTerminalContext->StopBits,
sizeof (UINT8)
);
//
// Change the device path in the ComPort
//
if (ChangeTerminal) {
Node1 = NewTerminalContext->DevicePath;
Node1 = NextDevicePathNode (Node1);
while (!IsDevicePathEnd (Node1)) {
if ((DevicePathType (Node1) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node1) == MSG_UART_DP)) {
Uart1 = (UART_DEVICE_PATH *) Node1;
CopyMem (
&Uart1->BaudRate,
&NewTerminalContext->BaudRate,
sizeof (UINT64)
);
CopyMem (
&Uart1->DataBits,
&NewTerminalContext->DataBits,
sizeof (UINT8)
);
CopyMem (
&Uart1->Parity,
&NewTerminalContext->Parity,
sizeof (UINT8)
);
CopyMem (
&Uart1->StopBits,
&NewTerminalContext->StopBits,
sizeof (UINT8)
);
break;
}
//
// end if
//
Node1 = NextDevicePathNode (Node1);
}
//
// end while
//
break;
}
}
Node = NextDevicePathNode (Node);
}
return EFI_SUCCESS;
}
/**
Update the device path that describing a terminal device
based on the new BaudRate, Data Bits, parity and Stop Bits
set.
@param DevicePath terminal device's path
**/
VOID
ChangeVariableDevicePath (
IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
{
EFI_DEVICE_PATH_PROTOCOL *Node;
ACPI_HID_DEVICE_PATH *Acpi;
UART_DEVICE_PATH *Uart;
UINTN Com;
UINT32 Match;
BM_TERMINAL_CONTEXT *NewTerminalContext;
BM_MENU_ENTRY *NewMenuEntry;
Match = EISA_PNP_ID (0x0501);
Node = DevicePath;
Node = NextDevicePathNode (Node);
Com = 0;
while (!IsDevicePathEnd (Node)) {
if ((DevicePathType (Node) == ACPI_DEVICE_PATH) && (DevicePathSubType (Node) == ACPI_DP)) {
Acpi = (ACPI_HID_DEVICE_PATH *) Node;
if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {
CopyMem (&Com, &Acpi->UID, sizeof (UINT32));
}
}
if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {
NewMenuEntry = BOpt_GetMenuEntry (
&TerminalMenu,
Com
);
ASSERT (NewMenuEntry != NULL);
NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
Uart = (UART_DEVICE_PATH *) Node;
CopyMem (
&Uart->BaudRate,
&NewTerminalContext->BaudRate,
sizeof (UINT64)
);
CopyMem (
&Uart->DataBits,
&NewTerminalContext->DataBits,
sizeof (UINT8)
);
CopyMem (
&Uart->Parity,
&NewTerminalContext->Parity,
sizeof (UINT8)
);
CopyMem (
&Uart->StopBits,
&NewTerminalContext->StopBits,
sizeof (UINT8)
);
}
Node = NextDevicePathNode (Node);
}
}
/**
Retrieve ACPI UID of UART from device path
@param Handle The handle for the UART device.
@param AcpiUid The ACPI UID on output.
@retval TRUE Find valid UID from device path
@retval FALSE Can't find
**/
BOOLEAN
RetrieveUartUid (
IN EFI_HANDLE Handle,
IN OUT UINT32 *AcpiUid
)
{
UINT32 Match;
UINT8 *Ptr;
ACPI_HID_DEVICE_PATH *Acpi;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
gBS->HandleProtocol (
Handle,
&gEfiDevicePathProtocolGuid,
(VOID **) &DevicePath
);
Ptr = (UINT8 *) DevicePath;
while (*Ptr != END_DEVICE_PATH_TYPE) {
Ptr++;
}
Ptr = Ptr - sizeof (UART_DEVICE_PATH) - sizeof (ACPI_HID_DEVICE_PATH);
Acpi = (ACPI_HID_DEVICE_PATH *) Ptr;
Match = EISA_PNP_ID (0x0501);
if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {
if (AcpiUid != NULL) {
*AcpiUid = Acpi->UID;
}
return TRUE;
} else {
return FALSE;
}
}
/**
Sort Uart handles array with Acpi->UID from low to high.
@param Handles EFI_SERIAL_IO_PROTOCOL handle buffer
@param NoHandles EFI_SERIAL_IO_PROTOCOL handle count
**/
VOID
SortedUartHandle (
IN EFI_HANDLE *Handles,
IN UINTN NoHandles
)
{
UINTN Index1;
UINTN Index2;
UINTN Position;
UINT32 AcpiUid1;
UINT32 AcpiUid2;
UINT32 TempAcpiUid;
EFI_HANDLE TempHandle;
for (Index1 = 0; Index1 < NoHandles-1; Index1++) {
if (!RetrieveUartUid (Handles[Index1], &AcpiUid1)) {
continue;
}
TempHandle = Handles[Index1];
Position = Index1;
TempAcpiUid = AcpiUid1;
for (Index2 = Index1+1; Index2 < NoHandles; Index2++) {
if (!RetrieveUartUid (Handles[Index2], &AcpiUid2)) {
continue;
}
if (AcpiUid2 < TempAcpiUid) {
TempAcpiUid = AcpiUid2;
TempHandle = Handles[Index2];
Position = Index2;
}
}
Handles[Position] = Handles[Index1];
Handles[Index1] = TempHandle;
}
}
/**
Test whether DevicePath is a valid Terminal
@param DevicePath DevicePath to be checked
@param Termi If DevicePath is valid Terminal, terminal type is returned.
@param Com If DevicePath is valid Terminal, Com Port type is returned.
@retval TRUE If DevicePath point to a Terminal.
@retval FALSE If DevicePath does not point to a Terminal.
**/
BOOLEAN
IsTerminalDevicePath (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
OUT TYPE_OF_TERMINAL *Termi,
OUT UINTN *Com
);
/**
Build a list containing all serial devices.
@retval EFI_SUCCESS The function complete successfully.
@retval EFI_UNSUPPORTED No serial ports present.
**/
EFI_STATUS
LocateSerialIo (
VOID
)
{
UINT8 *Ptr;
UINTN Index;
UINTN Index2;
UINTN NoHandles;
EFI_HANDLE *Handles;
EFI_STATUS Status;
ACPI_HID_DEVICE_PATH *Acpi;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
UINT32 Match;
EFI_SERIAL_IO_PROTOCOL *SerialIo;
EFI_DEVICE_PATH_PROTOCOL *OutDevicePath;
EFI_DEVICE_PATH_PROTOCOL *InpDevicePath;
EFI_DEVICE_PATH_PROTOCOL *ErrDevicePath;
BM_MENU_ENTRY *NewMenuEntry;
BM_TERMINAL_CONTEXT *NewTerminalContext;
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
VENDOR_DEVICE_PATH Vendor;
//
// Get all handles that have SerialIo protocol installed
//
InitializeListHead (&TerminalMenu.Head);
TerminalMenu.MenuNumber = 0;
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiSerialIoProtocolGuid,
NULL,
&NoHandles,
&Handles
);
if (EFI_ERROR (Status)) {
//
// No serial ports present
//
return EFI_UNSUPPORTED;
}
//
// Sort Uart handles array with Acpi->UID from low to high
// then Terminal menu can be built from low Acpi->UID to high Acpi->UID
//
SortedUartHandle (Handles, NoHandles);
for (Index = 0; Index < NoHandles; Index++) {
//
// Check to see whether the handle has DevicePath Protocol installed
//
gBS->HandleProtocol (
Handles[Index],
&gEfiDevicePathProtocolGuid,
(VOID **) &DevicePath
);
Ptr = (UINT8 *) DevicePath;
while (*Ptr != END_DEVICE_PATH_TYPE) {
Ptr++;
}
Ptr = Ptr - sizeof (UART_DEVICE_PATH) - sizeof (ACPI_HID_DEVICE_PATH);
Acpi = (ACPI_HID_DEVICE_PATH *) Ptr;
Match = EISA_PNP_ID (0x0501);
if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {
NewMenuEntry = BOpt_CreateMenuEntry (BM_TERMINAL_CONTEXT_SELECT);
if (NewMenuEntry == NULL) {
FreePool (Handles);
return EFI_OUT_OF_RESOURCES;
}
NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
CopyMem (&NewMenuEntry->OptionNumber, &Acpi->UID, sizeof (UINT32));
NewTerminalContext->DevicePath = DuplicateDevicePath (DevicePath);
//
// BugBug: I have no choice, calling EfiLibStrFromDatahub will hang the system!
// coz' the misc data for each platform is not correct, actually it's the device path stored in
// datahub which is not completed, so a searching for end of device path will enter a
// dead-loop.
//
NewMenuEntry->DisplayString = EfiLibStrFromDatahub (DevicePath);
if (NULL == NewMenuEntry->DisplayString) {
NewMenuEntry->DisplayString = DevicePathToStr (DevicePath);
}
NewMenuEntry->HelpString = NULL;
gBS->HandleProtocol (
Handles[Index],
&gEfiSerialIoProtocolGuid,
(VOID **) &SerialIo
);
CopyMem (
&NewTerminalContext->BaudRate,
&SerialIo->Mode->BaudRate,
sizeof (UINT64)
);
CopyMem (
&NewTerminalContext->DataBits,
&SerialIo->Mode->DataBits,
sizeof (UINT8)
);
CopyMem (
&NewTerminalContext->Parity,
&SerialIo->Mode->Parity,
sizeof (UINT8)
);
CopyMem (
&NewTerminalContext->StopBits,
&SerialIo->Mode->StopBits,
sizeof (UINT8)
);
InsertTailList (&TerminalMenu.Head, &NewMenuEntry->Link);
TerminalMenu.MenuNumber++;
}
}
if (Handles != NULL) {
FreePool (Handles);
}
//
// Get L"ConOut", L"ConIn" and L"ErrOut" from the Var
//
OutDevicePath = EfiLibGetVariable (L"ConOut", &gEfiGlobalVariableGuid);
InpDevicePath = EfiLibGetVariable (L"ConIn", &gEfiGlobalVariableGuid);
ErrDevicePath = EfiLibGetVariable (L"ErrOut", &gEfiGlobalVariableGuid);
if (OutDevicePath != NULL) {
UpdateComAttributeFromVariable (OutDevicePath);
}
if (InpDevicePath != NULL) {
UpdateComAttributeFromVariable (InpDevicePath);
}
if (ErrDevicePath != NULL) {
UpdateComAttributeFromVariable (ErrDevicePath);
}
for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
if (NULL == NewMenuEntry) {
return EFI_NOT_FOUND;
}
NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
NewTerminalContext->TerminalType = 0;
NewTerminalContext->IsConIn = FALSE;
NewTerminalContext->IsConOut = FALSE;
NewTerminalContext->IsStdErr = FALSE;
Vendor.Header.Type = MESSAGING_DEVICE_PATH;
Vendor.Header.SubType = MSG_VENDOR_DP;
for (Index2 = 0; Index2 < 4; Index2++) {
CopyMem (&Vendor.Guid, &TerminalTypeGuid[Index2], sizeof (EFI_GUID));
SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH));
NewDevicePath = AppendDevicePathNode (
NewTerminalContext->DevicePath,
(EFI_DEVICE_PATH_PROTOCOL *) &Vendor
);
if (NewMenuEntry->HelpString != NULL) {
FreePool (NewMenuEntry->HelpString);
}
//
// NewMenuEntry->HelpString = DevicePathToStr (NewDevicePath);
// NewMenuEntry->DisplayString = NewMenuEntry->HelpString;
//
NewMenuEntry->HelpString = NULL;
if (BdsLibMatchDevicePaths (OutDevicePath, NewDevicePath)) {
NewTerminalContext->IsConOut = TRUE;
NewTerminalContext->TerminalType = (UINT8) Index2;
}
if (BdsLibMatchDevicePaths (InpDevicePath, NewDevicePath)) {
NewTerminalContext->IsConIn = TRUE;
NewTerminalContext->TerminalType = (UINT8) Index2;
}
if (BdsLibMatchDevicePaths (ErrDevicePath, NewDevicePath)) {
NewTerminalContext->IsStdErr = TRUE;
NewTerminalContext->TerminalType = (UINT8) Index2;
}
}
}
return EFI_SUCCESS;
}
/**
Update Com Ports attributes from DevicePath
@param DevicePath DevicePath that contains Com ports
@retval EFI_SUCCESS The update is successful.
@retval EFI_NOT_FOUND Can not find specific menu entry
**/
EFI_STATUS
UpdateComAttributeFromVariable (
EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
{
EFI_DEVICE_PATH_PROTOCOL *Node;
EFI_DEVICE_PATH_PROTOCOL *SerialNode;
ACPI_HID_DEVICE_PATH *Acpi;
UART_DEVICE_PATH *Uart;
UART_DEVICE_PATH *Uart1;
UINT32 Match;
UINTN TerminalNumber;
BM_MENU_ENTRY *NewMenuEntry;
BM_TERMINAL_CONTEXT *NewTerminalContext;
UINTN Index;
Match = EISA_PNP_ID (0x0501);
Node = DevicePath;
Node = NextDevicePathNode (Node);
TerminalNumber = 0;
for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
while (!IsDevicePathEnd (Node)) {
if ((DevicePathType (Node) == ACPI_DEVICE_PATH) && (DevicePathSubType (Node) == ACPI_DP)) {
Acpi = (ACPI_HID_DEVICE_PATH *) Node;
if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {
CopyMem (&TerminalNumber, &Acpi->UID, sizeof (UINT32));
}
}
if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {
Uart = (UART_DEVICE_PATH *) Node;
NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, TerminalNumber);
if (NULL == NewMenuEntry) {
return EFI_NOT_FOUND;
}
NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
CopyMem (
&NewTerminalContext->BaudRate,
&Uart->BaudRate,
sizeof (UINT64)
);
CopyMem (
&NewTerminalContext->DataBits,
&Uart->DataBits,
sizeof (UINT8)
);
CopyMem (
&NewTerminalContext->Parity,
&Uart->Parity,
sizeof (UINT8)
);
CopyMem (
&NewTerminalContext->StopBits,
&Uart->StopBits,
sizeof (UINT8)
);
SerialNode = NewTerminalContext->DevicePath;
SerialNode = NextDevicePathNode (SerialNode);
while (!IsDevicePathEnd (SerialNode)) {
if ((DevicePathType (SerialNode) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (SerialNode) == MSG_UART_DP)) {
//
// Update following device paths according to
// previous acquired uart attributes
//
Uart1 = (UART_DEVICE_PATH *) SerialNode;
CopyMem (
&Uart1->BaudRate,
&NewTerminalContext->BaudRate,
sizeof (UINT64)
);
CopyMem (
&Uart1->DataBits,
&NewTerminalContext->DataBits,
sizeof (UINT8)
);
CopyMem (
&Uart1->Parity,
&NewTerminalContext->Parity,
sizeof (UINT8)
);
CopyMem (
&Uart1->StopBits,
&NewTerminalContext->StopBits,
sizeof (UINT8)
);
break;
}
SerialNode = NextDevicePathNode (SerialNode);
}
//
// end while
//
}
Node = NextDevicePathNode (Node);
}
//
// end while
//
}
return EFI_SUCCESS;
}
/**
Build up Console Menu based on types passed in. The type can
be BM_CONSOLE_IN_CONTEXT_SELECT, BM_CONSOLE_OUT_CONTEXT_SELECT
and BM_CONSOLE_ERR_CONTEXT_SELECT.
@param ConsoleMenuType Can be BM_CONSOLE_IN_CONTEXT_SELECT, BM_CONSOLE_OUT_CONTEXT_SELECT
and BM_CONSOLE_ERR_CONTEXT_SELECT.
@retval EFI_UNSUPPORTED The type passed in is not in the 3 types defined.
@retval EFI_NOT_FOUND If the EFI Variable defined in UEFI spec with name "ConOutDev",
"ConInDev" or "ConErrDev" doesn't exists.
@retval EFI_OUT_OF_RESOURCES Not enough resource to complete the operations.
@retval EFI_SUCCESS Function completes successfully.
**/
EFI_STATUS
GetConsoleMenu (
IN UINTN ConsoleMenuType
)
{
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_DEVICE_PATH_PROTOCOL *AllDevicePath;
EFI_DEVICE_PATH_PROTOCOL *MultiDevicePath;
EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;
UINTN Size;
UINTN AllCount;
UINTN Index;
UINTN Index2;
BM_MENU_ENTRY *NewMenuEntry;
BM_CONSOLE_CONTEXT *NewConsoleContext;
TYPE_OF_TERMINAL Terminal;
UINTN Com;
BM_MENU_OPTION *ConsoleMenu;
DevicePath = NULL;
AllDevicePath = NULL;
AllCount = 0;
switch (ConsoleMenuType) {
case BM_CONSOLE_IN_CONTEXT_SELECT:
ConsoleMenu = &ConsoleInpMenu;
DevicePath = EfiLibGetVariable (
L"ConIn",
&gEfiGlobalVariableGuid
);
AllDevicePath = EfiLibGetVariable (
L"ConInDev",
&gEfiGlobalVariableGuid
);
break;
case BM_CONSOLE_OUT_CONTEXT_SELECT:
ConsoleMenu = &ConsoleOutMenu;
DevicePath = EfiLibGetVariable (
L"ConOut",
&gEfiGlobalVariableGuid
);
AllDevicePath = EfiLibGetVariable (
L"ConOutDev",
&gEfiGlobalVariableGuid
);
break;
case BM_CONSOLE_ERR_CONTEXT_SELECT:
ConsoleMenu = &ConsoleErrMenu;
DevicePath = EfiLibGetVariable (
L"ErrOut",
&gEfiGlobalVariableGuid
);
AllDevicePath = EfiLibGetVariable (
L"ErrOutDev",
&gEfiGlobalVariableGuid
);
break;
default:
return EFI_UNSUPPORTED;
}
if (NULL == AllDevicePath) {
return EFI_NOT_FOUND;
}
InitializeListHead (&ConsoleMenu->Head);
AllCount = EfiDevicePathInstanceCount (AllDevicePath);
ConsoleMenu->MenuNumber = 0;
//
// Following is menu building up for Console Devices selected.
//
MultiDevicePath = AllDevicePath;
Index2 = 0;
for (Index = 0; Index < AllCount; Index++) {
DevicePathInst = GetNextDevicePathInstance (&MultiDevicePath, &Size);
NewMenuEntry = BOpt_CreateMenuEntry (BM_CONSOLE_CONTEXT_SELECT);
if (NULL == NewMenuEntry) {
return EFI_OUT_OF_RESOURCES;
}
NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
NewMenuEntry->OptionNumber = Index2;
NewConsoleContext->DevicePath = DuplicateDevicePath (DevicePathInst);
NewMenuEntry->DisplayString = EfiLibStrFromDatahub (NewConsoleContext->DevicePath);
if (NULL == NewMenuEntry->DisplayString) {
NewMenuEntry->DisplayString = DevicePathToStr (NewConsoleContext->DevicePath);
}
NewConsoleContext->IsTerminal = IsTerminalDevicePath (
NewConsoleContext->DevicePath,
&Terminal,
&Com
);
NewConsoleContext->IsActive = BdsLibMatchDevicePaths (
DevicePath,
NewConsoleContext->DevicePath
);
if (NewConsoleContext->IsTerminal) {
BOpt_DestroyMenuEntry (NewMenuEntry);
} else {
Index2++;
ConsoleMenu->MenuNumber++;
InsertTailList (&ConsoleMenu->Head, &NewMenuEntry->Link);
}
}
return EFI_SUCCESS;
}
/**
Build up ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu
@retval EFI_SUCCESS The function always complete successfully.
**/
EFI_STATUS
GetAllConsoles (
VOID
)
{
GetConsoleMenu (BM_CONSOLE_IN_CONTEXT_SELECT);
GetConsoleMenu (BM_CONSOLE_OUT_CONTEXT_SELECT);
GetConsoleMenu (BM_CONSOLE_ERR_CONTEXT_SELECT);
return EFI_SUCCESS;
}
/**
Free ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu
@retval EFI_SUCCESS The function always complete successfully.
**/
EFI_STATUS
FreeAllConsoles (
VOID
)
{
BOpt_FreeMenu (&ConsoleOutMenu);
BOpt_FreeMenu (&ConsoleInpMenu);
BOpt_FreeMenu (&ConsoleErrMenu);
BOpt_FreeMenu (&TerminalMenu);
return EFI_SUCCESS;
}
/**
Test whether DevicePath is a valid Terminal
@param DevicePath DevicePath to be checked
@param Termi If DevicePath is valid Terminal, terminal type is returned.
@param Com If DevicePath is valid Terminal, Com Port type is returned.
@retval TRUE If DevicePath point to a Terminal.
@retval FALSE If DevicePath does not point to a Terminal.
**/
BOOLEAN
IsTerminalDevicePath (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
OUT TYPE_OF_TERMINAL *Termi,
OUT UINTN *Com
)
{
UINT8 *Ptr;
BOOLEAN IsTerminal;
VENDOR_DEVICE_PATH *Vendor;
ACPI_HID_DEVICE_PATH *Acpi;
UINT32 Match;
EFI_GUID TempGuid;
IsTerminal = FALSE;
//
// Parse the Device Path, should be change later!!!
//
Ptr = (UINT8 *) DevicePath;
while (*Ptr != END_DEVICE_PATH_TYPE) {
Ptr++;
}
Ptr = Ptr - sizeof (VENDOR_DEVICE_PATH);
Vendor = (VENDOR_DEVICE_PATH *) Ptr;
//
// There are four kinds of Terminal types
// check to see whether this devicepath
// is one of that type
//
CopyMem (&TempGuid, &Vendor->Guid, sizeof (EFI_GUID));
if (CompareGuid (&TempGuid, &TerminalTypeGuid[0])) {
*Termi = PC_ANSI;
IsTerminal = TRUE;
} else {
if (CompareGuid (&TempGuid, &TerminalTypeGuid[1])) {
*Termi = VT_100;
IsTerminal = TRUE;
} else {
if (CompareGuid (&TempGuid, &TerminalTypeGuid[2])) {
*Termi = VT_100_PLUS;
IsTerminal = TRUE;
} else {
if (CompareGuid (&TempGuid, &TerminalTypeGuid[3])) {
*Termi = VT_UTF8;
IsTerminal = TRUE;
} else {
IsTerminal = FALSE;
}
}
}
}
if (!IsTerminal) {
return FALSE;
}
Ptr = Ptr - sizeof (UART_DEVICE_PATH) - sizeof (ACPI_HID_DEVICE_PATH);
Acpi = (ACPI_HID_DEVICE_PATH *) Ptr;
Match = EISA_PNP_ID (0x0501);
if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {
CopyMem (Com, &Acpi->UID, sizeof (UINT32));
} else {
return FALSE;
}
return TRUE;
}
/**
Get mode number according to column and row
@param CallbackData The BMM context data.
**/
VOID
GetConsoleOutMode (
IN BMM_CALLBACK_DATA *CallbackData
)
{
UINTN Col;
UINTN Row;
UINTN CurrentCol;
UINTN CurrentRow;
UINTN Mode;
UINTN MaxMode;
EFI_STATUS Status;
CONSOLE_OUT_MODE *ModeInfo;
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;
ConOut = gST->ConOut;
MaxMode = (UINTN) (ConOut->Mode->MaxMode);
ModeInfo = EfiLibGetVariable (VAR_CON_OUT_MODE, &gEfiGenericPlatformVariableGuid);
if (ModeInfo != NULL) {
CurrentCol = ModeInfo->Column;
CurrentRow = ModeInfo->Row;
for (Mode = 0; Mode < MaxMode; Mode++) {
Status = ConOut->QueryMode (ConOut, Mode, &Col, &Row);
if (!EFI_ERROR(Status)) {
if (CurrentCol == Col && CurrentRow == Row) {
CallbackData->BmmFakeNvData.ConsoleOutMode = (UINT16) Mode;
break;
}
}
}
FreePool (ModeInfo);
}
}

View File

@ -0,0 +1,315 @@
/** @file
Define some data used for Boot Maint
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "BootMaint.h"
EFI_HII_UPDATE_DATA gUpdateData;
STRING_DEPOSITORY *FileOptionStrDepository;
STRING_DEPOSITORY *ConsoleOptionStrDepository;
STRING_DEPOSITORY *BootOptionStrDepository;
STRING_DEPOSITORY *BootOptionHelpStrDepository;
STRING_DEPOSITORY *DriverOptionStrDepository;
STRING_DEPOSITORY *DriverOptionHelpStrDepository;
STRING_DEPOSITORY *TerminalStrDepository;
///
/// Terminal type string token storage
///
UINT16 TerminalType[] = {
STRING_TOKEN(STR_COM_TYPE_0),
STRING_TOKEN(STR_COM_TYPE_1),
STRING_TOKEN(STR_COM_TYPE_2),
STRING_TOKEN(STR_COM_TYPE_3),
};
///
/// File system selection menu
///
BM_MENU_OPTION FsOptionMenu = {
BM_MENU_OPTION_SIGNATURE,
{NULL},
0
};
///
/// Console Input Device Selection Menu
///
BM_MENU_OPTION ConsoleInpMenu = {
BM_MENU_OPTION_SIGNATURE,
{NULL},
0
};
///
/// Console Output Device Selection Menu
///
BM_MENU_OPTION ConsoleOutMenu = {
BM_MENU_OPTION_SIGNATURE,
{NULL},
0
};
///
/// Error Output Device Selection Menu
///
BM_MENU_OPTION ConsoleErrMenu = {
BM_MENU_OPTION_SIGNATURE,
{NULL},
0
};
///
/// Boot Option from variable Menu
///
BM_MENU_OPTION BootOptionMenu = {
BM_MENU_OPTION_SIGNATURE,
{NULL},
0
};
///
/// Driver Option from variable menu
///
BM_MENU_OPTION DriverOptionMenu = {
BM_MENU_OPTION_SIGNATURE,
{NULL},
0
};
///
/// Legacy FD Info from LegacyBios.GetBbsInfo()
///
BM_MENU_OPTION LegacyFDMenu = {
BM_MENU_OPTION_SIGNATURE,
{NULL},
0
};
///
/// Legacy HD Info from LegacyBios.GetBbsInfo()
///
BM_MENU_OPTION LegacyHDMenu = {
BM_MENU_OPTION_SIGNATURE,
{NULL},
0
};
///
/// Legacy CD Info from LegacyBios.GetBbsInfo()
///
BM_MENU_OPTION LegacyCDMenu = {
BM_MENU_OPTION_SIGNATURE,
{NULL},
0
};
///
/// Legacy NET Info from LegacyBios.GetBbsInfo()
///
BM_MENU_OPTION LegacyNETMenu = {
BM_MENU_OPTION_SIGNATURE,
{NULL},
0
};
///
/// Legacy NET Info from LegacyBios.GetBbsInfo()
///
BM_MENU_OPTION LegacyBEVMenu = {
BM_MENU_OPTION_SIGNATURE,
{NULL},
0
};
///
/// Files and sub-directories in current directory menu
///
BM_MENU_OPTION DirectoryMenu = {
BM_MENU_OPTION_SIGNATURE,
{NULL},
0
};
///
/// Handles in current system selection menu
///
BM_MENU_OPTION DriverMenu = {
BM_MENU_OPTION_SIGNATURE,
{NULL},
0
};
BM_MENU_OPTION TerminalMenu = {
BM_MENU_OPTION_SIGNATURE,
{NULL},
0
};
///
/// Value and string token correspondency for BaudRate
///
COM_ATTR BaudRateList[19] = {
{
115200,
STRING_TOKEN(STR_COM_BAUD_RATE_0)
},
{
57600,
STRING_TOKEN(STR_COM_BAUD_RATE_1)
},
{
38400,
STRING_TOKEN(STR_COM_BAUD_RATE_2)
},
{
19200,
STRING_TOKEN(STR_COM_BAUD_RATE_3)
},
{
9600,
STRING_TOKEN(STR_COM_BAUD_RATE_4)
},
{
7200,
STRING_TOKEN(STR_COM_BAUD_RATE_5)
},
{
4800,
STRING_TOKEN(STR_COM_BAUD_RATE_6)
},
{
3600,
STRING_TOKEN(STR_COM_BAUD_RATE_7)
},
{
2400,
STRING_TOKEN(STR_COM_BAUD_RATE_8)
},
{
2000,
STRING_TOKEN(STR_COM_BAUD_RATE_9)
},
{
1800,
STRING_TOKEN(STR_COM_BAUD_RATE_10)
},
{
1200,
STRING_TOKEN(STR_COM_BAUD_RATE_11)
},
{
600,
STRING_TOKEN(STR_COM_BAUD_RATE_12)
},
{
300,
STRING_TOKEN(STR_COM_BAUD_RATE_13)
},
{
150,
STRING_TOKEN(STR_COM_BAUD_RATE_14)
},
{
134,
STRING_TOKEN(STR_COM_BAUD_RATE_15)
},
{
110,
STRING_TOKEN(STR_COM_BAUD_RATE_16)
},
{
75,
STRING_TOKEN(STR_COM_BAUD_RATE_17)
},
{
50,
STRING_TOKEN(STR_COM_BAUD_RATE_18)
}
};
///
/// Value and string token correspondency for DataBits
///
COM_ATTR DataBitsList[4] = {
{
5,
STRING_TOKEN(STR_COM_DATA_BITS_0)
},
{
6,
STRING_TOKEN(STR_COM_DATA_BITS_1)
},
{
7,
STRING_TOKEN(STR_COM_DATA_BITS_2)
},
{
8,
STRING_TOKEN(STR_COM_DATA_BITS_3)
}
};
///
/// Value and string token correspondency for Parity
///
COM_ATTR ParityList[5] = {
{
NoParity,
STRING_TOKEN(STR_COM_PAR_0)
},
{
EvenParity,
STRING_TOKEN(STR_COM_PAR_1)
},
{
OddParity,
STRING_TOKEN(STR_COM_PAR_2)
},
{
MarkParity,
STRING_TOKEN(STR_COM_PAR_3)
},
{
SpaceParity,
STRING_TOKEN(STR_COM_PAR_4)
}
};
///
/// Value and string token correspondency for Baudreate
///
COM_ATTR StopBitsList[3] = {
{
OneStopBit,
STRING_TOKEN(STR_COM_STOP_BITS_0)
},
{
OneFiveStopBits,
STRING_TOKEN(STR_COM_STOP_BITS_1)
},
{
TwoStopBits,
STRING_TOKEN(STR_COM_STOP_BITS_2)
}
};
///
/// Guid for messaging path, used in Serial port setting.
///
EFI_GUID TerminalTypeGuid[4] = {
DEVICE_PATH_MESSAGING_PC_ANSI,
DEVICE_PATH_MESSAGING_VT_100,
DEVICE_PATH_MESSAGING_VT_100_PLUS,
DEVICE_PATH_MESSAGING_VT_UTF8
};

View File

@ -0,0 +1,126 @@
///** @file
//
// File Explorer Formset
//
// Copyright (c) 2004 - 2008, Intel Corporation. <BR>
// All rights reserved. This program and the accompanying materials
// are licensed and made available under the terms and conditions of the BSD License
// which accompanies this distribution. The full text of the license may be found at
// http://opensource.org/licenses/bsd-license.php
//
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
//
//**/
#include "FormGuid.h"
#define LABEL_END 0xffff
formset
guid = FILE_EXPLORE_FORMSET_GUID,
title = STRING_TOKEN(STR_FILE_EXPLORER_TITLE),
help = STRING_TOKEN(STR_NULL_STRING),
class = 0,
subclass = 0,
varstore FILE_EXPLORER_NV_DATA,
varid = VARSTORE_ID_BOOT_MAINT,
name = FeData,
guid = FILE_EXPLORE_FORMSET_GUID;
form formid = FORM_FILE_EXPLORER_ID,
title = STRING_TOKEN(STR_FILE_EXPLORER_TITLE);
label FORM_FILE_EXPLORER_ID;
label LABEL_END;
endform;
form formid = FORM_BOOT_ADD_DESCRIPTION_ID,
title = STRING_TOKEN(STR_FORM_BOOT_ADD_DESC_TITLE);
label FORM_BOOT_ADD_DESCRIPTION_ID;
label LABEL_END;
subtitle text = STRING_TOKEN(STR_NULL_STRING);
string varid = FeData.DescriptionData,
prompt = STRING_TOKEN(STR_LOAD_OPTION_DESC),
help = STRING_TOKEN(STR_NULL_STRING),
minsize = 6,
maxsize = 75,
endstring;
string varid = FeData.OptionalData,
prompt = STRING_TOKEN(STR_OPTIONAL_DATA),
help = STRING_TOKEN(STR_NULL_STRING),
minsize = 0,
maxsize = 120,
endstring;
subtitle text = STRING_TOKEN(STR_NULL_STRING);
text
help = STRING_TOKEN(STR_SAVE_AND_EXIT),
text = STRING_TOKEN(STR_SAVE_AND_EXIT),
text = STRING_TOKEN(STR_NULL_STRING),
flags = INTERACTIVE,
key = KEY_VALUE_SAVE_AND_EXIT_BOOT;
text
help = STRING_TOKEN(STR_NO_SAVE_AND_EXIT),
text = STRING_TOKEN(STR_NO_SAVE_AND_EXIT),
text = STRING_TOKEN(STR_NULL_STRING),
flags = INTERACTIVE,
key = KEY_VALUE_NO_SAVE_AND_EXIT_BOOT;
endform;
form formid = FORM_DRIVER_ADD_FILE_DESCRIPTION_ID,
title = STRING_TOKEN(STR_FORM_DRV_ADD_DESC_TITLE);
label FORM_DRIVER_ADD_FILE_DESCRIPTION_ID;
label LABEL_END;
subtitle text = STRING_TOKEN(STR_NULL_STRING);
string varid = FeData.DescriptionData,
prompt = STRING_TOKEN(STR_LOAD_OPTION_DESC),
help = STRING_TOKEN(STR_NULL_STRING),
minsize = 6,
maxsize = 75,
endstring;
string varid = FeData.OptionalData,
prompt = STRING_TOKEN(STR_OPTIONAL_DATA),
help = STRING_TOKEN(STR_NULL_STRING),
minsize = 0,
maxsize = 120,
endstring;
checkbox varid = FeData.ForceReconnect,
prompt = STRING_TOKEN(STR_LOAD_OPTION_FORCE_RECON),
help = STRING_TOKEN(STR_LOAD_OPTION_FORCE_RECON),
flags = CHECKBOX_DEFAULT,
key = 0,
endcheckbox;
subtitle text = STRING_TOKEN(STR_NULL_STRING);
text
help = STRING_TOKEN(STR_SAVE_AND_EXIT),
text = STRING_TOKEN(STR_SAVE_AND_EXIT),
text = STRING_TOKEN(STR_NULL_STRING),
flags = INTERACTIVE,
key = KEY_VALUE_SAVE_AND_EXIT_DRIVER; //BUGBUB: allow duplicate key in one formset???
text
help = STRING_TOKEN(STR_NO_SAVE_AND_EXIT),
text = STRING_TOKEN(STR_NO_SAVE_AND_EXIT),
text = STRING_TOKEN(STR_NULL_STRING),
flags = INTERACTIVE,
key = KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER;
endform;
endformset;

View File

@ -0,0 +1,319 @@
/** @file
File explorer related functions.
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "BootMaint.h"
/**
Update the File Explore page.
@param CallbackData The BMM context data.
@param MenuOption Pointer to menu options to display.
**/
VOID
UpdateFileExplorePage (
IN BMM_CALLBACK_DATA *CallbackData,
BM_MENU_OPTION *MenuOption
)
{
UINTN Index;
BM_MENU_ENTRY *NewMenuEntry;
BM_FILE_CONTEXT *NewFileContext;
EFI_FORM_ID FormId;
NewMenuEntry = NULL;
NewFileContext = NULL;
FormId = 0;
RefreshUpdateData ();
for (Index = 0; Index < MenuOption->MenuNumber; Index++) {
NewMenuEntry = BOpt_GetMenuEntry (MenuOption, Index);
NewFileContext = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext;
if (NewFileContext->IsBootLegacy) {
continue;
}
if ((NewFileContext->IsDir) || (BOOT_FROM_FILE_STATE == CallbackData->FeCurrentState)) {
//
// Create Text opcode for directory, also create Text opcode for file in BOOT_FROM_FILE_STATE.
//
CreateActionOpCode (
(UINT16) (FILE_OPTION_OFFSET + Index),
NewMenuEntry->DisplayStringToken,
STRING_TOKEN (STR_NULL_STRING),
EFI_IFR_FLAG_CALLBACK,
0,
&gUpdateData
);
} else {
//
// Create Goto opcode for file in ADD_BOOT_OPTION_STATE or ADD_DRIVER_OPTION_STATE.
//
if (ADD_BOOT_OPTION_STATE == CallbackData->FeCurrentState) {
FormId = FORM_BOOT_ADD_DESCRIPTION_ID;
} else if (ADD_DRIVER_OPTION_STATE == CallbackData->FeCurrentState) {
FormId = FORM_DRIVER_ADD_FILE_DESCRIPTION_ID;
}
CreateGotoOpCode (
FormId,
NewMenuEntry->DisplayStringToken,
STRING_TOKEN (STR_NULL_STRING),
EFI_IFR_FLAG_CALLBACK,
(UINT16) (FILE_OPTION_OFFSET + Index),
&gUpdateData
);
}
}
IfrLibUpdateForm (
CallbackData->FeHiiHandle,
&mFileExplorerGuid,
FORM_FILE_EXPLORER_ID,
FORM_FILE_EXPLORER_ID,
FALSE,
&gUpdateData
);
}
/**
Update the file explower page with the refershed file system.
@param CallbackData BMM context data
@param KeyValue Key value to identify the type of data to expect.
@retval TRUE Inform the caller to create a callback packet to exit file explorer.
@retval FALSE Indicate that there is no need to exit file explorer.
**/
BOOLEAN
UpdateFileExplorer (
IN BMM_CALLBACK_DATA *CallbackData,
IN UINT16 KeyValue
)
{
UINT16 FileOptionMask;
BM_MENU_ENTRY *NewMenuEntry;
BM_FILE_CONTEXT *NewFileContext;
EFI_FORM_ID FormId;
BOOLEAN ExitFileExplorer;
EFI_STATUS Status;
NewMenuEntry = NULL;
NewFileContext = NULL;
ExitFileExplorer = FALSE;
FileOptionMask = (UINT16) (FILE_OPTION_MASK & KeyValue);
if (UNKNOWN_CONTEXT == CallbackData->FeDisplayContext) {
//
// First in, display file system.
//
BOpt_FreeMenu (&FsOptionMenu);
BOpt_FindFileSystem (CallbackData);
CreateMenuStringToken (CallbackData, CallbackData->FeHiiHandle, &FsOptionMenu);
UpdateFileExplorePage (CallbackData, &FsOptionMenu);
CallbackData->FeDisplayContext = FILE_SYSTEM;
} else {
if (FILE_SYSTEM == CallbackData->FeDisplayContext) {
NewMenuEntry = BOpt_GetMenuEntry (&FsOptionMenu, FileOptionMask);
} else if (DIRECTORY == CallbackData->FeDisplayContext) {
NewMenuEntry = BOpt_GetMenuEntry (&DirectoryMenu, FileOptionMask);
}
CallbackData->FeDisplayContext = DIRECTORY;
NewFileContext = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext;
if (NewFileContext->IsDir ) {
RemoveEntryList (&NewMenuEntry->Link);
BOpt_FreeMenu (&DirectoryMenu);
Status = BOpt_FindFiles (CallbackData, NewMenuEntry);
if (EFI_ERROR (Status)) {
ExitFileExplorer = TRUE;
goto exit;
}
CreateMenuStringToken (CallbackData, CallbackData->FeHiiHandle, &DirectoryMenu);
BOpt_DestroyMenuEntry (NewMenuEntry);
UpdateFileExplorePage (CallbackData, &DirectoryMenu);
} else {
switch (CallbackData->FeCurrentState) {
case BOOT_FROM_FILE_STATE:
//
// Here boot from file
//
BootThisFile (NewFileContext);
ExitFileExplorer = TRUE;
break;
case ADD_BOOT_OPTION_STATE:
case ADD_DRIVER_OPTION_STATE:
if (ADD_BOOT_OPTION_STATE == CallbackData->FeCurrentState) {
FormId = FORM_BOOT_ADD_DESCRIPTION_ID;
} else {
FormId = FORM_DRIVER_ADD_FILE_DESCRIPTION_ID;
}
CallbackData->MenuEntry = NewMenuEntry;
CallbackData->LoadContext->FilePathList = ((BM_FILE_CONTEXT *) (CallbackData->MenuEntry->VariableContext))->DevicePath;
//
// Create Subtitle op-code for the display string of the option.
//
RefreshUpdateData ();
CreateSubTitleOpCode (
NewMenuEntry->DisplayStringToken,
0,
0,
0,
&gUpdateData
);
IfrLibUpdateForm (
CallbackData->FeHiiHandle,
&mFileExplorerGuid,
FormId,
FormId,
FALSE,
&gUpdateData
);
break;
default:
break;
}
}
}
exit:
return ExitFileExplorer;
}
/**
This function processes the results of changes in configuration.
When user select a interactive opcode, this callback will be triggered.
Based on the Question(QuestionId) that triggers the callback, the corresponding
actions is performed. It handles:
1) the addition of boot option.
2) the addition of driver option.
3) exit from file browser
4) update of file content if a dir is selected.
5) boot the file if a file is selected in "boot from file"
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param Action Specifies the type of action taken by the browser.
@param QuestionId A unique value which is sent to the original exporting driver
so that it can identify the type of data to expect.
@param Type The type of value for the question.
@param Value A pointer to the data being sent to the original exporting driver.
@param ActionRequest On return, points to the action requested by the callback function.
@retval EFI_SUCCESS The callback successfully handled the action.
@retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
@retval EFI_DEVICE_ERROR The variable could not be saved.
@retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
@retval EFI_INVALID_PARAMETER If paramter Value or ActionRequest is NULL.
**/
EFI_STATUS
EFIAPI
FileExplorerCallback (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN EFI_BROWSER_ACTION Action,
IN EFI_QUESTION_ID QuestionId,
IN UINT8 Type,
IN EFI_IFR_TYPE_VALUE *Value,
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
)
{
BMM_CALLBACK_DATA *Private;
FILE_EXPLORER_NV_DATA *NvRamMap;
EFI_STATUS Status;
UINTN BufferSize;
if ((Value == NULL) || (ActionRequest == NULL)) {
return EFI_INVALID_PARAMETER;
}
Status = EFI_SUCCESS;
Private = FE_CALLBACK_DATA_FROM_THIS (This);
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
//
// Retrieve uncommitted data from Form Browser
//
NvRamMap = &Private->FeFakeNvData;
BufferSize = sizeof (FILE_EXPLORER_NV_DATA);
Status = GetBrowserData (NULL, NULL, &BufferSize, (UINT8 *) NvRamMap);
if (EFI_ERROR (Status)) {
return Status;
}
if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_BOOT || QuestionId == KEY_VALUE_SAVE_AND_EXIT_DRIVER) {
//
// Apply changes and exit formset
//
if (ADD_BOOT_OPTION_STATE == Private->FeCurrentState) {
Status = Var_UpdateBootOption (Private, NvRamMap);
if (EFI_ERROR (Status)) {
return Status;
}
BOpt_GetBootOptions (Private);
CreateMenuStringToken (Private, Private->FeHiiHandle, &BootOptionMenu);
} else if (ADD_DRIVER_OPTION_STATE == Private->FeCurrentState) {
Status = Var_UpdateDriverOption (
Private,
Private->FeHiiHandle,
NvRamMap->DescriptionData,
NvRamMap->OptionalData,
NvRamMap->ForceReconnect
);
if (EFI_ERROR (Status)) {
return Status;
}
BOpt_GetDriverOptions (Private);
CreateMenuStringToken (Private, Private->FeHiiHandle, &DriverOptionMenu);
}
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
} else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_BOOT || QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER) {
//
// Discard changes and exit formset
//
NvRamMap->OptionalData[0] = 0x0000;
NvRamMap->DescriptionData[0] = 0x0000;
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
} else if (QuestionId < FILE_OPTION_OFFSET) {
//
// Exit File Explorer formset
//
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
} else {
if (UpdateFileExplorer (Private, QuestionId)) {
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
}
}
return Status;
}

View File

@ -0,0 +1,209 @@
/** @file
Formset guids, form id and VarStore data structure for Boot Maintenance Manager.
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _FORM_GUID_H_
#define _FORM_GUID_H_
#define BOOT_MAINT_FORMSET_GUID \
{ \
0x642237c7, 0x35d4, 0x472d, {0x83, 0x65, 0x12, 0xe0, 0xcc, 0xf2, 0x7a, 0x22} \
}
#define FILE_EXPLORE_FORMSET_GUID \
{ \
0x1f2d63e1, 0xfebd, 0x4dc7, {0x9c, 0xc5, 0xba, 0x2b, 0x1c, 0xef, 0x9c, 0x5b} \
}
#define FORM_MAIN_ID 0x1001
#define FORM_BOOT_ADD_ID 0x1002
#define FORM_BOOT_DEL_ID 0x1003
#define FORM_BOOT_CHG_ID 0x1004
#define FORM_DRV_ADD_ID 0x1005
#define FORM_DRV_DEL_ID 0x1006
#define FORM_DRV_CHG_ID 0x1007
#define FORM_CON_MAIN_ID 0x1008
#define FORM_CON_IN_ID 0x1009
#define FORM_CON_OUT_ID 0x100A
#define FORM_CON_ERR_ID 0x100B
#define FORM_FILE_SEEK_ID 0x100C
#define FORM_FILE_NEW_SEEK_ID 0x100D
#define FORM_DRV_ADD_FILE_ID 0x100E
#define FORM_DRV_ADD_HANDLE_ID 0x100F
#define FORM_DRV_ADD_HANDLE_DESC_ID 0x1010
#define FORM_BOOT_NEXT_ID 0x1011
#define FORM_TIME_OUT_ID 0x1012
#define FORM_RESET 0x1013
#define FORM_BOOT_SETUP_ID 0x1014
#define FORM_DRIVER_SETUP_ID 0x1015
#define FORM_BOOT_LEGACY_DEVICE_ID 0x1016
#define FORM_CON_COM_ID 0x1017
#define FORM_CON_COM_SETUP_ID 0x1018
#define FORM_SET_FD_ORDER_ID 0x1019
#define FORM_SET_HD_ORDER_ID 0x101A
#define FORM_SET_CD_ORDER_ID 0x101B
#define FORM_SET_NET_ORDER_ID 0x101C
#define FORM_SET_BEV_ORDER_ID 0x101D
#define FORM_FILE_EXPLORER_ID 0x101E
#define FORM_BOOT_ADD_DESCRIPTION_ID 0x101F
#define FORM_DRIVER_ADD_FILE_DESCRIPTION_ID 0x1020
#define FORM_CON_MODE_ID 0x1021
#define MAXIMUM_FORM_ID 0x10FF
#define KEY_VALUE_COM_SET_BAUD_RATE 0x1101
#define KEY_VALUE_COM_SET_DATA_BITS 0x1102
#define KEY_VALUE_COM_SET_STOP_BITS 0x1103
#define KEY_VALUE_COM_SET_PARITY 0x1104
#define KEY_VALUE_COM_SET_TERMI_TYPE 0x1105
#define KEY_VALUE_MAIN_BOOT_NEXT 0x1106
#define KEY_VALUE_BOOT_ADD_DESC_DATA 0x1107
#define KEY_VALUE_BOOT_ADD_OPT_DATA 0x1108
#define KEY_VALUE_DRIVER_ADD_DESC_DATA 0x1109
#define KEY_VALUE_DRIVER_ADD_OPT_DATA 0x110A
#define KEY_VALUE_SAVE_AND_EXIT 0x110B
#define KEY_VALUE_NO_SAVE_AND_EXIT 0x110C
#define KEY_VALUE_BOOT_FROM_FILE 0x110D
#define MAXIMUM_NORMAL_KEY_VALUE 0x11FF
//
// Varstore ID defined for Buffer Stoarge
//
#define VARSTORE_ID_BOOT_MAINT 0x1000
#define VARSTORE_ID_FILE_EXPLORER 0x1001
///
/// This is the structure that will be used to store the
/// question's current value. Use it at initialize time to
/// set default value for each question. When using at run
/// time, this map is returned by the callback function,
/// so dynamically changing the question's value will be
/// possible through this mechanism
///
typedef struct {
//
// Three questions displayed at the main page
// for Timeout, BootNext Variables respectively
//
UINT16 BootTimeOut;
UINT16 BootNext;
//
// This is the COM1 Attributes value storage
//
UINT8 COM1BaudRate;
UINT8 COM1DataRate;
UINT8 COM1StopBits;
UINT8 COM1Parity;
UINT8 COM1TerminalType;
//
// This is the COM2 Attributes value storage
//
UINT8 COM2BaudRate;
UINT8 COM2DataRate;
UINT8 COM2StopBits;
UINT8 COM2Parity;
UINT8 COM2TerminalType;
//
// Driver Option Add Handle page storage
//
UINT16 DriverAddHandleDesc[100];
UINT16 DriverAddHandleOptionalData[100];
UINT8 DriverAddActive;
UINT8 DriverAddForceReconnect;
//
// Console Input/Output/Errorout using COM port check storage
//
UINT8 ConsoleInputCOM1;
UINT8 ConsoleInputCOM2;
UINT8 ConsoleOutputCOM1;
UINT8 ConsoleOutputCOM2;
UINT8 ConsoleErrorCOM1;
UINT8 ConsoleErrorCOM2;
//
// At most 100 input/output/errorout device for console storage
//
UINT8 ConsoleCheck[100];
//
// Boot or Driver Option Order storage
//
UINT8 OptionOrder[100];
UINT8 DriverOptionToBeDeleted[100];
//
// Boot Option Delete storage
//
UINT8 BootOptionDel[100];
UINT8 DriverOptionDel[100];
//
// This is the Terminal Attributes value storage
//
UINT8 COMBaudRate;
UINT8 COMDataRate;
UINT8 COMStopBits;
UINT8 COMParity;
UINT8 COMTerminalType;
//
// Legacy Device Order Selection Storage
//
UINT8 LegacyFD[100];
UINT8 LegacyHD[100];
UINT8 LegacyCD[100];
UINT8 LegacyNET[100];
UINT8 LegacyBEV[100];
//
// We use DisableMap array to record the enable/disable state of each boot device
// It should be taken as a bit array, from left to right there are totally 256 bits
// the most left one stands for BBS table item 0, and the most right one stands for item 256
// If the bit is 1, it means the boot device has been disabled.
//
UINT8 DisableMap[32];
//
// Console Output Text Mode
//
UINT16 ConsoleOutMode;
//
// UINT16 PadArea[10];
//
} BMM_FAKE_NV_DATA;
//
// Key used by File Explorer forms
//
#define KEY_VALUE_SAVE_AND_EXIT_BOOT 0x1000
#define KEY_VALUE_NO_SAVE_AND_EXIT_BOOT 0x1001
#define KEY_VALUE_SAVE_AND_EXIT_DRIVER 0x1002
#define KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER 0x1003
///
/// This is the data structure used by File Explorer formset
///
typedef struct {
UINT16 DescriptionData[75];
UINT16 OptionalData[127];
UINT8 Active;
UINT8 ForceReconnect;
} FILE_EXPLORER_NV_DATA;
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,299 @@
/** @file
The platform boot manager reference implementation
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "BootManager.h"
UINT16 mKeyInput;
EFI_GUID mBootManagerGuid = BOOT_MANAGER_FORMSET_GUID;
LIST_ENTRY *mBootOptionsList;
BDS_COMMON_OPTION *gOption;
BOOT_MANAGER_CALLBACK_DATA gBootManagerPrivate = {
BOOT_MANAGER_CALLBACK_DATA_SIGNATURE,
NULL,
NULL,
{
FakeExtractConfig,
FakeRouteConfig,
BootManagerCallback
}
};
/**
This call back funtion is registered with Boot Manager formset.
When user selects a boot option, this call back function will
be triggered. The boot option is saved for later processing.
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param Action Specifies the type of action taken by the browser.
@param QuestionId A unique value which is sent to the original exporting driver
so that it can identify the type of data to expect.
@param Type The type of value for the question.
@param Value A pointer to the data being sent to the original exporting driver.
@param ActionRequest On return, points to the action requested by the callback function.
@retval EFI_SUCCESS The callback successfully handled the action.
@retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
**/
EFI_STATUS
EFIAPI
BootManagerCallback (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN EFI_BROWSER_ACTION Action,
IN EFI_QUESTION_ID QuestionId,
IN UINT8 Type,
IN EFI_IFR_TYPE_VALUE *Value,
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
)
{
BDS_COMMON_OPTION *Option;
LIST_ENTRY *Link;
UINT16 KeyCount;
if ((Value == NULL) || (ActionRequest == NULL)) {
return EFI_INVALID_PARAMETER;
}
//
// Initialize the key count
//
KeyCount = 0;
for (Link = mBootOptionsList->ForwardLink; Link != mBootOptionsList; Link = Link->ForwardLink) {
Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
KeyCount++;
gOption = Option;
//
// Is this device the one chosen?
//
if (KeyCount == QuestionId) {
//
// Assigning the returned Key to a global allows the original routine to know what was chosen
//
mKeyInput = QuestionId;
//
// Request to exit SendForm(), so that we could boot the selected option
//
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
break;
}
}
return EFI_SUCCESS;
}
/**
Registers HII packages for the Boot Manger to HII Database.
It also registers the browser call back function.
@return Status of HiiLibCreateHiiDriverHandle() and gHiiDatabase->NewPackageList()
**/
EFI_STATUS
InitializeBootManager (
VOID
)
{
EFI_STATUS Status;
EFI_HII_PACKAGE_LIST_HEADER *PackageList;
//
// Create driver handle used by HII database
//
Status = HiiLibCreateHiiDriverHandle (&gBootManagerPrivate.DriverHandle);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Install Config Access protocol to driver handle
//
Status = gBS->InstallProtocolInterface (
&gBootManagerPrivate.DriverHandle,
&gEfiHiiConfigAccessProtocolGuid,
EFI_NATIVE_INTERFACE,
&gBootManagerPrivate.ConfigAccess
);
ASSERT_EFI_ERROR (Status);
//
// Publish our HII data
//
PackageList = HiiLibPreparePackageList (2, &mBootManagerGuid, BootManagerVfrBin, BdsDxeStrings);
ASSERT (PackageList != NULL);
Status = gHiiDatabase->NewPackageList (
gHiiDatabase,
PackageList,
gBootManagerPrivate.DriverHandle,
&gBootManagerPrivate.HiiHandle
);
FreePool (PackageList);
return Status;
}
/**
This funtion invokees Boot Manager. If all devices have not a chance to be connected,
the connect all will be triggered. It then enumerate all boot options. If
a boot option from the Boot Manager page is selected, Boot Manager will boot
from this boot option.
**/
VOID
CallBootManager (
VOID
)
{
EFI_STATUS Status;
BDS_COMMON_OPTION *Option;
LIST_ENTRY *Link;
EFI_HII_UPDATE_DATA UpdateData;
CHAR16 *ExitData;
UINTN ExitDataSize;
EFI_STRING_ID Token;
EFI_INPUT_KEY Key;
LIST_ENTRY BdsBootOptionList;
CHAR16 *HelpString;
EFI_STRING_ID HelpToken;
UINT16 *TempStr;
EFI_HII_HANDLE HiiHandle;
EFI_BROWSER_ACTION_REQUEST ActionRequest;
UINTN TempSize;
gOption = NULL;
InitializeListHead (&BdsBootOptionList);
//
// Connect all prior to entering the platform setup menu.
//
if (!gConnectAllHappened) {
BdsLibConnectAllDriversToAllControllers ();
gConnectAllHappened = TRUE;
}
//
// BugBug: Here we can not remove the legacy refresh macro, so we need
// get the boot order every time from "BootOrder" variable.
// Recreate the boot option list base on the BootOrder variable
//
BdsLibEnumerateAllBootOption (&BdsBootOptionList);
mBootOptionsList = &BdsBootOptionList;
HiiHandle = gBootManagerPrivate.HiiHandle;
//
// Allocate space for creation of UpdateData Buffer
//
UpdateData.BufferSize = 0x1000;
UpdateData.Offset = 0;
UpdateData.Data = AllocateZeroPool (0x1000);
ASSERT (UpdateData.Data != NULL);
mKeyInput = 0;
for (Link = BdsBootOptionList.ForwardLink; Link != &BdsBootOptionList; Link = Link->ForwardLink) {
Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
//
// At this stage we are creating a menu entry, thus the Keys are reproduceable
//
mKeyInput++;
//
// Don't display the boot option marked as LOAD_OPTION_HIDDEN
//
if (Option->Attribute & LOAD_OPTION_HIDDEN) {
continue;
}
HiiLibNewString (HiiHandle, &Token, Option->Description);
TempStr = DevicePathToStr (Option->DevicePath);
TempSize = StrSize (TempStr);
HelpString = AllocateZeroPool (TempSize + StrSize (L"Device Path : "));
ASSERT (HelpString != NULL);
StrCat (HelpString, L"Device Path : ");
StrCat (HelpString, TempStr);
HiiLibNewString (HiiHandle, &HelpToken, HelpString);
CreateActionOpCode (
mKeyInput,
Token,
HelpToken,
EFI_IFR_FLAG_CALLBACK,
0,
&UpdateData
);
}
IfrLibUpdateForm (
HiiHandle,
&mBootManagerGuid,
BOOT_MANAGER_FORM_ID,
LABEL_BOOT_OPTION,
FALSE,
&UpdateData
);
FreePool (UpdateData.Data);
ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
Status = gFormBrowser2->SendForm (
gFormBrowser2,
&HiiHandle,
1,
NULL,
0,
NULL,
&ActionRequest
);
if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
EnableResetRequired ();
}
if (gOption == NULL) {
return ;
}
//
//Will leave browser, check any reset required change is applied? if yes, reset system
//
SetupResetReminder ();
//
// parse the selected option
//
Status = BdsLibBootViaBootOption (gOption, gOption->DevicePath, &ExitDataSize, &ExitData);
if (!EFI_ERROR (Status)) {
gOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED));
PlatformBdsBootSuccess (gOption);
} else {
gOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_FAILED));
PlatformBdsBootFail (gOption, Status, ExitData, ExitDataSize);
gST->ConOut->OutputString (
gST->ConOut,
GetStringById (STRING_TOKEN (STR_ANY_KEY_CONTINUE))
);
gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
}
}

View File

@ -0,0 +1,108 @@
/** @file
The platform boot manager reference implement
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _EFI_BOOT_MANAGER_H_
#define _EFI_BOOT_MANAGER_H_
#include "Bds.h"
#include "FrontPage.h"
//
// These are defined as the same with vfr file
//
#define BOOT_MANAGER_FORMSET_GUID \
{ \
0x847bc3fe, 0xb974, 0x446d, {0x94, 0x49, 0x5a, 0xd5, 0x41, 0x2e, 0x99, 0x3b} \
}
#define BOOT_MANAGER_FORM_ID 0x1000
#define LABEL_BOOT_OPTION 0x00
//
// These are the VFR compiler generated data representing our VFR data.
//
extern UINT8 BootManagerVfrBin[];
#define BOOT_MANAGER_CALLBACK_DATA_SIGNATURE SIGNATURE_32 ('B', 'M', 'C', 'B')
typedef struct {
UINTN Signature;
//
// HII relative handles
//
EFI_HII_HANDLE HiiHandle;
EFI_HANDLE DriverHandle;
//
// Produced protocols
//
EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
} BOOT_MANAGER_CALLBACK_DATA;
/**
This call back funtion is registered with Boot Manager formset.
When user selects a boot option, this call back function will
be triggered. The boot option is saved for later processing.
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param Action Specifies the type of action taken by the browser.
@param QuestionId A unique value which is sent to the original exporting driver
so that it can identify the type of data to expect.
@param Type The type of value for the question.
@param Value A pointer to the data being sent to the original exporting driver.
@param ActionRequest On return, points to the action requested by the callback function.
@retval EFI_SUCCESS The callback successfully handled the action.
@retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
**/
EFI_STATUS
EFIAPI
BootManagerCallback (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN EFI_BROWSER_ACTION Action,
IN EFI_QUESTION_ID QuestionId,
IN UINT8 Type,
IN EFI_IFR_TYPE_VALUE *Value,
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
);
/**
Registers HII packages for the Boot Manger to HII Database.
It also registers the browser call back function.
@return Status of HiiLibCreateHiiDriverHandle() and gHiiDatabase->NewPackageList()
**/
EFI_STATUS
InitializeBootManager (
VOID
);
/**
This funtion invokees Boot Manager. If all devices have not a chance to be connected,
the connect all will be triggered. It then enumerate all boot options. If
a boot option from the Boot Manager page is selected, Boot Manager will boot
from this boot option.
**/
VOID
CallBootManager (
VOID
);
#endif

View File

@ -0,0 +1,51 @@
///** @file
//
// Browser formset.
//
// Copyright (c) 2004 - 2008, Intel Corporation. <BR>
// All rights reserved. This program and the accompanying materials
// are licensed and made available under the terms and conditions of the BSD License
// which accompanies this distribution. The full text of the license may be found at
// http://opensource.org/licenses/bsd-license.php
//
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
//
//**/
#define FORMSET_GUID { 0x847bc3fe, 0xb974, 0x446d, 0x94, 0x49, 0x5a, 0xd5, 0x41, 0x2e, 0x99, 0x3b }
#define BOOT_MANAGER_FORM_ID 0x1000
#define LABEL_BOOT_OPTION 0x00
#define LABEL_BOOT_OPTION_END 0x01
#define BOOT_MANAGER_CLASS 0x00
#define BOOT_MANAGER_SUBCLASS 0x00
formset
guid = FORMSET_GUID,
title = STRING_TOKEN(STR_BM_BANNER),
help = STRING_TOKEN(STR_LAST_STRING),
class = BOOT_MANAGER_CLASS,
subclass = BOOT_MANAGER_SUBCLASS,
form formid = BOOT_MANAGER_FORM_ID,
title = STRING_TOKEN(STR_BM_BANNER);
subtitle text = STRING_TOKEN(STR_LAST_STRING);
subtitle text = STRING_TOKEN(STR_BOOT_OPTION_BANNER);
subtitle text = STRING_TOKEN(STR_LAST_STRING);
//
// This is where we will dynamically add choices for the Boot Manager
//
label LABEL_BOOT_OPTION;
label LABEL_BOOT_OPTION_END;
subtitle text = STRING_TOKEN(STR_LAST_STRING);
subtitle text = STRING_TOKEN(STR_HELP_FOOTER);
endform;
endformset;

View File

@ -0,0 +1,257 @@
/** @file
BDS routines to handle capsules.
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Bds.h"
/**
This function locks the block
@param CpuIo A instance of EFI_CPU_IO_PROTOCOL.
@param Base The base address flash region to be locked.
**/
VOID
BdsLockFv (
IN EFI_CPU_IO_PROTOCOL *CpuIo,
IN EFI_PHYSICAL_ADDRESS Base
)
{
EFI_FV_BLOCK_MAP_ENTRY *BlockMap;
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
EFI_PHYSICAL_ADDRESS BaseAddress;
UINT8 Data;
UINT32 BlockLength;
UINTN Index;
BaseAddress = Base - 0x400000 + 2;
FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) (Base));
BlockMap = &(FvHeader->BlockMap[0]);
while ((BlockMap->NumBlocks != 0) && (BlockMap->Length != 0)) {
BlockLength = BlockMap->Length;
for (Index = 0; Index < BlockMap->NumBlocks; Index++) {
CpuIo->Mem.Read (
CpuIo,
EfiCpuIoWidthUint8,
BaseAddress,
1,
&Data
);
Data = (UINT8) (Data | 0x3);
CpuIo->Mem.Write (
CpuIo,
EfiCpuIoWidthUint8,
BaseAddress,
1,
&Data
);
BaseAddress += BlockLength;
}
BlockMap++;
}
}
/**
This routine is called to see if there are any capsules we need to process.
If the boot mode is not UPDATE, then we do nothing. Otherwise find the
capsule HOBS and produce firmware volumes for them via the DXE service.
Then call the dispatcher to dispatch drivers from them. Finally, check
the status of the updates.
This function should be called by BDS in case we need to do some
sort of processing even if there is no capsule to process. We
need to do this if an earlier update went away and we need to
clear the capsule variable so on the next reset PEI does not see it and
think there is a capsule available.
@param BootMode the current boot mode
@retval EFI_INVALID_PARAMETER boot mode is not correct for an update
@retval EFI_SUCCESS There is no error when processing capsule
**/
EFI_STATUS
ProcessCapsules (
EFI_BOOT_MODE BootMode
)
{
EFI_STATUS Status;
EFI_PEI_HOB_POINTERS HobPointer;
EFI_CAPSULE_HEADER *CapsuleHeader;
UINT32 Size;
UINT32 CapsuleNumber;
UINT32 CapsuleTotalNumber;
EFI_CAPSULE_TABLE *CapsuleTable;
UINT32 Index;
UINT32 CacheIndex;
UINT32 CacheNumber;
VOID **CapsulePtr;
VOID **CapsulePtrCache;
EFI_GUID *CapsuleGuidCache;
CAPSULE_HOB_INFO *CapsuleHobInfo;
CapsuleNumber = 0;
CapsuleTotalNumber = 0;
CacheIndex = 0;
CacheNumber = 0;
CapsulePtr = NULL;
CapsulePtrCache = NULL;
CapsuleGuidCache = NULL;
//
// We don't do anything else if the boot mode is not flash-update
//
if (BootMode != BOOT_ON_FLASH_UPDATE) {
return EFI_INVALID_PARAMETER;
}
Status = EFI_SUCCESS;
//
// Find all capsule images from hob
//
HobPointer.Raw = GetHobList ();
while ((HobPointer.Raw = GetNextGuidHob (&gEfiCapsuleVendorGuid, HobPointer.Raw)) != NULL) {
CapsuleTotalNumber ++;
HobPointer.Raw = GET_NEXT_HOB (HobPointer);
}
if (CapsuleTotalNumber == 0) {
//
// We didn't find a hob, so had no errors.
//
PlatformBdsLockNonUpdatableFlash ();
return EFI_SUCCESS;
}
//
// Init temp Capsule Data table.
//
CapsulePtr = (VOID **) AllocateZeroPool (sizeof (VOID *) * CapsuleTotalNumber);
ASSERT (CapsulePtr != NULL);
CapsulePtrCache = (VOID **) AllocateZeroPool (sizeof (VOID *) * CapsuleTotalNumber);
ASSERT (CapsulePtrCache != NULL);
CapsuleGuidCache = (EFI_GUID *) AllocateZeroPool (sizeof (EFI_GUID) * CapsuleTotalNumber);
ASSERT (CapsuleGuidCache != NULL);
//
// Find all capsule images from hob
//
HobPointer.Raw = GetHobList ();
while ((HobPointer.Raw = GetNextGuidHob (&gEfiCapsuleVendorGuid, HobPointer.Raw)) != NULL) {
CapsuleHobInfo = GET_GUID_HOB_DATA (HobPointer.Guid);
CapsulePtr [CapsuleNumber++] = (VOID *)(UINTN)(CapsuleHobInfo->BaseAddress);
HobPointer.Raw = GET_NEXT_HOB (HobPointer);
}
//
//Check the capsule flags,if contains CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE, install
//capsuleTable to configure table with EFI_CAPSULE_GUID
//
//
// Capsules who have CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE always are used for operating
// System to have information persist across a system reset. EFI System Table must
// point to an array of capsules that contains the same CapsuleGuid value. And agents
// searching for this type capsule will look in EFI System Table and search for the
// capsule's Guid and associated pointer to retrieve the data. Two steps below describes
// how to sorting the capsules by the unique guid and install the array to EFI System Table.
// Firstly, Loop for all coalesced capsules, record unique CapsuleGuids and cache them in an
// array for later sorting capsules by CapsuleGuid.
//
for (Index = 0; Index < CapsuleTotalNumber; Index++) {
CapsuleHeader = (EFI_CAPSULE_HEADER*) CapsulePtr [Index];
if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0) {
//
// For each capsule, we compare it with known CapsuleGuid in the CacheArray.
// If already has the Guid, skip it. Whereas, record it in the CacheArray as
// an additional one.
//
CacheIndex = 0;
while (CacheIndex < CacheNumber) {
if (CompareGuid(&CapsuleGuidCache[CacheIndex],&CapsuleHeader->CapsuleGuid)) {
break;
}
CacheIndex++;
}
if (CacheIndex == CacheNumber) {
CopyMem(&CapsuleGuidCache[CacheNumber++],&CapsuleHeader->CapsuleGuid,sizeof(EFI_GUID));
}
}
}
//
// Secondly, for each unique CapsuleGuid in CacheArray, gather all coalesced capsules
// whose guid is the same as it, and malloc memory for an array which preceding
// with UINT32. The array fills with entry point of capsules that have the same
// CapsuleGuid, and UINT32 represents the size of the array of capsules. Then install
// this array into EFI System Table, so that agents searching for this type capsule
// will look in EFI System Table and search for the capsule's Guid and associated
// pointer to retrieve the data.
//
CacheIndex = 0;
while (CacheIndex < CacheNumber) {
CapsuleNumber = 0;
for (Index = 0; Index < CapsuleTotalNumber; Index++) {
CapsuleHeader = (EFI_CAPSULE_HEADER*) CapsulePtr [Index];
if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0) {
if (CompareGuid (&CapsuleGuidCache[CacheIndex], &CapsuleHeader->CapsuleGuid)) {
//
// Cache Caspuleheader to the array, this array is uniqued with certain CapsuleGuid.
//
CapsulePtrCache[CapsuleNumber++] = (VOID*)CapsuleHeader;
}
}
}
if (CapsuleNumber != 0) {
Size = sizeof(EFI_CAPSULE_TABLE) + (CapsuleNumber - 1) * sizeof(VOID*);
CapsuleTable = AllocateRuntimePool (Size);
ASSERT (CapsuleTable != NULL);
CapsuleTable->CapsuleArrayNumber = CapsuleNumber;
CopyMem(&CapsuleTable->CapsulePtr[0], CapsulePtrCache, CapsuleNumber * sizeof(VOID*));
Status = gBS->InstallConfigurationTable (&CapsuleGuidCache[CacheIndex], (VOID*)CapsuleTable);
ASSERT_EFI_ERROR (Status);
}
CacheIndex++;
}
//
// Besides ones with CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flag, all capsules left are
// recognized by platform with CapsuleGuid. For general platform driver, UpdateFlash
// type is commonly supported, so here only deal with encapsuled FVs capsule. Additional
// type capsule transaction could be extended. It depends on platform policy.
//
for (Index = 0; Index < CapsuleTotalNumber; Index++) {
CapsuleHeader = (EFI_CAPSULE_HEADER*) CapsulePtr [Index];
if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) {
//
// Call capsule library to process capsule image.
//
ProcessCapsuleImage (CapsuleHeader);
}
}
PlatformBdsLockNonUpdatableFlash ();
//
// Free the allocated temp memory space.
//
FreePool (CapsuleGuidCache);
FreePool (CapsulePtrCache);
FreePool (CapsulePtr);
return Status;
}

View File

@ -0,0 +1,409 @@
/** @file
The platform device manager reference implementation
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "DeviceManager.h"
DEVICE_MANAGER_CALLBACK_DATA gDeviceManagerPrivate = {
DEVICE_MANAGER_CALLBACK_DATA_SIGNATURE,
NULL,
NULL,
{
FakeExtractConfig,
FakeRouteConfig,
DeviceManagerCallback
}
};
EFI_GUID mDeviceManagerGuid = DEVICE_MANAGER_FORMSET_GUID;
DEVICE_MANAGER_MENU_ITEM mDeviceManagerMenuItemTable[] = {
{ STRING_TOKEN (STR_DISK_DEVICE), EFI_DISK_DEVICE_CLASS },
{ STRING_TOKEN (STR_VIDEO_DEVICE), EFI_VIDEO_DEVICE_CLASS },
{ STRING_TOKEN (STR_NETWORK_DEVICE), EFI_NETWORK_DEVICE_CLASS },
{ STRING_TOKEN (STR_INPUT_DEVICE), EFI_INPUT_DEVICE_CLASS },
{ STRING_TOKEN (STR_ON_BOARD_DEVICE), EFI_ON_BOARD_DEVICE_CLASS },
{ STRING_TOKEN (STR_OTHER_DEVICE), EFI_OTHER_DEVICE_CLASS }
};
#define MENU_ITEM_NUM \
(sizeof (mDeviceManagerMenuItemTable) / sizeof (DEVICE_MANAGER_MENU_ITEM))
/**
This function is invoked if user selected a iteractive opcode from Device Manager's
Formset. The decision by user is saved to gCallbackKey for later processing. If
user set VBIOS, the new value is saved to EFI variable.
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param Action Specifies the type of action taken by the browser.
@param QuestionId A unique value which is sent to the original exporting driver
so that it can identify the type of data to expect.
@param Type The type of value for the question.
@param Value A pointer to the data being sent to the original exporting driver.
@param ActionRequest On return, points to the action requested by the callback function.
@retval EFI_SUCCESS The callback successfully handled the action.
@retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
**/
EFI_STATUS
EFIAPI
DeviceManagerCallback (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN EFI_BROWSER_ACTION Action,
IN EFI_QUESTION_ID QuestionId,
IN UINT8 Type,
IN EFI_IFR_TYPE_VALUE *Value,
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
)
{
DEVICE_MANAGER_CALLBACK_DATA *PrivateData;
if ((Value == NULL) || (ActionRequest == NULL)) {
return EFI_INVALID_PARAMETER;
}
PrivateData = DEVICE_MANAGER_CALLBACK_DATA_FROM_THIS (This);
switch (QuestionId) {
case DEVICE_MANAGER_KEY_VBIOS:
PrivateData->VideoBios = Value->u8;
gRT->SetVariable (
L"VBIOS",
&gEfiGenericPlatformVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
sizeof (UINT8),
&PrivateData->VideoBios
);
//
// Tell browser not to ask for confirmation of changes,
// since we have already applied.
//
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
break;
default:
//
// The key corresponds the Handle Index which was requested to be displayed
//
gCallbackKey = QuestionId;
//
// Request to exit SendForm(), so as to switch to selected form
//
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
break;
}
return EFI_SUCCESS;
}
/**
This function registers HII packages to HII database.
@retval EFI_SUCCESS This function complete successfully.
@return Other value if failed to register HII packages.
**/
EFI_STATUS
InitializeDeviceManager (
VOID
)
{
EFI_STATUS Status;
EFI_HII_PACKAGE_LIST_HEADER *PackageList;
//
// Create driver handle used by HII database
//
Status = HiiLibCreateHiiDriverHandle (&gDeviceManagerPrivate.DriverHandle);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Install Config Access protocol to driver handle
//
Status = gBS->InstallProtocolInterface (
&gDeviceManagerPrivate.DriverHandle,
&gEfiHiiConfigAccessProtocolGuid,
EFI_NATIVE_INTERFACE,
&gDeviceManagerPrivate.ConfigAccess
);
ASSERT_EFI_ERROR (Status);
//
// Publish our HII data
//
PackageList = HiiLibPreparePackageList (2, &mDeviceManagerGuid, DeviceManagerVfrBin, BdsDxeStrings);
ASSERT (PackageList != NULL);
Status = gHiiDatabase->NewPackageList (
gHiiDatabase,
PackageList,
gDeviceManagerPrivate.DriverHandle,
&gDeviceManagerPrivate.HiiHandle
);
FreePool (PackageList);
return Status;
}
/**
Call the browser and display the device manager to allow user
to configure the platform.
This function create the dynamic content for device manager. It includes
section header for all class of devices, one-of opcode to set VBIOS.
@retval EFI_SUCCESS Operation is successful.
@return Other values if failed to clean up the dynamic content from HII
database.
**/
EFI_STATUS
CallDeviceManager (
VOID
)
{
EFI_STATUS Status;
UINTN Count;
UINTN Index;
CHAR16 *String;
UINTN StringLength;
EFI_HII_UPDATE_DATA UpdateData[MENU_ITEM_NUM];
EFI_STRING_ID Token;
EFI_STRING_ID TokenHelp;
IFR_OPTION *IfrOptionList;
UINT8 *VideoOption;
UINTN VideoOptionSize;
EFI_HII_HANDLE *HiiHandles;
UINTN HandleBufferLength;
UINTN NumberOfHiiHandles;
EFI_HII_HANDLE HiiHandle;
UINT16 FormSetClass;
EFI_STRING_ID FormSetTitle;
EFI_STRING_ID FormSetHelp;
EFI_BROWSER_ACTION_REQUEST ActionRequest;
EFI_HII_PACKAGE_LIST_HEADER *PackageList;
IfrOptionList = NULL;
VideoOption = NULL;
HiiHandles = NULL;
HandleBufferLength = 0;
Status = EFI_SUCCESS;
gCallbackKey = 0;
//
// Connect all prior to entering the platform setup menu.
//
if (!gConnectAllHappened) {
BdsLibConnectAllDriversToAllControllers ();
gConnectAllHappened = TRUE;
}
//
// Create Subtitle OpCodes
//
for (Index = 0; Index < MENU_ITEM_NUM; Index++) {
//
// Allocate space for creation of UpdateData Buffer
//
UpdateData[Index].BufferSize = 0x1000;
UpdateData[Index].Offset = 0;
UpdateData[Index].Data = AllocatePool (0x1000);
ASSERT (UpdateData[Index].Data != NULL);
CreateSubTitleOpCode (mDeviceManagerMenuItemTable[Index].StringId, 0, 0, 1, &UpdateData[Index]);
}
//
// Get all the Hii handles
//
Status = HiiLibGetHiiHandles (&HandleBufferLength, &HiiHandles);
ASSERT_EFI_ERROR (Status && (HiiHandles != NULL));
HiiHandle = gDeviceManagerPrivate.HiiHandle;
StringLength = 0x1000;
String = AllocateZeroPool (StringLength);
ASSERT (String != NULL);
//
// Search for formset of each class type
//
NumberOfHiiHandles = HandleBufferLength / sizeof (EFI_HII_HANDLE);
for (Index = 0; Index < NumberOfHiiHandles; Index++) {
IfrLibExtractClassFromHiiHandle (HiiHandles[Index], &FormSetClass, &FormSetTitle, &FormSetHelp);
if (FormSetClass == EFI_NON_DEVICE_CLASS) {
continue;
}
Token = 0;
*String = 0;
StringLength = 0x1000;
HiiLibGetString (HiiHandles[Index], FormSetTitle, String, &StringLength);
HiiLibNewString (HiiHandle, &Token, String);
TokenHelp = 0;
*String = 0;
StringLength = 0x1000;
HiiLibGetString (HiiHandles[Index], FormSetHelp, String, &StringLength);
HiiLibNewString (HiiHandle, &TokenHelp, String);
for (Count = 0; Count < MENU_ITEM_NUM; Count++) {
if (FormSetClass & mDeviceManagerMenuItemTable[Count].Class) {
CreateActionOpCode (
(EFI_QUESTION_ID) (Index + DEVICE_KEY_OFFSET),
Token,
TokenHelp,
EFI_IFR_FLAG_CALLBACK,
0,
&UpdateData[Count]
);
}
}
}
FreePool (String);
for (Index = 0; Index < MENU_ITEM_NUM; Index++) {
//
// Add End Opcode for Subtitle
//
CreateEndOpCode (&UpdateData[Index]);
IfrLibUpdateForm (
HiiHandle,
&mDeviceManagerGuid,
DEVICE_MANAGER_FORM_ID,
mDeviceManagerMenuItemTable[Index].Class,
FALSE,
&UpdateData[Index]
);
}
//
// Add oneof for video BIOS selection
//
VideoOption = BdsLibGetVariableAndSize (
L"VBIOS",
&gEfiGenericPlatformVariableGuid,
&VideoOptionSize
);
if (VideoOption == NULL) {
gDeviceManagerPrivate.VideoBios = 0;
} else {
gDeviceManagerPrivate.VideoBios = VideoOption[0];
FreePool (VideoOption);
}
ASSERT (gDeviceManagerPrivate.VideoBios <= 1);
IfrOptionList = AllocatePool (2 * sizeof (IFR_OPTION));
ASSERT (IfrOptionList != NULL);
IfrOptionList[0].Flags = 0;
IfrOptionList[0].StringToken = STRING_TOKEN (STR_ONE_OF_PCI);
IfrOptionList[0].Value.u8 = 0;
IfrOptionList[1].Flags = 0;
IfrOptionList[1].StringToken = STRING_TOKEN (STR_ONE_OF_AGP);
IfrOptionList[1].Value.u8 = 1;
IfrOptionList[gDeviceManagerPrivate.VideoBios].Flags |= EFI_IFR_OPTION_DEFAULT;
UpdateData[0].Offset = 0;
CreateOneOfOpCode (
DEVICE_MANAGER_KEY_VBIOS,
0,
0,
STRING_TOKEN (STR_ONE_OF_VBIOS),
STRING_TOKEN (STR_ONE_OF_VBIOS_HELP),
EFI_IFR_FLAG_CALLBACK,
EFI_IFR_NUMERIC_SIZE_1,
IfrOptionList,
2,
&UpdateData[0]
);
IfrLibUpdateForm (
HiiHandle,
&mDeviceManagerGuid,
DEVICE_MANAGER_FORM_ID,
LABEL_VBIOS,
FALSE,
&UpdateData[0]
);
ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
Status = gFormBrowser2->SendForm (
gFormBrowser2,
&HiiHandle,
1,
NULL,
0,
NULL,
&ActionRequest
);
if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
EnableResetRequired ();
}
//
// We will have returned from processing a callback - user either hit ESC to exit, or selected
// a target to display
//
if (gCallbackKey != 0) {
ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
Status = gFormBrowser2->SendForm (
gFormBrowser2,
&HiiHandles[gCallbackKey - DEVICE_KEY_OFFSET],
1,
NULL,
0,
NULL,
&ActionRequest
);
if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
EnableResetRequired ();
}
//
// Force return to Device Manager
//
gCallbackKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
}
//
// Cleanup dynamic created strings in HII database by reinstall the packagelist
//
gHiiDatabase->RemovePackageList (gHiiDatabase, HiiHandle);
PackageList = HiiLibPreparePackageList (2, &mDeviceManagerGuid, DeviceManagerVfrBin, BdsDxeStrings);
ASSERT (PackageList != NULL);
Status = gHiiDatabase->NewPackageList (
gHiiDatabase,
PackageList,
gDeviceManagerPrivate.DriverHandle,
&gDeviceManagerPrivate.HiiHandle
);
FreePool (PackageList);
for (Index = 0; Index < MENU_ITEM_NUM; Index++) {
FreePool (UpdateData[Index].Data);
}
FreePool (HiiHandles);
return Status;
}

View File

@ -0,0 +1,134 @@
/** @file
The platform device manager reference implement
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _DEVICE_MANAGER_H_
#define _DEVICE_MANAGER_H_
#include "Bds.h"
#include "FrontPage.h"
//
// These are defined as the same with vfr file
//
#define DEVICE_MANAGER_FORMSET_GUID \
{ \
0x3ebfa8e6, 0x511d, 0x4b5b, {0xa9, 0x5f, 0xfb, 0x38, 0x26, 0xf, 0x1c, 0x27} \
}
#define LABEL_VBIOS 0x0040
#define DEVICE_MANAGER_FORM_ID 0x1000
#define DEVICE_KEY_OFFSET 0x1000
#define DEVICE_MANAGER_KEY_VBIOS 0x2000
//
// These are the VFR compiler generated data representing our VFR data.
//
extern UINT8 DeviceManagerVfrBin[];
#define DEVICE_MANAGER_CALLBACK_DATA_SIGNATURE SIGNATURE_32 ('D', 'M', 'C', 'B')
typedef struct {
UINTN Signature;
///
/// HII relative handles
///
EFI_HII_HANDLE HiiHandle;
EFI_HANDLE DriverHandle;
///
/// Produced protocols
///
EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
///
/// Configuration data
///
UINT8 VideoBios;
} DEVICE_MANAGER_CALLBACK_DATA;
#define DEVICE_MANAGER_CALLBACK_DATA_FROM_THIS(a) \
CR (a, \
DEVICE_MANAGER_CALLBACK_DATA, \
ConfigAccess, \
DEVICE_MANAGER_CALLBACK_DATA_SIGNATURE \
)
typedef struct {
EFI_STRING_ID StringId;
UINT16 Class;
} DEVICE_MANAGER_MENU_ITEM;
/**
This function is invoked if user selected a iteractive opcode from Device Manager's
Formset. The decision by user is saved to gCallbackKey for later processing. If
user set VBIOS, the new value is saved to EFI variable.
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param Action Specifies the type of action taken by the browser.
@param QuestionId A unique value which is sent to the original exporting driver
so that it can identify the type of data to expect.
@param Type The type of value for the question.
@param Value A pointer to the data being sent to the original exporting driver.
@param ActionRequest On return, points to the action requested by the callback function.
@retval EFI_SUCCESS The callback successfully handled the action.
@retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
**/
EFI_STATUS
EFIAPI
DeviceManagerCallback (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN EFI_BROWSER_ACTION Action,
IN EFI_QUESTION_ID QuestionId,
IN UINT8 Type,
IN EFI_IFR_TYPE_VALUE *Value,
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
);
/**
This function registers HII packages to HII database.
@retval EFI_SUCCESS This function complete successfully.
@return Other value if failed to register HII packages.
**/
EFI_STATUS
InitializeDeviceManager (
VOID
);
/**
Call the browser and display the device manager to allow user
to configure the platform.
This function create the dynamic content for device manager. It includes
section header for all class of devices, one-of opcode to set VBIOS.
@retval EFI_SUCCESS Operation is successful.
@retval Other values if failed to clean up the dynamic content from HII
database.
**/
EFI_STATUS
CallDeviceManager (
VOID
);
#endif

View File

@ -0,0 +1,74 @@
///** @file
//
// Device Manager formset.
//
// Copyright (c) 2004 - 2008, Intel Corporation. <BR>
// All rights reserved. This program and the accompanying materials
// are licensed and made available under the terms and conditions of the BSD License
// which accompanies this distribution. The full text of the license may be found at
// http://opensource.org/licenses/bsd-license.php
//
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
//
//**/
#define FORMSET_GUID { 0x3ebfa8e6, 0x511d, 0x4b5b, 0xa9, 0x5f, 0xfb, 0x38, 0x26, 0xf, 0x1c, 0x27 }
#define EFI_DISK_DEVICE_CLASS 0x0001
#define EFI_VIDEO_DEVICE_CLASS 0x0002
#define EFI_NETWORK_DEVICE_CLASS 0x0004
#define EFI_INPUT_DEVICE_CLASS 0x0008
#define EFI_ON_BOARD_DEVICE_CLASS 0x0010
#define EFI_OTHER_DEVICE_CLASS 0x0020
#define LABEL_VBIOS 0x0040
#define LABEL_END 0xffff
#define DEVICE_MANAGER_CLASS 0x0000
#define FRONT_PAGE_SUBCLASS 0x0003
#define DEVICE_MANAGER_FORM_ID 0x1000
formset
guid = FORMSET_GUID,
title = STRING_TOKEN(STR_DEVICE_MANAGER_TITLE),
help = STRING_TOKEN(STR_EMPTY_STRING),
class = DEVICE_MANAGER_CLASS,
subclass = FRONT_PAGE_SUBCLASS,
form formid = DEVICE_MANAGER_FORM_ID,
title = STRING_TOKEN(STR_DEVICE_MANAGER_TITLE);
//
// This is where devices get added to the device manager hierarchy
//
label EFI_DISK_DEVICE_CLASS;
// label LABEL_END; // Since next opcode is a label, so this one could be omitted to save code size
label EFI_VIDEO_DEVICE_CLASS;
// label LABEL_END;
label EFI_NETWORK_DEVICE_CLASS;
// label LABEL_END;
label EFI_INPUT_DEVICE_CLASS;
// label LABEL_END;
label EFI_ON_BOARD_DEVICE_CLASS;
// label LABEL_END;
label EFI_OTHER_DEVICE_CLASS;
label LABEL_END;
subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
label LABEL_VBIOS;
label LABEL_END;
subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
subtitle text = STRING_TOKEN(STR_EXIT_STRING);
endform;
endformset;

View File

@ -0,0 +1,976 @@
/** @file
FrontPage routines to handle the callbacks and browser calls
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Bds.h"
#include "FrontPage.h"
EFI_GUID mFrontPageGuid = FRONT_PAGE_FORMSET_GUID;
BOOLEAN gConnectAllHappened = FALSE;
UINTN gCallbackKey;
EFI_HII_DATABASE_PROTOCOL *gHiiDatabase;
EFI_HII_STRING_PROTOCOL *gHiiString;
EFI_FORM_BROWSER2_PROTOCOL *gFormBrowser2;
EFI_HII_CONFIG_ROUTING_PROTOCOL *gHiiConfigRouting;
FRONT_PAGE_CALLBACK_DATA gFrontPagePrivate = {
FRONT_PAGE_CALLBACK_DATA_SIGNATURE,
NULL,
NULL,
NULL,
{
FakeExtractConfig,
FakeRouteConfig,
FrontPageCallback
}
};
/**
This function allows a caller to extract the current configuration for one
or more named elements from the target driver.
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param Request A null-terminated Unicode string in <ConfigRequest> format.
@param Progress On return, points to a character in the Request string.
Points to the string's null terminator if request was successful.
Points to the most recent '&' before the first failing name/value
pair (or the beginning of the string if the failure is in the
first name/value pair) if the request was not successful.
@param Results A null-terminated Unicode string in <ConfigAltResp> format which
has all values filled in for the names in the Request string.
String to be allocated by the called function.
@retval EFI_SUCCESS The Results is filled with the requested values.
@retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
@retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
**/
EFI_STATUS
EFIAPI
FakeExtractConfig (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN CONST EFI_STRING Request,
OUT EFI_STRING *Progress,
OUT EFI_STRING *Results
)
{
return EFI_NOT_FOUND;
}
/**
This function processes the results of changes in configuration.
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param Configuration A null-terminated Unicode string in <ConfigResp> format.
@param Progress A pointer to a string filled in with the offset of the most
recent '&' before the first failing name/value pair (or the
beginning of the string if the failure is in the first
name/value pair) or the terminating NULL if all was successful.
@retval EFI_SUCCESS The Results is processed successfully.
@retval EFI_INVALID_PARAMETER Configuration is NULL.
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
**/
EFI_STATUS
EFIAPI
FakeRouteConfig (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN CONST EFI_STRING Configuration,
OUT EFI_STRING *Progress
)
{
return EFI_SUCCESS;
}
/**
This function processes the results of changes in configuration.
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param Action Specifies the type of action taken by the browser.
@param QuestionId A unique value which is sent to the original exporting driver
so that it can identify the type of data to expect.
@param Type The type of value for the question.
@param Value A pointer to the data being sent to the original exporting driver.
@param ActionRequest On return, points to the action requested by the callback function.
@retval EFI_SUCCESS The callback successfully handled the action.
@retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
@retval EFI_DEVICE_ERROR The variable could not be saved.
@retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
**/
EFI_STATUS
EFIAPI
FrontPageCallback (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN EFI_BROWSER_ACTION Action,
IN EFI_QUESTION_ID QuestionId,
IN UINT8 Type,
IN EFI_IFR_TYPE_VALUE *Value,
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
)
{
CHAR8 *LanguageString;
CHAR8 *LangCode;
CHAR8 Lang[RFC_3066_ENTRY_SIZE];
CHAR8 OldLang[ISO_639_2_ENTRY_SIZE];
UINTN Index;
EFI_STATUS Status;
if ((Value == NULL) || (ActionRequest == NULL)) {
return EFI_INVALID_PARAMETER;
}
gCallbackKey = QuestionId;
//
// The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
// describe to their customers in documentation how to find their setup information (namely
// under the device manager and specific buckets)
//
switch (QuestionId) {
case FRONT_PAGE_KEY_CONTINUE:
//
// This is the continue - clear the screen and return an error to get out of FrontPage loop
//
break;
case FRONT_PAGE_KEY_LANGUAGE:
//
// Collect the languages from what our current Language support is based on our VFR
//
LanguageString = HiiLibGetSupportedLanguages (gFrontPagePrivate.HiiHandle);
ASSERT (LanguageString != NULL);
Index = 0;
LangCode = LanguageString;
while (*LangCode != 0) {
HiiLibGetNextLanguage (&LangCode, Lang);
if (Index == Value->u8) {
break;
}
Index++;
}
Status = gRT->SetVariable (
L"PlatformLang",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
AsciiStrSize (Lang),
Lang
);
if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
//
// Set UEFI deprecated variable "Lang" for backwards compatibility
//
Status = ConvertRfc3066LanguageToIso639Language (Lang, OldLang);
if (!EFI_ERROR (Status)) {
Status = gRT->SetVariable (
L"Lang",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
ISO_639_2_ENTRY_SIZE,
OldLang
);
}
}
FreePool (LanguageString);
break;
case FRONT_PAGE_KEY_BOOT_MANAGER:
//
// Boot Manager
//
break;
case FRONT_PAGE_KEY_DEVICE_MANAGER:
//
// Device Manager
//
break;
case FRONT_PAGE_KEY_BOOT_MAINTAIN:
//
// Boot Maintenance Manager
//
break;
default:
gCallbackKey = 0;
break;
}
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
return EFI_SUCCESS;
}
/**
Initialize HII information for the FrontPage
@param InitializeHiiData TRUE if HII elements need to be initialized.
@retval EFI_SUCCESS The operation is successful.
@retval EFI_DEVICE_ERROR If the dynamic opcode creation failed.
**/
EFI_STATUS
InitializeFrontPage (
IN BOOLEAN InitializeHiiData
)
{
EFI_STATUS Status;
EFI_HII_PACKAGE_LIST_HEADER *PackageList;
EFI_HII_UPDATE_DATA UpdateData;
IFR_OPTION *OptionList;
CHAR8 *LanguageString;
CHAR8 *LangCode;
CHAR8 Lang[RFC_3066_ENTRY_SIZE];
CHAR8 CurrentLang[RFC_3066_ENTRY_SIZE];
UINTN OptionCount;
EFI_STRING_ID Token;
CHAR16 *StringBuffer;
UINTN BufferSize;
UINTN Index;
EFI_HII_HANDLE HiiHandle;
if (InitializeHiiData) {
//
// Initialize the Device Manager
//
InitializeDeviceManager ();
//
// Initialize the Device Manager
//
InitializeBootManager ();
gCallbackKey = 0;
//
// Locate Hii relative protocols
//
Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &gHiiDatabase);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &gHiiString);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &gFormBrowser2);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &gHiiConfigRouting);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Create driver handle used by HII database
//
Status = HiiLibCreateHiiDriverHandle (&gFrontPagePrivate.DriverHandle);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Install Config Access protocol to driver handle
//
Status = gBS->InstallProtocolInterface (
&gFrontPagePrivate.DriverHandle,
&gEfiHiiConfigAccessProtocolGuid,
EFI_NATIVE_INTERFACE,
&gFrontPagePrivate.ConfigAccess
);
ASSERT_EFI_ERROR (Status);
//
// Publish our HII data
//
PackageList = HiiLibPreparePackageList (2, &mFrontPageGuid, FrontPageVfrBin, BdsDxeStrings);
ASSERT (PackageList != NULL);
Status = gHiiDatabase->NewPackageList (
gHiiDatabase,
PackageList,
gFrontPagePrivate.DriverHandle,
&gFrontPagePrivate.HiiHandle
);
FreePool (PackageList);
if (EFI_ERROR (Status)) {
return Status;
}
}
//
// Get current language setting
//
GetCurrentLanguage (CurrentLang);
//
// Allocate space for creation of UpdateData Buffer
//
UpdateData.BufferSize = 0x1000;
UpdateData.Data = AllocateZeroPool (0x1000);
ASSERT (UpdateData.Data != NULL);
OptionList = AllocateZeroPool (0x1000);
ASSERT (OptionList != NULL);
//
// Collect the languages from what our current Language support is based on our VFR
//
HiiHandle = gFrontPagePrivate.HiiHandle;
LanguageString = HiiLibGetSupportedLanguages (HiiHandle);
ASSERT (LanguageString != NULL);
OptionCount = 0;
LangCode = LanguageString;
while (*LangCode != 0) {
HiiLibGetNextLanguage (&LangCode, Lang);
if (gFrontPagePrivate.LanguageToken == NULL) {
//
// Get Language Name from String Package. The StringId of Printable Language
// Name is always 1 which is generated by StringGather Tool.
//
BufferSize = 0x100;
StringBuffer = AllocatePool (BufferSize);
Status = gHiiString->GetString (
gHiiString,
Lang,
HiiHandle,
PRINTABLE_LANGUAGE_NAME_STRING_ID,
StringBuffer,
&BufferSize,
NULL
);
if (Status == EFI_BUFFER_TOO_SMALL) {
FreePool (StringBuffer);
StringBuffer = AllocatePool (BufferSize);
Status = gHiiString->GetString (
gHiiString,
Lang,
HiiHandle,
PRINTABLE_LANGUAGE_NAME_STRING_ID,
StringBuffer,
&BufferSize,
NULL
);
}
ASSERT_EFI_ERROR (Status);
Token = 0;
Status = HiiLibNewString (HiiHandle, &Token, StringBuffer);
FreePool (StringBuffer);
} else {
Token = gFrontPagePrivate.LanguageToken[OptionCount];
}
if (AsciiStrCmp (Lang, CurrentLang) == 0) {
OptionList[OptionCount].Flags = EFI_IFR_OPTION_DEFAULT;
} else {
OptionList[OptionCount].Flags = 0;
}
OptionList[OptionCount].StringToken = Token;
OptionList[OptionCount].Value.u8 = (UINT8) OptionCount;
OptionCount++;
}
FreePool (LanguageString);
UpdateData.Offset = 0;
CreateOneOfOpCode (
FRONT_PAGE_KEY_LANGUAGE,
0,
0,
STRING_TOKEN (STR_LANGUAGE_SELECT),
STRING_TOKEN (STR_LANGUAGE_SELECT_HELP),
EFI_IFR_FLAG_CALLBACK,
EFI_IFR_NUMERIC_SIZE_1,
OptionList,
OptionCount,
&UpdateData
);
Status = IfrLibUpdateForm (
HiiHandle,
&mFrontPageGuid,
FRONT_PAGE_FORM_ID,
LABEL_SELECT_LANGUAGE,
FALSE,
&UpdateData
);
//
// Save the string Id for each language
//
gFrontPagePrivate.LanguageToken = AllocatePool (OptionCount * sizeof (EFI_STRING_ID));
ASSERT (gFrontPagePrivate.LanguageToken != NULL);
for (Index = 0; Index < OptionCount; Index++) {
gFrontPagePrivate.LanguageToken[Index] = OptionList[Index].StringToken;
}
FreePool (UpdateData.Data);
FreePool (OptionList);
return Status;
}
/**
Call the browser and display the front page
@return Status code that will be returned by
EFI_FORM_BROWSER2_PROTOCOL.SendForm ().
**/
EFI_STATUS
CallFrontPage (
VOID
)
{
EFI_STATUS Status;
EFI_BROWSER_ACTION_REQUEST ActionRequest;
//
// Begin waiting for USER INPUT
//
REPORT_STATUS_CODE (
EFI_PROGRESS_CODE,
(EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_INPUT_WAIT)
);
ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
Status = gFormBrowser2->SendForm (
gFormBrowser2,
&gFrontPagePrivate.HiiHandle,
1,
NULL,
0,
NULL,
&ActionRequest
);
//
// Check whether user change any option setting which needs a reset to be effective
//
if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
EnableResetRequired ();
}
return Status;
}
/**
Acquire the string associated with the ProducerGuid and return it.
@param ProducerGuid The Guid to search the HII database for
@param Token The token value of the string to extract
@param String The string that is extracted
@retval EFI_SUCCESS The function returns EFI_SUCCESS always.
**/
EFI_STATUS
GetProducerString (
IN EFI_GUID *ProducerGuid,
IN EFI_STRING_ID Token,
OUT CHAR16 **String
)
{
EFI_STATUS Status;
Status = HiiLibGetStringFromToken (ProducerGuid, Token, String);
if (EFI_ERROR (Status)) {
*String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));
}
return EFI_SUCCESS;
}
/**
Convert Processor Frequency Data to a string
@param ProcessorFrequency The frequency data to process
@param String The string that is created
**/
VOID
ConvertProcessorToString (
IN EFI_PROCESSOR_CORE_FREQUENCY_DATA *ProcessorFrequency,
OUT CHAR16 **String
)
{
CHAR16 *StringBuffer;
UINTN Index;
UINT32 FreqMhz;
if (ProcessorFrequency->Exponent >= 6) {
FreqMhz = ProcessorFrequency->Value;
for (Index = 0; Index < (UINTN) (ProcessorFrequency->Exponent - 6); Index++) {
FreqMhz *= 10;
}
} else {
FreqMhz = 0;
}
StringBuffer = AllocateZeroPool (0x20);
ASSERT (StringBuffer != NULL);
Index = UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, FreqMhz / 1000, 3);
StrCat (StringBuffer, L".");
UnicodeValueToString (StringBuffer + Index + 1, PREFIX_ZERO, (FreqMhz % 1000) / 10, 2);
StrCat (StringBuffer, L" GHz");
*String = (CHAR16 *) StringBuffer;
return ;
}
/**
Convert Memory Size to a string.
@param MemorySize The size of the memory to process
@param String The string that is created
**/
VOID
ConvertMemorySizeToString (
IN UINT32 MemorySize,
OUT CHAR16 **String
)
{
CHAR16 *StringBuffer;
StringBuffer = AllocateZeroPool (0x20);
ASSERT (StringBuffer != NULL);
UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, MemorySize, 6);
StrCat (StringBuffer, L" MB RAM");
*String = (CHAR16 *) StringBuffer;
return ;
}
/**
Update the banner information for the Front Page based on DataHub information.
**/
VOID
UpdateFrontPageStrings (
VOID
)
{
EFI_STATUS Status;
EFI_STRING_ID TokenToUpdate;
CHAR16 *NewString;
UINT64 MonotonicCount;
EFI_DATA_HUB_PROTOCOL *DataHub;
EFI_DATA_RECORD_HEADER *Record;
EFI_SUBCLASS_TYPE1_HEADER *DataHeader;
EFI_MISC_BIOS_VENDOR_DATA *BiosVendor;
EFI_MISC_SYSTEM_MANUFACTURER_DATA *SystemManufacturer;
EFI_PROCESSOR_VERSION_DATA *ProcessorVersion;
EFI_PROCESSOR_CORE_FREQUENCY_DATA *ProcessorFrequency;
EFI_MEMORY_ARRAY_START_ADDRESS_DATA *MemoryArray;
BOOLEAN Find[5];
ZeroMem (Find, sizeof (Find));
//
// Update Front Page strings
//
Status = gBS->LocateProtocol (
&gEfiDataHubProtocolGuid,
NULL,
(VOID **) &DataHub
);
ASSERT_EFI_ERROR (Status);
MonotonicCount = 0;
Record = NULL;
do {
Status = DataHub->GetNextRecord (DataHub, &MonotonicCount, NULL, &Record);
if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {
DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *) (Record + 1);
if (CompareGuid (&Record->DataRecordGuid, &gEfiMiscSubClassGuid) &&
(DataHeader->RecordType == EFI_MISC_BIOS_VENDOR_RECORD_NUMBER)
) {
BiosVendor = (EFI_MISC_BIOS_VENDOR_DATA *) (DataHeader + 1);
GetProducerString (&Record->ProducerName, BiosVendor->BiosVersion, &NewString);
TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION);
HiiLibSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString);
FreePool (NewString);
Find[0] = TRUE;
}
if (CompareGuid (&Record->DataRecordGuid, &gEfiMiscSubClassGuid) &&
(DataHeader->RecordType == EFI_MISC_SYSTEM_MANUFACTURER_RECORD_NUMBER)
) {
SystemManufacturer = (EFI_MISC_SYSTEM_MANUFACTURER_DATA *) (DataHeader + 1);
GetProducerString (&Record->ProducerName, SystemManufacturer->SystemProductName, &NewString);
TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL);
HiiLibSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString);
FreePool (NewString);
Find[1] = TRUE;
}
if (CompareGuid (&Record->DataRecordGuid, &gEfiProcessorSubClassGuid) &&
(DataHeader->RecordType == ProcessorVersionRecordType)
) {
ProcessorVersion = (EFI_PROCESSOR_VERSION_DATA *) (DataHeader + 1);
GetProducerString (&Record->ProducerName, *ProcessorVersion, &NewString);
TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL);
HiiLibSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString);
FreePool (NewString);
Find[2] = TRUE;
}
if (CompareGuid (&Record->DataRecordGuid, &gEfiProcessorSubClassGuid) &&
(DataHeader->RecordType == ProcessorCoreFrequencyRecordType)
) {
ProcessorFrequency = (EFI_PROCESSOR_CORE_FREQUENCY_DATA *) (DataHeader + 1);
ConvertProcessorToString (ProcessorFrequency, &NewString);
TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED);
HiiLibSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString);
FreePool (NewString);
Find[3] = TRUE;
}
if (CompareGuid (&Record->DataRecordGuid, &gEfiMemorySubClassGuid) &&
(DataHeader->RecordType == EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER)
) {
MemoryArray = (EFI_MEMORY_ARRAY_START_ADDRESS_DATA *) (DataHeader + 1);
ConvertMemorySizeToString (
(UINT32)(RShiftU64((MemoryArray->MemoryArrayEndAddress - MemoryArray->MemoryArrayStartAddress + 1), 20)),
&NewString
);
TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE);
HiiLibSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString);
FreePool (NewString);
Find[4] = TRUE;
}
}
} while (!EFI_ERROR (Status) && (MonotonicCount != 0) && !(Find[0] && Find[1] && Find[2] && Find[3] && Find[4]));
return ;
}
/**
Function waits for a given event to fire, or for an optional timeout to expire.
@param Event The event to wait for
@param Timeout An optional timeout value in 100 ns units.
@retval EFI_SUCCESS Event fired before Timeout expired.
@retval EFI_TIME_OUT Timout expired before Event fired..
**/
EFI_STATUS
WaitForSingleEvent (
IN EFI_EVENT Event,
IN UINT64 Timeout OPTIONAL
)
{
EFI_STATUS Status;
UINTN Index;
EFI_EVENT TimerEvent;
EFI_EVENT WaitList[2];
if (Timeout != 0) {
//
// Create a timer event
//
Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);
if (!EFI_ERROR (Status)) {
//
// Set the timer event
//
gBS->SetTimer (
TimerEvent,
TimerRelative,
Timeout
);
//
// Wait for the original event or the timer
//
WaitList[0] = Event;
WaitList[1] = TimerEvent;
Status = gBS->WaitForEvent (2, WaitList, &Index);
gBS->CloseEvent (TimerEvent);
//
// If the timer expired, change the return to timed out
//
if (!EFI_ERROR (Status) && Index == 1) {
Status = EFI_TIMEOUT;
}
}
} else {
//
// No timeout... just wait on the event
//
Status = gBS->WaitForEvent (1, &Event, &Index);
ASSERT (!EFI_ERROR (Status));
ASSERT (Index == 0);
}
return Status;
}
/**
Function show progress bar to wait for user input.
@param TimeoutDefault The fault time out value before the system continue to boot.
@retval EFI_SUCCESS User pressed some key except "Enter"
@retval EFI_TIME_OUT Timout expired or user press "Enter"
**/
EFI_STATUS
ShowProgress (
IN UINT16 TimeoutDefault
)
{
EFI_STATUS Status;
CHAR16 *TmpStr;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;
EFI_INPUT_KEY Key;
UINT16 TimeoutRemain;
if (TimeoutDefault == 0) {
return EFI_TIMEOUT;
}
DEBUG ((EFI_D_INFO, "\n\nStart showing progress bar... Press any key to stop it! ...Zzz....\n"));
SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
//
// Clear the progress status bar first
//
TmpStr = GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION));
if (TmpStr != NULL) {
PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);
}
TimeoutRemain = TimeoutDefault;
while (TimeoutRemain != 0) {
DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain));
Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);
if (Status != EFI_TIMEOUT) {
break;
}
TimeoutRemain--;
//
// Show progress
//
if (TmpStr != NULL) {
PlatformBdsShowProgress (
Foreground,
Background,
TmpStr,
Color,
((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault),
0
);
}
}
gBS->FreePool (TmpStr);
//
// Timeout expired
//
if (TimeoutRemain == 0) {
return EFI_TIMEOUT;
}
//
// User pressed some key
//
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
if (EFI_ERROR (Status)) {
return Status;
}
if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
//
// User pressed enter, equivalent to select "continue"
//
return EFI_TIMEOUT;
}
return EFI_SUCCESS;
}
/**
This function is the main entry of the platform setup entry.
The function will present the main menu of the system setup,
this is the platform reference part and can be customize.
@param TimeoutDefault The fault time out value before the system
continue to boot.
@param ConnectAllHappened The indicater to check if the connect all have
already happended.
**/
VOID
PlatformBdsEnterFrontPage (
IN UINT16 TimeoutDefault,
IN BOOLEAN ConnectAllHappened
)
{
EFI_STATUS Status;
EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;
PERF_START (0, "BdsTimeOut", "BDS", 0);
//
// Indicate if we need connect all in the platform setup
//
if (ConnectAllHappened) {
gConnectAllHappened = TRUE;
}
if (TimeoutDefault != 0xffff) {
Status = ShowProgress (TimeoutDefault);
//
// Ensure screen is clear when switch Console from Graphics mode to Text mode
//
gST->ConOut->EnableCursor (gST->ConOut, TRUE);
gST->ConOut->ClearScreen (gST->ConOut);
if (EFI_ERROR (Status)) {
//
// Timeout or user press enter to continue
//
goto Exit;
}
}
do {
InitializeFrontPage (FALSE);
//
// Update Front Page strings
//
UpdateFrontPageStrings ();
gCallbackKey = 0;
Status = CallFrontPage ();
//
// If gCallbackKey is greater than 1 and less or equal to 5,
// it will lauch configuration utilities.
// 2 = set language
// 3 = boot manager
// 4 = device manager
// 5 = boot maintainenance manager
//
if (gCallbackKey != 0) {
REPORT_STATUS_CODE (
EFI_PROGRESS_CODE,
(EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)
);
}
//
// Based on the key that was set, we can determine what to do
//
switch (gCallbackKey) {
//
// The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
// describe to their customers in documentation how to find their setup information (namely
// under the device manager and specific buckets)
//
// These entries consist of the Continue, Select language, Boot Manager, and Device Manager
//
case FRONT_PAGE_KEY_CONTINUE:
//
// User hit continue
//
break;
case FRONT_PAGE_KEY_LANGUAGE:
//
// User made a language setting change - display front page again
//
break;
case FRONT_PAGE_KEY_BOOT_MANAGER:
//
// User chose to run the Boot Manager
//
CallBootManager ();
break;
case FRONT_PAGE_KEY_DEVICE_MANAGER:
//
// Display the Device Manager
//
do {
CallDeviceManager();
} while (gCallbackKey == FRONT_PAGE_KEY_DEVICE_MANAGER);
break;
case FRONT_PAGE_KEY_BOOT_MAINTAIN:
//
// Display the Boot Maintenance Manager
//
BdsStartBootMaint ();
break;
}
} while ((Status == EFI_SUCCESS) && (gCallbackKey != FRONT_PAGE_KEY_CONTINUE));
//
//Will leave browser, check any reset required change is applied? if yes, reset system
//
SetupResetReminder ();
Exit:
//
// Automatically load current entry
// Note: The following lines of code only execute when Auto boot
// takes affect
//
PERF_END (0, "BdsTimeOut", "BDS", 0);
Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);
ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);
}

View File

@ -0,0 +1,240 @@
/** @file
FrontPage routines to handle the callbacks and browser calls
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _FRONT_PAGE_H_
#define _FRONT_PAGE_H_
#include "DeviceMngr/DeviceManager.h"
#include "BootMaint/BootMaint.h"
#include "BootMngr/BootManager.h"
#include "String.h"
#define ONE_SECOND 10000000
//
// This is the VFR compiler generated header file which defines the
// string identifiers.
//
#define PRINTABLE_LANGUAGE_NAME_STRING_ID 0x0001
//
// These are defined as the same with vfr file
//
#define FRONT_PAGE_FORM_ID 0x1000
#define FRONT_PAGE_KEY_CONTINUE 0x1000
#define FRONT_PAGE_KEY_LANGUAGE 0x1234
#define FRONT_PAGE_KEY_BOOT_MANAGER 0x1064
#define FRONT_PAGE_KEY_DEVICE_MANAGER 0x8567
#define FRONT_PAGE_KEY_BOOT_MAINTAIN 0x9876
#define LABEL_SELECT_LANGUAGE 0x1000
#define FRONT_PAGE_FORMSET_GUID \
{ \
0x9e0c30bc, 0x3f06, 0x4ba6, {0x82, 0x88, 0x9, 0x17, 0x9b, 0x85, 0x5d, 0xbe} \
}
#define FRONT_PAGE_CALLBACK_DATA_SIGNATURE SIGNATURE_32 ('F', 'P', 'C', 'B')
typedef struct {
UINTN Signature;
//
// HII relative handles
//
EFI_HII_HANDLE HiiHandle;
EFI_HANDLE DriverHandle;
EFI_STRING_ID *LanguageToken;
//
// Produced protocols
//
EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
} FRONT_PAGE_CALLBACK_DATA;
#define EFI_FP_CALLBACK_DATA_FROM_THIS(a) \
CR (a, \
FRONT_PAGE_CALLBACK_DATA, \
ConfigAccess, \
FRONT_PAGE_CALLBACK_DATA_SIGNATURE \
)
//
// These are the VFR compiler generated data representing our VFR data.
//
extern UINT8 FrontPageVfrBin[];
extern EFI_HII_DATABASE_PROTOCOL *gHiiDatabase;
extern EFI_HII_STRING_PROTOCOL *gHiiString;
extern EFI_FORM_BROWSER2_PROTOCOL *gFormBrowser2;
extern EFI_HII_CONFIG_ROUTING_PROTOCOL *gHiiConfigRouting;
extern UINTN gCallbackKey;
extern BOOLEAN gConnectAllHappened;
/**
This function allows a caller to extract the current configuration for one
or more named elements from the target driver.
@param This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param Request - A null-terminated Unicode string in <ConfigRequest> format.
@param Progress - On return, points to a character in the Request string.
Points to the string's null terminator if request was successful.
Points to the most recent '&' before the first failing name/value
pair (or the beginning of the string if the failure is in the
first name/value pair) if the request was not successful.
@param Results - A null-terminated Unicode string in <ConfigAltResp> format which
has all values filled in for the names in the Request string.
String to be allocated by the called function.
@retval EFI_SUCCESS The Results is filled with the requested values.
@retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
@retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
**/
EFI_STATUS
EFIAPI
FakeExtractConfig (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN CONST EFI_STRING Request,
OUT EFI_STRING *Progress,
OUT EFI_STRING *Results
);
/**
This function processes the results of changes in configuration.
@param This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param Configuration - A null-terminated Unicode string in <ConfigResp> format.
@param Progress - A pointer to a string filled in with the offset of the most
recent '&' before the first failing name/value pair (or the
beginning of the string if the failure is in the first
name/value pair) or the terminating NULL if all was successful.
@retval EFI_SUCCESS The Results is processed successfully.
@retval EFI_INVALID_PARAMETER Configuration is NULL.
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
**/
EFI_STATUS
EFIAPI
FakeRouteConfig (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN CONST EFI_STRING Configuration,
OUT EFI_STRING *Progress
);
/**
This function processes the results of changes in configuration.
@param This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param Action - Specifies the type of action taken by the browser.
@param QuestionId - A unique value which is sent to the original exporting driver
so that it can identify the type of data to expect.
@param Type - The type of value for the question.
@param Value - A pointer to the data being sent to the original exporting driver.
@param ActionRequest - On return, points to the action requested by the callback function.
@retval EFI_SUCCESS The callback successfully handled the action.
@retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
@retval EFI_DEVICE_ERROR The variable could not be saved.
@retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
**/
EFI_STATUS
EFIAPI
FrontPageCallback (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN EFI_BROWSER_ACTION Action,
IN EFI_QUESTION_ID QuestionId,
IN UINT8 Type,
IN EFI_IFR_TYPE_VALUE *Value,
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
);
/**
Initialize HII information for the FrontPage
@param InitializeHiiData TRUE if HII elements need to be initialized.
@retval EFI_SUCCESS The operation is successful.
@retval EFI_DEVICE_ERROR If the dynamic opcode creation failed.
**/
EFI_STATUS
InitializeFrontPage (
IN BOOLEAN InitializeHiiData
);
/**
Acquire the string associated with the ProducerGuid and return it.
@param ProducerGuid - The Guid to search the HII database for
@param Token - The token value of the string to extract
@param String - The string that is extracted
@retval EFI_SUCCESS The function returns EFI_SUCCESS always.
**/
EFI_STATUS
GetProducerString (
IN EFI_GUID *ProducerGuid,
IN EFI_STRING_ID Token,
OUT CHAR16 **String
);
/**
Compare two EFI_TIME data.
@param FirstTime - A pointer to the first EFI_TIME data.
@param SecondTime - A pointer to the second EFI_TIME data.
@retval TRUE The FirstTime is not later than the SecondTime.
@retval FALSE The FirstTime is later than the SecondTime.
**/
BOOLEAN
TimeCompare (
IN EFI_TIME *FirstTime,
IN EFI_TIME *SecondTime
);
/**
This function is the main entry of the platform setup entry.
The function will present the main menu of the system setup,
this is the platform reference part and can be customize.
@param TimeoutDefault - The fault time out value before the system
continue to boot.
@param ConnectAllHappened - The indicater to check if the connect all have
already happended.
**/
VOID
PlatformBdsEnterFrontPage (
IN UINT16 TimeoutDefault,
IN BOOLEAN ConnectAllHappened
);
#endif // _FRONT_PAGE_H_

View File

@ -0,0 +1,137 @@
///** @file
//
// Browser formset.
//
// Copyright (c) 2007 - 2008, Intel Corporation. <BR>
// All rights reserved. This program and the accompanying materials
// are licensed and made available under the terms and conditions of the BSD License
// which accompanies this distribution. The full text of the license may be found at
// http://opensource.org/licenses/bsd-license.php
//
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
//
//**/
#define FORMSET_GUID { 0x9e0c30bc, 0x3f06, 0x4ba6, 0x82, 0x88, 0x9, 0x17, 0x9b, 0x85, 0x5d, 0xbe }
#define FRONT_PAGE_CLASS 0x0000
#define FRONT_PAGE_SUBCLASS 0x0002
#define FRONT_PAGE_FORM_ID 0x1000
#define FRONT_PAGE_ITEM_ONE 0x0001
#define FRONT_PAGE_ITEM_TWO 0x0002
#define FRONT_PAGE_ITEM_THREE 0x0003
#define FRONT_PAGE_ITEM_FOUR 0x0004
#define FRONT_PAGE_ITEM_FIVE 0x0005
#define FRONT_PAGE_KEY_CONTINUE 0x1000
#define FRONT_PAGE_KEY_LANGUAGE 0x1234
#define FRONT_PAGE_KEY_BOOT_MANAGER 0x1064
#define FRONT_PAGE_KEY_DEVICE_MANAGER 0x8567
#define FRONT_PAGE_KEY_BOOT_MAINTAIN 0x9876
#define LABEL_SELECT_LANGUAGE 0x1000
#define LABEL_TIMEOUT 0x2000
#define LABEL_END 0xffff
formset
guid = FORMSET_GUID,
title = STRING_TOKEN(STR_FRONT_PAGE_TITLE),
help = STRING_TOKEN(STR_NULL_STRING),
class = FRONT_PAGE_CLASS,
subclass = FRONT_PAGE_SUBCLASS,
form formid = FRONT_PAGE_FORM_ID,
title = STRING_TOKEN(STR_FRONT_PAGE_TITLE);
banner
title = STRING_TOKEN(STR_FRONT_PAGE_COMPUTER_MODEL),
line 0,
align left;
banner
title = STRING_TOKEN(STR_FRONT_PAGE_CPU_MODEL),
line 1,
align left;
banner
title = STRING_TOKEN(STR_FRONT_PAGE_CPU_SPEED),
line 1,
align right;
banner
title = STRING_TOKEN(STR_FRONT_PAGE_BIOS_VERSION),
line 2,
align left;
banner
title = STRING_TOKEN(STR_FRONT_PAGE_MEMORY_SIZE),
line 2,
align right;
// banner
// title = STRING_TOKEN(STR_FRONT_PAGE_BANNER_0_LEFT),
// line 0,
// align left;
// banner
// title = STRING_TOKEN(STR_FRONT_PAGE_BANNER_0_RIGHT),
// line 0,
// align right;
// banner
// title = STRING_TOKEN(STR_FRONT_PAGE_BANNER_1_LEFT),
// line 1,
// align left;
// banner
// title = STRING_TOKEN(STR_FRONT_PAGE_BANNER_1_RIGHT),
// line 1,
// align right;
// banner
// title = STRING_TOKEN(STR_FRONT_PAGE_BANNER_2_LEFT),
// line 2,
// align left;
// banner
// title = STRING_TOKEN(STR_FRONT_PAGE_BANNER_3_LEFT),
// line 3,
// align left;
goto FRONT_PAGE_ITEM_ONE,
prompt = STRING_TOKEN(STR_CONTINUE_PROMPT),
help = STRING_TOKEN(STR_CONTINUE_HELP),
flags = INTERACTIVE,
key = FRONT_PAGE_KEY_CONTINUE;
label LABEL_SELECT_LANGUAGE;
//
// This is where we will dynamically add a OneOf type op-code to select
// Languages from the currently available choices
//
label LABEL_END;
goto FRONT_PAGE_ITEM_THREE,
prompt = STRING_TOKEN(STR_BOOT_MANAGER),
help = STRING_TOKEN(STR_BOOT_MANAGER_HELP),
flags = INTERACTIVE,
key = FRONT_PAGE_KEY_BOOT_MANAGER;
goto FRONT_PAGE_ITEM_FOUR,
prompt = STRING_TOKEN(STR_DEVICE_MANAGER),
help = STRING_TOKEN(STR_DEVICE_MANAGER_HELP),
flags = INTERACTIVE,
key = FRONT_PAGE_KEY_DEVICE_MANAGER;
goto FRONT_PAGE_ITEM_FIVE,
prompt = STRING_TOKEN(STR_BOOT_MAINT_MANAGER),
help = STRING_TOKEN(STR_BOOT_MAINT_MANAGER_HELP),
flags = INTERACTIVE,
key = FRONT_PAGE_KEY_BOOT_MAINTAIN;
endform;
endformset;

View File

@ -0,0 +1,701 @@
/** @file
Provides a way for 3rd party applications to register themselves for launch by the
Boot Manager based on hot key
Copyright (c) 2007 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Hotkey.h"
LIST_ENTRY mHotkeyList = INITIALIZE_LIST_HEAD_VARIABLE (mHotkeyList);
BOOLEAN mHotkeyCallbackPending = FALSE;
EFI_EVENT mHotkeyEvent;
VOID *mHotkeyRegistration;
/**
Check if the Key Option is valid or not.
@param KeyOption The Hot Key Option to be checked.
@retval TRUE The Hot Key Option is valid.
@retval FALSE The Hot Key Option is invalid.
**/
BOOLEAN
IsKeyOptionValid (
IN EFI_KEY_OPTION *KeyOption
)
{
UINT16 BootOptionName[10];
UINT8 *BootOptionVar;
UINTN BootOptionSize;
UINT32 Crc;
//
// Check whether corresponding Boot Option exist
//
UnicodeSPrint (BootOptionName, sizeof (BootOptionName), L"Boot%04x", KeyOption->BootOption);
BootOptionVar = BdsLibGetVariableAndSize (
BootOptionName,
&gEfiGlobalVariableGuid,
&BootOptionSize
);
if (BootOptionVar == NULL || BootOptionSize == 0) {
return FALSE;
}
//
// Check CRC for Boot Option
//
gBS->CalculateCrc32 (BootOptionVar, BootOptionSize, &Crc);
FreePool (BootOptionVar);
return (BOOLEAN) ((KeyOption->BootOptionCrc == Crc) ? TRUE : FALSE);
}
/**
Create Key#### for the given hotkey.
@param KeyOption The Hot Key Option to be added.
@param KeyOptionNumber The key option number for Key#### (optional).
@retval EFI_SUCCESS Register hotkey successfully.
@retval EFI_INVALID_PARAMETER The hotkey option is invalid.
@retval EFI_OUT_OF_RESOURCES Fail to allocate memory resource.
**/
EFI_STATUS
RegisterHotkey (
IN EFI_KEY_OPTION *KeyOption,
OUT UINT16 *KeyOptionNumber
)
{
UINT16 KeyOptionName[10];
UINT16 *KeyOrder;
UINTN KeyOrderSize;
UINT16 *NewKeyOrder;
UINTN Index;
UINT16 MaxOptionNumber;
UINT16 RegisterOptionNumber;
EFI_KEY_OPTION *TempOption;
UINTN TempOptionSize;
EFI_STATUS Status;
UINTN KeyOptionSize;
BOOLEAN UpdateBootOption;
//
// Validate the given key option
//
if (!IsKeyOptionValid (KeyOption)) {
return EFI_INVALID_PARAMETER;
}
KeyOptionSize = sizeof (EFI_KEY_OPTION) + GET_KEY_CODE_COUNT (KeyOption->KeyData.PackedValue) * sizeof (EFI_INPUT_KEY);
UpdateBootOption = FALSE;
//
// check whether HotKey conflict with keys used by Setup Browser
//
KeyOrder = BdsLibGetVariableAndSize (
VAR_KEY_ORDER,
&gEfiGlobalVariableGuid,
&KeyOrderSize
);
if (KeyOrder == NULL) {
KeyOrderSize = 0;
}
//
// Find free key option number
//
MaxOptionNumber = 0;
TempOption = NULL;
for (Index = 0; Index < KeyOrderSize / sizeof (UINT16); Index++) {
if (MaxOptionNumber < KeyOrder[Index]) {
MaxOptionNumber = KeyOrder[Index];
}
UnicodeSPrint (KeyOptionName, sizeof (KeyOptionName), L"Key%04x", KeyOrder[Index]);
TempOption = BdsLibGetVariableAndSize (
KeyOptionName,
&gEfiGlobalVariableGuid,
&TempOptionSize
);
if (CompareMem (TempOption, KeyOption, TempOptionSize) == 0) {
//
// Got the option, so just return
//
FreePool (TempOption);
FreePool (KeyOrder);
return EFI_SUCCESS;
}
if (KeyOption->KeyData.PackedValue == TempOption->KeyData.PackedValue) {
if (GET_KEY_CODE_COUNT (KeyOption->KeyData.PackedValue) == 0 ||
CompareMem (
((UINT8 *) TempOption) + sizeof (EFI_KEY_OPTION),
((UINT8 *) KeyOption) + sizeof (EFI_KEY_OPTION),
KeyOptionSize - sizeof (EFI_KEY_OPTION)
) == 0) {
//
// Hotkey is the same but BootOption changed, need update
//
UpdateBootOption = TRUE;
break;
}
}
FreePool (TempOption);
}
if (UpdateBootOption) {
RegisterOptionNumber = KeyOrder[Index];
FreePool (TempOption);
} else {
RegisterOptionNumber = (UINT16) (MaxOptionNumber + 1);
}
if (KeyOptionNumber != NULL) {
*KeyOptionNumber = RegisterOptionNumber;
}
//
// Create variable Key####
//
UnicodeSPrint (KeyOptionName, sizeof (KeyOptionName), L"Key%04x", RegisterOptionNumber);
Status = gRT->SetVariable (
KeyOptionName,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
KeyOptionSize,
KeyOption
);
if (EFI_ERROR (Status)) {
FreePool (KeyOrder);
return Status;
}
//
// Update the key order variable - "KeyOrder"
//
if (!UpdateBootOption) {
Index = KeyOrderSize / sizeof (UINT16);
KeyOrderSize += sizeof (UINT16);
}
NewKeyOrder = AllocatePool (KeyOrderSize);
if (NewKeyOrder == NULL) {
FreePool (KeyOrder);
return EFI_OUT_OF_RESOURCES;
}
if (KeyOrder != NULL) {
CopyMem (NewKeyOrder, KeyOrder, KeyOrderSize);
}
NewKeyOrder[Index] = RegisterOptionNumber;
Status = gRT->SetVariable (
VAR_KEY_ORDER,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
KeyOrderSize,
NewKeyOrder
);
FreePool (KeyOrder);
FreePool (NewKeyOrder);
return Status;
}
/**
Delete Key#### for the given Key Option number.
@param KeyOptionNumber Key option number for Key####
@retval EFI_SUCCESS Unregister hotkey successfully.
@retval EFI_NOT_FOUND No Key#### is found for the given Key Option number.
**/
EFI_STATUS
UnregisterHotkey (
IN UINT16 KeyOptionNumber
)
{
UINT16 KeyOption[10];
UINTN Index;
EFI_STATUS Status;
UINTN Index2Del;
UINT16 *KeyOrder;
UINTN KeyOrderSize;
//
// Delete variable Key####
//
UnicodeSPrint (KeyOption, sizeof (KeyOption), L"Key%04x", KeyOptionNumber);
gRT->SetVariable (
KeyOption,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
0,
NULL
);
//
// Adjust key order array
//
KeyOrder = BdsLibGetVariableAndSize (
VAR_KEY_ORDER,
&gEfiGlobalVariableGuid,
&KeyOrderSize
);
if (KeyOrder == NULL) {
return EFI_SUCCESS;
}
Index2Del = 0;
for (Index = 0; Index < KeyOrderSize / sizeof (UINT16); Index++) {
if (KeyOrder[Index] == KeyOptionNumber) {
Index2Del = Index;
break;
}
}
if (Index != KeyOrderSize / sizeof (UINT16)) {
//
// KeyOptionNumber found in "KeyOrder", delete it
//
for (Index = Index2Del; Index < KeyOrderSize / sizeof (UINT16) - 1; Index++) {
KeyOrder[Index] = KeyOrder[Index + 1];
}
KeyOrderSize -= sizeof (UINT16);
}
Status = gRT->SetVariable (
VAR_KEY_ORDER,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
KeyOrderSize,
KeyOrder
);
FreePool (KeyOrder);
return Status;
}
/**
This is the common notification function for HotKeys, it will be registered
with SimpleTextInEx protocol interface - RegisterKeyNotify() of ConIn handle.
@param KeyData A pointer to a buffer that is filled in with the keystroke
information for the key that was pressed.
@retval EFI_SUCCESS KeyData is successfully processed.
@return EFI_NOT_FOUND Fail to find boot option variable.
**/
EFI_STATUS
HotkeyCallback (
IN EFI_KEY_DATA *KeyData
)
{
BOOLEAN HotkeyCatched;
LIST_ENTRY BootLists;
LIST_ENTRY *Link;
BDS_HOTKEY_OPTION *Hotkey;
UINT16 Buffer[10];
BDS_COMMON_OPTION *BootOption;
UINTN ExitDataSize;
CHAR16 *ExitData;
EFI_STATUS Status;
EFI_KEY_DATA *HotkeyData;
if (mHotkeyCallbackPending) {
//
// When responsing to a Hotkey, ignore sequential hotkey stroke until
// the current Boot#### load option returned
//
return EFI_SUCCESS;
}
Status = EFI_SUCCESS;
Link = GetFirstNode (&mHotkeyList);
while (!IsNull (&mHotkeyList, Link)) {
HotkeyCatched = FALSE;
Hotkey = BDS_HOTKEY_OPTION_FROM_LINK (Link);
//
// Is this Key Stroke we are waiting for?
//
ASSERT (Hotkey->WaitingKey < (sizeof (Hotkey->KeyData) / sizeof (Hotkey->KeyData[0])));
HotkeyData = &Hotkey->KeyData[Hotkey->WaitingKey];
if ((KeyData->Key.ScanCode == HotkeyData->Key.ScanCode) &&
(KeyData->Key.UnicodeChar == HotkeyData->Key.UnicodeChar) &&
((HotkeyData->KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) ? (KeyData->KeyState.KeyShiftState == HotkeyData->KeyState.KeyShiftState) : 1)) {
//
// Receive an expecting key stroke
//
if (Hotkey->CodeCount > 1) {
//
// For hotkey of key combination, transit to next waiting state
//
Hotkey->WaitingKey++;
if (Hotkey->WaitingKey == Hotkey->CodeCount) {
//
// Received the whole key stroke sequence
//
HotkeyCatched = TRUE;
}
} else {
//
// For hotkey of single key stroke
//
HotkeyCatched = TRUE;
}
} else {
//
// Receive an unexpected key stroke, reset to initial waiting state
//
Hotkey->WaitingKey = 0;
}
if (HotkeyCatched) {
//
// Reset to initial waiting state
//
Hotkey->WaitingKey = 0;
//
// Launch its BootOption
//
InitializeListHead (&BootLists);
UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", Hotkey->BootOptionNumber);
BootOption = BdsLibVariableToOption (&BootLists, Buffer);
if (BootOption == NULL) {
return EFI_NOT_FOUND;
}
BootOption->BootCurrent = Hotkey->BootOptionNumber;
BdsLibConnectDevicePath (BootOption->DevicePath);
//
// Clear the screen before launch this BootOption
//
gST->ConOut->Reset (gST->ConOut, FALSE);
mHotkeyCallbackPending = TRUE;
Status = BdsLibBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData);
mHotkeyCallbackPending = FALSE;
if (EFI_ERROR (Status)) {
//
// Call platform action to indicate the boot fail
//
BootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_FAILED));
PlatformBdsBootFail (BootOption, Status, ExitData, ExitDataSize);
} else {
//
// Call platform action to indicate the boot success
//
BootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED));
PlatformBdsBootSuccess (BootOption);
}
}
Link = GetNextNode (&mHotkeyList, Link);
}
return Status;
}
/**
Register the common HotKey notify function to given SimpleTextInEx protocol instance.
@param SimpleTextInEx Simple Text Input Ex protocol instance
@retval EFI_SUCCESS Register hotkey notification function successfully.
@retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures.
**/
EFI_STATUS
HotkeyRegisterNotify (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleTextInEx
)
{
UINTN Index;
EFI_STATUS Status;
LIST_ENTRY *Link;
BDS_HOTKEY_OPTION *Hotkey;
//
// Register notification function for each hotkey
//
Link = GetFirstNode (&mHotkeyList);
while (!IsNull (&mHotkeyList, Link)) {
Hotkey = BDS_HOTKEY_OPTION_FROM_LINK (Link);
Index = 0;
do {
Status = SimpleTextInEx->RegisterKeyNotify (
SimpleTextInEx,
&Hotkey->KeyData[Index],
HotkeyCallback,
&Hotkey->NotifyHandle
);
if (EFI_ERROR (Status)) {
//
// some of the hotkey registry failed
//
return Status;
}
Index ++;
} while (Index < Hotkey->CodeCount);
Link = GetNextNode (&mHotkeyList, Link);
}
return EFI_SUCCESS;
}
/**
Callback function for SimpleTextInEx protocol install events
@param Event the event that is signaled.
@param Context not used here.
**/
VOID
EFIAPI
HotkeyEvent (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
UINTN BufferSize;
EFI_HANDLE Handle;
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleTextInEx;
while (TRUE) {
BufferSize = sizeof (EFI_HANDLE);
Status = gBS->LocateHandle (
ByRegisterNotify,
NULL,
mHotkeyRegistration,
&BufferSize,
&Handle
);
if (EFI_ERROR (Status)) {
//
// If no more notification events exist
//
return ;
}
Status = gBS->HandleProtocol (
Handle,
&gEfiSimpleTextInputExProtocolGuid,
(VOID **) &SimpleTextInEx
);
ASSERT_EFI_ERROR (Status);
HotkeyRegisterNotify (SimpleTextInEx);
}
}
/**
Insert Key Option to hotkey list.
@param KeyOption The Hot Key Option to be added to hotkey list.
@retval EFI_SUCCESS Add to hotkey list success.
@retval EFI_OUT_OF_RESOURCES Fail to allocate memory resource.
**/
EFI_STATUS
HotkeyInsertList (
IN EFI_KEY_OPTION *KeyOption
)
{
BDS_HOTKEY_OPTION *HotkeyLeft;
BDS_HOTKEY_OPTION *HotkeyRight;
UINTN Index;
UINT32 KeyOptions;
UINT32 KeyShiftStateLeft;
UINT32 KeyShiftStateRight;
EFI_INPUT_KEY *InputKey;
EFI_KEY_DATA *KeyData;
HotkeyLeft = AllocateZeroPool (sizeof (BDS_HOTKEY_OPTION));
if (HotkeyLeft == NULL) {
return EFI_OUT_OF_RESOURCES;
}
HotkeyLeft->Signature = BDS_HOTKEY_OPTION_SIGNATURE;
HotkeyLeft->BootOptionNumber = KeyOption->BootOption;
KeyOptions = KeyOption->KeyData.PackedValue;
HotkeyLeft->CodeCount = (UINT8) GET_KEY_CODE_COUNT (KeyOptions);
//
// Map key shift state from KeyOptions to EFI_KEY_DATA.KeyState
//
KeyShiftStateRight = (KeyOptions & EFI_KEY_OPTION_SHIFT) |
((KeyOptions & EFI_KEY_OPTION_CONTROL) << 1) |
((KeyOptions & EFI_KEY_OPTION_ALT) << 2) |
((KeyOptions & EFI_KEY_OPTION_LOGO) << 3) |
((KeyOptions & (EFI_KEY_OPTION_MENU | EFI_KEY_OPTION_SYSREQ)) << 4) |
EFI_SHIFT_STATE_VALID;
KeyShiftStateLeft = (KeyShiftStateRight & 0xffffff00) | ((KeyShiftStateRight & 0xff) << 1);
InputKey = (EFI_INPUT_KEY *) (((UINT8 *) KeyOption) + sizeof (EFI_KEY_OPTION));
Index = 0;
KeyData = &HotkeyLeft->KeyData[0];
do {
//
// If Key CodeCount is 0, then only KeyData[0] is used;
// if Key CodeCount is n, then KeyData[0]~KeyData[n-1] are used
//
KeyData->Key.ScanCode = InputKey[Index].ScanCode;
KeyData->Key.UnicodeChar = InputKey[Index].UnicodeChar;
KeyData->KeyState.KeyShiftState = KeyShiftStateLeft;
Index++;
KeyData++;
} while (Index < HotkeyLeft->CodeCount);
InsertTailList (&mHotkeyList, &HotkeyLeft->Link);
if (KeyShiftStateLeft != KeyShiftStateRight) {
//
// Need an extra hotkey for shift key on right
//
HotkeyRight = AllocateCopyPool (sizeof (BDS_HOTKEY_OPTION), HotkeyLeft);
if (HotkeyRight == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Index = 0;
KeyData = &HotkeyRight->KeyData[0];
do {
//
// Key.ScanCode and Key.UnicodeChar have already been initialized,
// only need to update KeyState.KeyShiftState
//
KeyData->KeyState.KeyShiftState = KeyShiftStateRight;
Index++;
KeyData++;
} while (Index < HotkeyRight->CodeCount);
InsertTailList (&mHotkeyList, &HotkeyRight->Link);
}
return EFI_SUCCESS;
}
/**
Process all the "Key####" variables, associate Hotkeys with corresponding Boot Options.
@retval EFI_SUCCESS Hotkey services successfully initialized.
@retval EFI_NOT_FOUND Can not find the "KeyOrder" variable
**/
EFI_STATUS
InitializeHotkeyService (
VOID
)
{
EFI_STATUS Status;
UINT32 BootOptionSupport;
UINT16 *KeyOrder;
UINTN KeyOrderSize;
UINTN Index;
UINT16 KeyOptionName[8];
UINTN KeyOptionSize;
EFI_KEY_OPTION *KeyOption;
//
// Export our capability - EFI_BOOT_OPTION_SUPPORT_KEY and EFI_BOOT_OPTION_SUPPORT_APP
//
BootOptionSupport = EFI_BOOT_OPTION_SUPPORT_KEY | EFI_BOOT_OPTION_SUPPORT_APP;
Status = gRT->SetVariable (
L"BootOptionSupport",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
sizeof (UINT32),
&BootOptionSupport
);
//
// Get valid Key Option List from private EFI variable "KeyOrder"
//
KeyOrder = BdsLibGetVariableAndSize (
VAR_KEY_ORDER,
&gEfiGlobalVariableGuid,
&KeyOrderSize
);
if (KeyOrder == NULL) {
return EFI_NOT_FOUND;
}
for (Index = 0; Index < KeyOrderSize / sizeof (UINT16); Index ++) {
UnicodeSPrint (KeyOptionName, sizeof (KeyOptionName), L"Key%04x", KeyOrder[Index]);
KeyOption = BdsLibGetVariableAndSize (
KeyOptionName,
&gEfiGlobalVariableGuid,
&KeyOptionSize
);
if (KeyOption == NULL || !IsKeyOptionValid (KeyOption)) {
UnregisterHotkey (KeyOrder[Index]);
} else {
HotkeyInsertList (KeyOption);
}
}
//
// Register Protocol notify for Hotkey service
//
Status = gBS->CreateEvent (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
HotkeyEvent,
NULL,
&mHotkeyEvent
);
ASSERT_EFI_ERROR (Status);
//
// Register for protocol notifications on this event
//
Status = gBS->RegisterProtocolNotify (
&gEfiSimpleTextInputExProtocolGuid,
mHotkeyEvent,
&mHotkeyRegistration
);
ASSERT_EFI_ERROR (Status);
return Status;
}

View File

@ -0,0 +1,90 @@
/** @file
Provides a way for 3rd party applications to register themselves for launch by the
Boot Manager based on hot key
Copyright (c) 2007 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _HOTKEY_H_
#define _HOTKEY_H_
#include "Bds.h"
#include "String.h"
#define GET_KEY_CODE_COUNT(KeyOptions) (((KeyOptions) & EFI_KEY_CODE_COUNT) >> 8)
#define BDS_HOTKEY_OPTION_SIGNATURE SIGNATURE_32 ('B', 'd', 'K', 'O')
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
EFI_HANDLE NotifyHandle;
UINT16 BootOptionNumber;
UINT8 CodeCount;
UINT8 WaitingKey;
EFI_KEY_DATA KeyData[3];
} BDS_HOTKEY_OPTION;
#define BDS_HOTKEY_OPTION_FROM_LINK(a) CR (a, BDS_HOTKEY_OPTION, Link, BDS_HOTKEY_OPTION_SIGNATURE)
#define VAR_KEY_ORDER L"KeyOrder"
/**
Create Key#### for the given hotkey.
@param KeyOption - The Hot Key Option to be added.
@param KeyOptionNumber - The key option number for Key#### (optional).
@retval EFI_SUCCESS Register hotkey successfully.
@retval EFI_INVALID_PARAMETER The hotkey option is invalid.
**/
EFI_STATUS
RegisterHotkey (
IN EFI_KEY_OPTION *KeyOption,
OUT UINT16 *KeyOptionNumber
);
/**
Delete Key#### for the given Key Option number.
@param KeyOptionNumber - Key option number for Key####
@retval EFI_SUCCESS Unregister hotkey successfully.
@retval EFI_NOT_FOUND No Key#### is found for the given Key Option number.
**/
EFI_STATUS
UnregisterHotkey (
IN UINT16 KeyOptionNumber
);
/**
Process all the "Key####" variables, associate Hotkeys with corresponding Boot Options.
@param VOID
@retval EFI_SUCCESS Hotkey services successfully initialized.
**/
EFI_STATUS
InitializeHotkeyService (
VOID
);
#endif

View File

@ -0,0 +1,49 @@
/** @file
Set the level of support for Hardware Error Record Persistence that is
implemented by the platform.
Copyright (c) 2007 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "HwErrRecSupport.h"
/**
Set the HwErrRecSupport variable contains a binary UINT16 that supplies the
level of support for Hardware Error Record Persistence that is implemented
by the platform.
@param HwErrRecSupportLevel
zero value: Indicates that the platform implements no support for
Hardware Error Record Persistence.
non-zero value: Indicates that the platform implements Hardware Error
Record Persistence.
**/
VOID
InitializeHwErrRecSupport (
IN UINT16 HwErrRecSupportLevel
)
{
EFI_STATUS Status;
Status = gRT->SetVariable (
L"HwErrRecSupport",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
sizeof (UINT16),
&HwErrRecSupportLevel
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "HwErrRecSupport: Can not set the variable\n"));
}
}

View File

@ -0,0 +1,39 @@
/** @file
Set the level of support for Hardware Error Record Persistence that is
implemented by the platform.
Copyright (c) 2007 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _HW_ERR_REC_SUPPORT_H_
#define _HW_ERR_REC_SUPPORT_H_
#include "Bds.h"
/**
Set the HwErrRecSupport variable contains a binary UINT16 that supplies the
level of support for Hardware Error Record Persistence that is implemented
by the platform.
@param HwErrRecSupportLevel
zero value - Indicates that the platform implements no support for
Hardware Error Record Persistence.
non-zero value - Indicates that the platform implements Hardware Error
Record Persistence.
**/
VOID
InitializeHwErrRecSupport (
IN UINT16 HwErrRecSupportLevel
);
#endif

View File

@ -0,0 +1,399 @@
/** @file
Language settings
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Language.h"
#include "FrontPage.h"
#define NARROW_GLYPH_NUMBER 8
#define WIDE_GLYPH_NUMBER 75
EFI_GUID mFontPackageGuid = {
0x78941450, 0x90ab, 0x4fb1, {0xb7, 0x5f, 0x58, 0x92, 0x14, 0xe2, 0x4a, 0xc}
};
typedef struct {
///
/// This 4-bytes total array length is required by HiiLibPreparePackageList()
///
UINT32 Length;
//
// This is the Font package definition
//
EFI_HII_PACKAGE_HEADER Header;
UINT16 NumberOfNarrowGlyphs;
UINT16 NumberOfWideGlyphs;
EFI_NARROW_GLYPH NarrowArray[NARROW_GLYPH_NUMBER];
EFI_WIDE_GLYPH WideArray[WIDE_GLYPH_NUMBER];
} FONT_PACK_BIN;
FONT_PACK_BIN mFontBin = {
sizeof (FONT_PACK_BIN),
{
sizeof (FONT_PACK_BIN) - sizeof (UINT32),
EFI_HII_PACKAGE_SIMPLE_FONTS,
},
NARROW_GLYPH_NUMBER,
0,
{ // Narrow Glyphs
{
0x05d0,
0x00,
{
0x00,
0x00,
0x00,
0x4E,
0x6E,
0x62,
0x32,
0x32,
0x3C,
0x68,
0x4C,
0x4C,
0x46,
0x76,
0x72,
0x00,
0x00,
0x00,
0x00
}
},
{
0x05d1,
0x00,
{
0x00,
0x00,
0x00,
0x78,
0x7C,
0x0C,
0x0C,
0x0C,
0x0C,
0x0C,
0x0C,
0x0C,
0x0C,
0x7E,
0x7E,
0x00,
0x00,
0x00,
0x00
}
},
{
0x05d2,
0x00,
{
0x00,
0x00,
0x00,
0x78,
0x7C,
0x0C,
0x0C,
0x0C,
0x0C,
0x0C,
0x0C,
0x1C,
0x3E,
0x66,
0x66,
0x00,
0x00,
0x00,
0x00
}
},
{
0x05d3,
0x00,
{
0x00,
0x00,
0x00,
0x7E,
0x7E,
0x0C,
0x0C,
0x0C,
0x0C,
0x0C,
0x0C,
0x0C,
0x0C,
0x0C,
0x0C,
0x00,
0x00,
0x00,
0x00
}
},
{
0x05d4,
0x00,
{
0x00,
0x00,
0x00,
0x7C,
0x7E,
0x06,
0x06,
0x06,
0x06,
0x66,
0x66,
0x66,
0x66,
0x66,
0x66,
0x00,
0x00,
0x00,
0x00
}
},
{
0x05d5,
0x00,
{
0x00,
0x00,
0x00,
0x3C,
0x3C,
0x0C,
0x0C,
0x0C,
0x0C,
0x0C,
0x0C,
0x0C,
0x0C,
0x0C,
0x0C,
0x00,
0x00,
0x00,
0x00
}
},
{
0x05d6,
0x00,
{
0x00,
0x00,
0x00,
0x38,
0x38,
0x1E,
0x1E,
0x18,
0x18,
0x18,
0x18,
0x18,
0x18,
0x18,
0x18,
0x00,
0x00,
0x00,
0x00
}
},
{
0x0000,
0x00,
{
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00
}
}
}
};
/**
Routine to export glyphs to the HII database. This is in addition to whatever is defined in the Graphics Console driver.
**/
VOID
ExportFonts (
VOID
)
{
EFI_STATUS Status;
EFI_HANDLE DriverHandle;
EFI_HII_HANDLE HiiHandle;
EFI_HII_PACKAGE_LIST_HEADER *PackageList;
//
// Create driver handle used by HII database
//
Status = HiiLibCreateHiiDriverHandle (&DriverHandle);
if (EFI_ERROR (Status)) {
return ;
}
PackageList = HiiLibPreparePackageList (1, &mFontPackageGuid, &mFontBin);
ASSERT (PackageList != NULL);
gHiiDatabase->NewPackageList (gHiiDatabase, PackageList, DriverHandle, &HiiHandle);
FreePool (PackageList);
}
/**
Determine the current language that will be used
based on language related EFI Variables.
@param LangCodesSettingRequired - If required to set LangCode variable
**/
VOID
InitializeLanguage (
BOOLEAN LangCodesSettingRequired
)
{
EFI_STATUS Status;
UINTN Size;
CHAR8 *Lang;
CHAR8 LangCode[ISO_639_2_ENTRY_SIZE];
CHAR8 *LangCodes;
CHAR8 *PlatformLang;
CHAR8 *PlatformLangCodes;
UINTN Index;
BOOLEAN Invalid;
ExportFonts ();
LangCodes = (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultLangCodes);
if (LangCodesSettingRequired) {
if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
//
// UEFI 2.1 depricated this variable so we support turning it off
//
Status = gRT->SetVariable (
L"LangCodes",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
AsciiStrLen (LangCodes),
LangCodes
);
}
PlatformLangCodes = (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes);
Status = gRT->SetVariable (
L"PlatformLangCodes",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
AsciiStrSize (PlatformLangCodes),
PlatformLangCodes
);
}
if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
//
// UEFI 2.1 depricated this variable so we support turning it off
//
//
// Find current LangCode from Lang NV Variable
//
Size = ISO_639_2_ENTRY_SIZE;
Status = gRT->GetVariable (
L"Lang",
&gEfiGlobalVariableGuid,
NULL,
&Size,
&LangCode
);
if (!EFI_ERROR (Status)) {
Status = EFI_NOT_FOUND;
for (Index = 0; LangCodes[Index] != 0; Index += ISO_639_2_ENTRY_SIZE) {
if (CompareMem (&LangCodes[Index], LangCode, ISO_639_2_ENTRY_SIZE) == 0) {
Status = EFI_SUCCESS;
break;
}
}
}
//
// If we cannot get language code from Lang variable,
// or LangCode cannot be found from language table,
// set the mDefaultLangCode to Lang variable.
//
if (EFI_ERROR (Status)) {
Lang = (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultLang);
Status = gRT->SetVariable (
L"Lang",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
ISO_639_2_ENTRY_SIZE,
Lang
);
}
}
Invalid = FALSE;
PlatformLang = BdsLibGetVariableAndSize (L"PlatformLang", &gEfiGlobalVariableGuid, &Size);
if (PlatformLang != NULL) {
//
// Check Current PlatformLang value against PlatformLangCode. Need a library that is TBD
// Set Invalid based on state of PlatformLang.
//
FreePool (PlatformLang);
} else {
// No valid variable is set
Invalid = TRUE;
}
if (Invalid) {
PlatformLang = (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLang);
Status = gRT->SetVariable (
L"PlatformLang",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
AsciiStrSize (PlatformLang),
PlatformLang
);
}
}

View File

@ -0,0 +1,32 @@
/** @file
Language setting
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _LANGUAGE_H_
#define _LANGUAGE_H_
#include "String.h"
/**
Determine the current language that will be used
based on language related EFI Variables.
@param LangCodesSettingRequired If required to set LangCode variable
**/
VOID
InitializeLanguage (
BOOLEAN LangCodesSettingRequired
);
#endif // _LANGUAGE_H_

View File

@ -0,0 +1,425 @@
/** @file
Perform the platform memory test
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Bds.h"
#include "String.h"
//
// BDS Platform Functions
//
/**
Show progress bar with title above it. It only works in Graphics mode.
@param TitleForeground Foreground color for Title.
@param TitleBackground Background color for Title.
@param Title Title above progress bar.
@param ProgressColor Progress bar color.
@param Progress Progress (0-100)
@param PreviousValue The previous value of the progress.
@retval EFI_STATUS Success update the progress bar
**/
EFI_STATUS
PlatformBdsShowProgress (
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground,
IN CHAR16 *Title,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor,
IN UINTN Progress,
IN UINTN PreviousValue
)
{
EFI_STATUS Status;
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
EFI_UGA_DRAW_PROTOCOL *UgaDraw;
UINT32 SizeOfX;
UINT32 SizeOfY;
UINT32 ColorDepth;
UINT32 RefreshRate;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;
UINTN BlockHeight;
UINTN BlockWidth;
UINTN BlockNum;
UINTN PosX;
UINTN PosY;
UINTN Index;
if (Progress > 100) {
return EFI_INVALID_PARAMETER;
}
UgaDraw = NULL;
Status = gBS->HandleProtocol (
gST->ConsoleOutHandle,
&gEfiGraphicsOutputProtocolGuid,
(VOID **) &GraphicsOutput
);
if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
GraphicsOutput = NULL;
Status = gBS->HandleProtocol (
gST->ConsoleOutHandle,
&gEfiUgaDrawProtocolGuid,
(VOID **) &UgaDraw
);
}
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
SizeOfX = 0;
SizeOfY = 0;
if (GraphicsOutput != NULL) {
SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;
SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;
} else if (UgaDraw != NULL) {
Status = UgaDraw->GetMode (
UgaDraw,
&SizeOfX,
&SizeOfY,
&ColorDepth,
&RefreshRate
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
} else {
return EFI_UNSUPPORTED;
}
BlockWidth = SizeOfX / 100;
BlockHeight = SizeOfY / 50;
BlockNum = Progress;
PosX = 0;
PosY = SizeOfY * 48 / 50;
if (BlockNum == 0) {
//
// Clear progress area
//
SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
if (GraphicsOutput != NULL) {
Status = GraphicsOutput->Blt (
GraphicsOutput,
&Color,
EfiBltVideoFill,
0,
0,
0,
PosY - EFI_GLYPH_HEIGHT - 1,
SizeOfX,
SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1),
SizeOfX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
);
} else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
Status = UgaDraw->Blt (
UgaDraw,
(EFI_UGA_PIXEL *) &Color,
EfiUgaVideoFill,
0,
0,
0,
PosY - EFI_GLYPH_HEIGHT - 1,
SizeOfX,
SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1),
SizeOfX * sizeof (EFI_UGA_PIXEL)
);
} else {
return EFI_UNSUPPORTED;
}
}
//
// Show progress by drawing blocks
//
for (Index = PreviousValue; Index < BlockNum; Index++) {
PosX = Index * BlockWidth;
if (GraphicsOutput != NULL) {
Status = GraphicsOutput->Blt (
GraphicsOutput,
&ProgressColor,
EfiBltVideoFill,
0,
0,
PosX,
PosY,
BlockWidth - 1,
BlockHeight,
(BlockWidth) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
);
} else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
Status = UgaDraw->Blt (
UgaDraw,
(EFI_UGA_PIXEL *) &ProgressColor,
EfiUgaVideoFill,
0,
0,
PosX,
PosY,
BlockWidth - 1,
BlockHeight,
(BlockWidth) * sizeof (EFI_UGA_PIXEL)
);
} else {
return EFI_UNSUPPORTED;
}
}
PrintXY (
(SizeOfX - StrLen (Title) * EFI_GLYPH_WIDTH) / 2,
PosY - EFI_GLYPH_HEIGHT - 1,
&TitleForeground,
&TitleBackground,
Title
);
return EFI_SUCCESS;
}
/**
Perform the memory test base on the memory test intensive level,
and update the memory resource.
@param Level The memory test intensive level.
@retval EFI_STATUS Success test all the system memory and update
the memory resource
**/
EFI_STATUS
BdsMemoryTest (
IN EXTENDMEM_COVERAGE_LEVEL Level
)
{
EFI_STATUS Status;
EFI_STATUS KeyStatus;
EFI_STATUS InitStatus;
EFI_STATUS ReturnStatus;
BOOLEAN RequireSoftECCInit;
EFI_GENERIC_MEMORY_TEST_PROTOCOL *GenMemoryTest;
UINT64 TestedMemorySize;
UINT64 TotalMemorySize;
UINTN TestPercent;
UINT64 PreviousValue;
BOOLEAN ErrorOut;
BOOLEAN TestAbort;
EFI_INPUT_KEY Key;
CHAR16 StrPercent[16];
CHAR16 *StrTotalMemory;
CHAR16 *Pos;
CHAR16 *TmpStr;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;
UINT8 Value;
UINTN DataSize;
UINT32 Attributes;
UINT32 TempData;
ReturnStatus = EFI_SUCCESS;
ZeroMem (&Key, sizeof (EFI_INPUT_KEY));
Pos = AllocatePool (128);
if (Pos == NULL) {
return ReturnStatus;
}
StrTotalMemory = Pos;
TestedMemorySize = 0;
TotalMemorySize = 0;
PreviousValue = 0;
ErrorOut = FALSE;
TestAbort = FALSE;
SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
RequireSoftECCInit = FALSE;
gST->ConOut->ClearScreen (gST->ConOut);
gST->ConOut->SetAttribute (gST->ConOut, EFI_YELLOW | EFI_BRIGHT);
gST->ConOut->EnableCursor (gST->ConOut, FALSE);
Status = gBS->LocateProtocol (
&gEfiGenericMemTestProtocolGuid,
NULL,
(VOID **) &GenMemoryTest
);
if (EFI_ERROR (Status)) {
FreePool (Pos);
return EFI_SUCCESS;
}
InitStatus = GenMemoryTest->MemoryTestInit (
GenMemoryTest,
Level,
&RequireSoftECCInit
);
if (InitStatus == EFI_NO_MEDIA) {
//
// The PEI codes also have the relevant memory test code to check the memory,
// it can select to test some range of the memory or all of them. If PEI code
// checks all the memory, this BDS memory test will has no not-test memory to
// do the test, and then the status of EFI_NO_MEDIA will be returned by
// "MemoryTestInit". So it does not need to test memory again, just return.
//
FreePool (Pos);
return EFI_SUCCESS;
}
gST->ConOut->SetCursorPosition (gST->ConOut, 0, 2);
TmpStr = GetStringById (STRING_TOKEN (STR_ESC_TO_SKIP_MEM_TEST));
if (TmpStr != NULL) {
gST->ConOut->OutputString (gST->ConOut, TmpStr);
FreePool (TmpStr);
}
do {
Status = GenMemoryTest->PerformMemoryTest (
GenMemoryTest,
&TestedMemorySize,
&TotalMemorySize,
&ErrorOut,
TestAbort
);
if (ErrorOut && (Status == EFI_DEVICE_ERROR)) {
TmpStr = GetStringById (STRING_TOKEN (STR_SYSTEM_MEM_ERROR));
if (TmpStr != NULL) {
PrintXY (10, 10, NULL, NULL, TmpStr);
gST->ConOut->SetCursorPosition (gST->ConOut, 0, 4);
gST->ConOut->OutputString (gST->ConOut, TmpStr);
FreePool (TmpStr);
}
ASSERT (0);
}
TempData = (UINT32) DivU64x32 (TotalMemorySize, 16);
TestPercent = (UINTN) DivU64x32 (
DivU64x32 (MultU64x32 (TestedMemorySize, 100), 16),
TempData
);
if (TestPercent != PreviousValue) {
UnicodeValueToString (StrPercent, 0, TestPercent, 0);
gST->ConOut->SetCursorPosition (gST->ConOut, 0, 0);
TmpStr = GetStringById (STRING_TOKEN (STR_MEMORY_TEST_PERCENT));
if (TmpStr != NULL) {
BdsLibOutputStrings (gST->ConOut, StrPercent, TmpStr, NULL);
FreePool (TmpStr);
}
TmpStr = GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST));
if (TmpStr != NULL) {
PlatformBdsShowProgress (
Foreground,
Background,
TmpStr,
Color,
TestPercent,
(UINTN) PreviousValue
);
FreePool (TmpStr);
}
}
PreviousValue = TestPercent;
KeyStatus = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
if (!EFI_ERROR (KeyStatus) && (Key.ScanCode == SCAN_ESC)) {
if (!RequireSoftECCInit) {
TmpStr = GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST));
if (TmpStr != NULL) {
PlatformBdsShowProgress (
Foreground,
Background,
TmpStr,
Color,
100,
(UINTN) PreviousValue
);
FreePool (TmpStr);
}
gST->ConOut->SetCursorPosition (gST->ConOut, 0, 0);
gST->ConOut->OutputString (gST->ConOut, L"100");
Status = GenMemoryTest->Finished (GenMemoryTest);
goto Done;
}
TestAbort = TRUE;
}
} while (Status != EFI_NOT_FOUND);
Status = GenMemoryTest->Finished (GenMemoryTest);
Done:
UnicodeValueToString (StrTotalMemory, COMMA_TYPE, TotalMemorySize, 0);
if (StrTotalMemory[0] == L',') {
StrTotalMemory++;
}
TmpStr = GetStringById (STRING_TOKEN (STR_MEM_TEST_COMPLETED));
if (TmpStr != NULL) {
StrCat (StrTotalMemory, TmpStr);
FreePool (TmpStr);
}
gST->ConOut->ClearScreen (gST->ConOut);
gST->ConOut->SetAttribute (gST->ConOut, EFI_YELLOW | EFI_BRIGHT);
gST->ConOut->EnableCursor (gST->ConOut, FALSE);
gST->ConOut->OutputString (gST->ConOut, StrTotalMemory);
PlatformBdsShowProgress (
Foreground,
Background,
StrTotalMemory,
Color,
100,
(UINTN) PreviousValue
);
FreePool (Pos);
DataSize = sizeof (Value);
Status = gRT->GetVariable (
L"BootState",
&gEfiBootStateGuid,
&Attributes,
&DataSize,
&Value
);
if (EFI_ERROR (Status)) {
Value = 1;
gRT->SetVariable (
L"BootState",
&gEfiBootStateGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
sizeof (Value),
&Value
);
}
return ReturnStatus;
}

View File

@ -0,0 +1,88 @@
/** @file
String support
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Bds.h"
#include "Language.h"
#include "FrontPage.h"
EFI_HII_HANDLE gStringPackHandle;
EFI_GUID mBdsStringPackGuid = {
0x7bac95d3, 0xddf, 0x42f3, {0x9e, 0x24, 0x7c, 0x64, 0x49, 0x40, 0x37, 0x9a}
};
/**
Initialize HII global accessor for string support
@retval EFI_SUCCESS String support initialize success.
**/
EFI_STATUS
InitializeStringSupport (
VOID
)
{
EFI_STATUS Status;
EFI_HANDLE DriverHandle;
EFI_HII_PACKAGE_LIST_HEADER *PackageList;
Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &gHiiDatabase);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Create driver handle used by HII database
//
Status = HiiLibCreateHiiDriverHandle (&DriverHandle);
if (EFI_ERROR (Status)) {
return Status;
}
PackageList = HiiLibPreparePackageList (1, &mBdsStringPackGuid, &BdsDxeStrings);
ASSERT (PackageList != NULL);
Status = gHiiDatabase->NewPackageList (
gHiiDatabase,
PackageList,
DriverHandle,
&gStringPackHandle
);
FreePool (PackageList);
return Status;
}
/**
Get string by string id from HII Interface
@param Id String ID.
@retval CHAR16 * String from ID.
@retval NULL If error occurs.
**/
CHAR16 *
GetStringById (
IN EFI_STRING_ID Id
)
{
CHAR16 *String;
String = NULL;
HiiLibGetStringFromHandle (gStringPackHandle, Id, &String);
return String;
}

View File

@ -0,0 +1,75 @@
/** @file
String support
Copyright (c) 2004 - 2008, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _STRING_H_
#define _STRING_H_
#include "Bds.h"
extern EFI_HII_HANDLE gStringPackHandle;
//
// This is the VFR compiler generated header file which defines the
// string identifiers.
//
extern UINT8 BdsDxeStrings[];
//
// String Definition Guid for BDS Platform
//
#define EFI_BDS_PLATFORM_GUID \
{ \
0x7777E939, 0xD57E, 0x4DCB, 0xA0, 0x8E, 0x64, 0xD7, 0x98, 0x57, 0x1E, 0x0F \
}
/**
Get string by string id from HII Interface
@param Id String ID.
@retval CHAR16 * String from ID.
@retval NULL If error occurs.
**/
CHAR16 *
GetStringById (
IN EFI_STRING_ID Id
);
/**
Initialize HII global accessor for string support
@retval EFI_SUCCESS String support initialize success.
**/
EFI_STATUS
InitializeStringSupport (
VOID
);
/**
Call the browser and display the front page
@return Status code that will be returned by
EFI_FORM_BROWSER2_PROTOCOL.SendForm ().
**/
EFI_STATUS
CallFrontPage (
VOID
);
#endif // _STRING_H_

Binary file not shown.