diff options
author | qwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524> | 2008-01-21 14:39:56 +0000 |
---|---|---|
committer | qwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524> | 2008-01-21 14:39:56 +0000 |
commit | 93e3992d1ea50fb30c48f498d257d4e66252dd9b (patch) | |
tree | b76adcd31d2017cd76317f21be967ad3cb05305e /MdeModulePkg/Universal/BdsDxe | |
parent | f79314fa8f44a79e862d2877e5a9b1a3a9f96791 (diff) | |
download | edk2-platforms-93e3992d1ea50fb30c48f498d257d4e66252dd9b.tar.xz |
UEFI HII: Merge UEFI HII support changes from branch.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4599 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg/Universal/BdsDxe')
42 files changed, 16976 insertions, 0 deletions
diff --git a/MdeModulePkg/Universal/BdsDxe/Bds.h b/MdeModulePkg/Universal/BdsDxe/Bds.h new file mode 100644 index 0000000000..fbfa9658da --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/Bds.h @@ -0,0 +1,117 @@ +/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+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.
+
+Module Name:
+
+ Bds.h
+
+Abstract:
+
+ Head file for BDS Architectural Protocol implementation
+
+Revision History
+
+--*/
+
+#ifndef _BDS_MODULE_H_
+#define _BDS_MODULE_H_
+
+#undef EFI_SPECIFICATION_VERSION
+#define EFI_SPECIFICATION_VERSION 0x0002000A
+#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/HobList.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/GraphicsLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/IfrSupportLib.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/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 \
+ )
+
+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
+//
+EFI_STATUS
+EFIAPI
+BdsInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+VOID
+EFIAPI
+BdsEntry (
+ IN EFI_BDS_ARCH_PROTOCOL *This
+ );
+
+#endif
diff --git a/MdeModulePkg/Universal/BdsDxe/BdsDxe.inf b/MdeModulePkg/Universal/BdsDxe/BdsDxe.inf new file mode 100644 index 0000000000..c4c6b7fd8f --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/BdsDxe.inf @@ -0,0 +1,154 @@ +#/** @file
+# Component discription file for Bds module
+#
+# N/A
+# Copyright (c) 2008, Intel Corporation
+#
+# 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 = Bds
+ FILE_GUID = FC5C7020-1A48-4198-9BE2-EAD5ABC8CF2F
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ EDK_RELEASE_VERSION = 0x00020000
+ 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
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+
+
+[LibraryClasses]
+ DevicePathLib
+ BaseLib
+ HobLib
+ UefiRuntimeServicesTableLib
+ IfrSupportLib
+ GenericBdsLib
+ ReportStatusCodeLib
+ PerformanceLib
+ DxeServicesTableLib
+ MemoryAllocationLib
+ GraphicsLib
+ UefiLib
+ UefiBootServicesTableLib
+ BaseMemoryLib
+ DebugLib
+ PrintLib
+ HiiLib
+ UefiDriverEntryPoint
+ PlatformBdsLib
+ CapsuleLib
+
+[Guids]
+ gEfiGlobalVariableGuid # ALWAYS_CONSUMED
+ gEfiHobListGuid # 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
+ gEfiCpuIoProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ gEfiBdsArchProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ 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
+ gEfiAcpiS3SaveProtocolGuid
+
+[FeaturePcd.common]
+ gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDepricate
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSupportHardwareErrorRecord
+
+[Pcd.common]
+ gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangCodes
+ gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLang
+ gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLangCodes
+ gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang
+ gEfiMdeModulePkgTokenSpaceGuid.PcdHardwareErrorRecordLevel
+
+[Depex]
+ gEfiHiiDatabaseProtocolGuid
+
diff --git a/MdeModulePkg/Universal/BdsDxe/BdsDxe.msa b/MdeModulePkg/Universal/BdsDxe/BdsDxe.msa new file mode 100644 index 0000000000..25547558ae --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/BdsDxe.msa @@ -0,0 +1,238 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <MsaHeader>
+ <ModuleName>BdsDxe</ModuleName>
+ <ModuleType>DXE_DRIVER</ModuleType>
+ <GuidValue>FC5C7020-1A48-4198-9BE2-EAD5ABC8CF2F</GuidValue>
+ <Version>1.0</Version>
+ <Abstract>Component discription file for Bds module</Abstract>
+ <Description>N/A</Description>
+ <Copyright>Copyright (c) 2008, Intel Corporation</Copyright>
+ <License>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.</License>
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
+ </MsaHeader>
+ <ModuleDefinitions>
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
+ <BinaryModule>false</BinaryModule>
+ <OutputFileBasename>Bds</OutputFileBasename>
+ </ModuleDefinitions>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverEntryPoint</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>PrintLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DebugLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseMemoryLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>EfiShellLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>EdkGenericPlatformBdsLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiBootServicesTableLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>EdkGraphicsLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>MemoryAllocationLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DxeServicesTableLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>PerformanceLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>ReportStatusCodeLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>EdkGenericBdsLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>EdkIfrSupportLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiRuntimeServicesTableLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>HobLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DevicePathLib</Keyword>
+ </LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>BdsEntry.c</Filename>
+ <Filename>FrontPage.c</Filename>
+ <Filename>FrontPageStrings.uni</Filename>
+ <Filename>FrontPageVfr.Vfr</Filename>
+ <Filename>Language.c</Filename>
+ <Filename>String.c</Filename>
+ <Filename>Strings.uni</Filename>
+ <Filename>Capsules.c</Filename>
+ <Filename>MemoryTest.c</Filename>
+ <Filename>Hotkey.c</Filename>
+ <Filename>BootMaint/Bmstring.uni</Filename>
+ <Filename>BootMaint/Bm.vfr</Filename>
+ <Filename>BootMaint/BmLib.c</Filename>
+ <Filename>BootMaint/BootOption.c</Filename>
+ <Filename>BootMaint/ConsoleOption.c</Filename>
+ <Filename>BootMaint/Data.c</Filename>
+ <Filename>BootMaint/Variable.c</Filename>
+ <Filename>BootMaint/UpdatePage.c</Filename>
+ <Filename>BootMaint/BBSsupport.c</Filename>
+ <Filename>BootMaint/BootMaint.c</Filename>
+ <Filename>BootMaint/FileExplorer.c</Filename>
+ <Filename>BootMaint/FE.vfr</Filename>
+ <Filename>BootMngr/BootManager.c</Filename>
+ <Filename>BootMngr/BootManagerStrings.uni</Filename>
+ <Filename>BootMngr/BootManagerVfr.Vfr</Filename>
+ <Filename>DeviceMngr/DeviceManager.c</Filename>
+ <Filename>DeviceMngr/DeviceManagerStrings.uni</Filename>
+ <Filename>DeviceMngr/DeviceManagerVfr.Vfr</Filename>
+ <Filename>Bds.dxs</Filename>
+ <Filename>DeviceMngr/DeviceManager.h</Filename>
+ <Filename>BootMaint/FormGuid.h</Filename>
+ <Filename>String.h</Filename>
+ <Filename>BootMaint/BootMaint.h</Filename>
+ <Filename>BootMngr/BootManager.h</Filename>
+ <Filename>BootMaint/BBSsupport.h</Filename>
+ <Filename>Hotkey.h</Filename>
+ <Filename>Bds.h</Filename>
+ <Filename>Language.h</Filename>
+ <Filename>FrontPage.h</Filename>
+ <Filename>EdkILib.c</Filename>
+ </SourceFiles>
+ <NonProcessedFiles>
+ <Filename>DeviceMngr/PlatOverMngr/PlatOverMngr.c</Filename>
+ <Filename>DeviceMngr/PlatOverMngr/PlatOverMngr.dxs</Filename>
+ <Filename>DeviceMngr/PlatOverMngr/PlatOverMngr.h</Filename>
+ <Filename>DeviceMngr/PlatOverMngr/Vfr.vfr</Filename>
+ <Filename>DeviceMngr/PlatOverMngr/VfrStrings.uni</Filename>
+ <Filename>DeviceMngr/SetOptions/GetInfo.c</Filename>
+ <Filename>DeviceMngr/SetOptions/GetInfo.h</Filename>
+ <Filename>DeviceMngr/SetOptions/SetOptions.c</Filename>
+ <Filename>DeviceMngr/SetOptions/SetOptions.h</Filename>
+ <Filename>DeviceMngr/SetOptions/Vfr.vfr</Filename>
+ <Filename>DeviceMngr/SetOptions/VfrStrings.uni</Filename>
+ <Filename>HwErrRecSupport.c</Filename>
+ <Filename>HwErrRecSupport.h</Filename>
+ </NonProcessedFiles>
+ <PackageDependencies>
+ <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
+ <Package PackageGuid="3bd11b88-bf8b-4d90-9e04-77c97e58bbdd"/>
+ </PackageDependencies>
+ <Protocols>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiSerialIoProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiFormBrowser2ProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiHiiConfigAccessProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiHiiConfigRoutingProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiSimpleTextInputExProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiGraphicsOutputProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiBlockIoProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiUgaDrawProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiHiiDatabaseProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiConsoleControlProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiLegacyBiosProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiGenericMemTestProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiDataHubProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiBdsArchProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiCpuIoProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiLoadFileProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiSimpleFileSystemProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiHiiStringProtocolGuid</ProtocolCName>
+ </Protocol>
+ </Protocols>
+ <Guids>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiFlashMapHobGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gTerminalDriverGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiFileInfoGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiFileSystemVolumeLabelInfoIdGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiBootStateGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiHobListGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiGenericVariableGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiGlobalVariableGuid</GuidCName>
+ </GuidCNames>
+ </Guids>
+ <Externs>
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
+ <Extern>
+ <ModuleEntryPoint>BdsInitialize</ModuleEntryPoint>
+ </Extern>
+ </Externs>
+</ModuleSurfaceArea>
diff --git a/MdeModulePkg/Universal/BdsDxe/BdsEntry.c b/MdeModulePkg/Universal/BdsDxe/BdsEntry.c new file mode 100644 index 0000000000..b40e0ee7fa --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/BdsEntry.c @@ -0,0 +1,375 @@ +/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ BdsEntry.c
+
+Abstract:
+
+ The entry of the bds
+
+--*/
+
+#include "Bds.h"
+#include "Language.h"
+#include "FrontPage.h"
+#include "Hotkey.h"
+#include "HwErrRecSupport.h"
+
+
+EFI_BDS_ARCH_PROTOCOL_INSTANCE gBdsInstanceTemplate = {
+ EFI_BDS_ARCH_PROTOCOL_INSTANCE_SIGNATURE,
+ NULL,
+ {BdsEntry},
+ 0xFFFF,
+ TRUE,
+ EXTENSIVE
+};
+
+UINT16 *mBootNext = NULL;
+
+EFI_HANDLE mBdsImageHandle;
+
+EFI_STATUS
+EFIAPI
+BdsInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+
+ Install Boot Device Selection Protocol
+
+Arguments:
+
+ (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
+
+Returns:
+
+ EFI_SUCEESS - BDS has finished initializing.
+ Rerun the
+ dispatcher and recall BDS.Entry
+
+ Other - Return value from AllocatePool()
+ or gBS->InstallProtocolInterface
+
+--*/
+{
+ 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;
+}
+
+VOID
+BdsBootDeviceSelect (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ In the loop of attempt to boot for the boot order
+
+Arguments:
+
+ None.
+
+Returns:
+
+ None.
+
+--*/
+{
+ 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);
+ 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;
+ }
+ }
+
+}
+
+VOID
+EFIAPI
+BdsEntry (
+ IN EFI_BDS_ARCH_PROTOCOL *This
+ )
+/*++
+
+Routine Description:
+
+ Service routine for BdsInstance->Entry(). Devices are connected, the
+ consoles are initialized, and the boot options are tried.
+
+Arguments:
+
+ This - Protocol Instance structure.
+
+Returns:
+
+ EFI_SUCEESS - BDS->Entry has finished executing.
+
+--*/
+{
+ 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 (FALSE);
+
+ //
+ // 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 ;
+}
diff --git a/MdeModulePkg/Universal/BdsDxe/BootMaint/BBSsupport.c b/MdeModulePkg/Universal/BdsDxe/BootMaint/BBSsupport.c new file mode 100644 index 0000000000..2f0d5d9eb2 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/BootMaint/BBSsupport.c @@ -0,0 +1,1664 @@ +/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ BBSsupport.c
+
+Abstract:
+
+ This function deal with the legacy boot option, it create, delete
+ and manage the legacy boot option, all legacy boot option is getting from
+ the legacy BBS table.
+
+--*/
+
+#include "BBSsupport.h"
+
+EFI_DEVICE_PATH_PROTOCOL EndDevicePath[] = {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ END_DEVICE_PATH_LENGTH,
+ 0
+};
+
+VOID
+AsciiToUnicodeSize (
+ IN UINT8 *a,
+ IN UINTN Size,
+ OUT UINT16 *u
+ )
+/*++
+
+ Routine Description:
+
+ Translate the first n characters of an Ascii string to
+ Unicode characters. The count n is indicated by parameter
+ Size. If Size is greater than the length of string, then
+ the entire string is translated.
+
+ Arguments:
+
+ a - Pointer to input Ascii string.
+ Size - The number of characters to translate.
+ u - Pointer to output Unicode string buffer.
+
+ Returns:
+
+ None
+
+--*/
+{
+ UINTN i;
+
+ i = 0;
+ while (a[i] != 0) {
+ u[i] = (CHAR16) a[i];
+ if (i == Size) {
+ break;
+ }
+
+ i++;
+ }
+ u[i] = 0;
+}
+
+UINTN
+UnicodeToAscii (
+ IN CHAR16 *UStr,
+ IN UINTN Length,
+ OUT CHAR8 *AStr
+ )
+/*++
+Routine Description:
+
+ change a Unicode string t ASCII string
+
+Arguments:
+
+ UStr - Unicode string
+ Lenght - most possible length of AStr
+ AStr - ASCII string to pass out
+
+Returns:
+
+ Actuall length
+
+--*/
+{
+ UINTN Index;
+
+ //
+ // just buffer copy, not character copy
+ //
+ for (Index = 0; Index < Length; Index++) {
+ *AStr++ = (CHAR8) *UStr++;
+ }
+
+ return Index;
+}
+
+VOID
+BdsBuildLegacyDevNameString (
+ IN BBS_TABLE *CurBBSEntry,
+ IN UINTN Index,
+ IN UINTN BufSize,
+ OUT CHAR16 *BootString
+ )
+{
+ CHAR16 *Fmt;
+ CHAR16 *Type;
+ UINT8 *StringDesc;
+ CHAR16 temp[80];
+
+ switch (Index) {
+ //
+ // Primary Master
+ //
+ case 1:
+ Fmt = L"Primary Master %s";
+ break;
+
+ //
+ // Primary Slave
+ //
+ case 2:
+ Fmt = L"Primary Slave %s";
+ break;
+
+ //
+ // Secondary Master
+ //
+ case 3:
+ Fmt = L"Secondary Master %s";
+ break;
+
+ //
+ // Secondary Slave
+ //
+ case 4:
+ Fmt = L"Secondary Slave %s";
+ break;
+
+ default:
+ Fmt = L"%s";
+ break;
+ }
+
+ switch (CurBBSEntry->DeviceType) {
+ case BBS_FLOPPY:
+ Type = L"Floppy";
+ break;
+
+ case BBS_HARDDISK:
+ Type = L"Harddisk";
+ break;
+
+ case BBS_CDROM:
+ Type = L"CDROM";
+ break;
+
+ case BBS_PCMCIA:
+ Type = L"PCMCIAe";
+ break;
+
+ case BBS_USB:
+ Type = L"USB";
+ break;
+
+ case BBS_EMBED_NETWORK:
+ Type = L"Network";
+ break;
+
+ case BBS_BEV_DEVICE:
+ Type = L"BEVe";
+ break;
+
+ case BBS_UNKNOWN:
+ default:
+ Type = L"Unknown";
+ break;
+ }
+ //
+ // If current BBS entry has its description then use it.
+ //
+ StringDesc = (UINT8 *) (UINTN) ((CurBBSEntry->DescStringSegment << 4) + CurBBSEntry->DescStringOffset);
+ if (NULL != StringDesc) {
+ //
+ // Only get fisrt 32 characters, this is suggested by BBS spec
+ //
+ AsciiToUnicodeSize (StringDesc, 32, temp);
+ Fmt = L"%s";
+ Type = temp;
+ }
+
+ //
+ // BbsTable 16 entries are for onboard IDE.
+ // Set description string for SATA harddisks, Harddisk 0 ~ Harddisk 11
+ //
+ if (Index >= 5 && Index <= 16 && CurBBSEntry->DeviceType == BBS_HARDDISK) {
+ Fmt = L"%s %d";
+ UnicodeSPrint (BootString, BufSize, Fmt, Type, Index - 5);
+ } else {
+ UnicodeSPrint (BootString, BufSize, Fmt, Type);
+ }
+}
+
+EFI_STATUS
+BdsCreateLegacyBootOption (
+ IN BBS_TABLE *CurrentBbsEntry,
+ IN EFI_DEVICE_PATH_PROTOCOL *CurrentBbsDevPath,
+ IN UINTN Index,
+ IN OUT UINT16 **BootOrderList,
+ IN OUT UINTN *BootOrderListSize
+ )
+/*++
+
+ Routine Description:
+
+ Create a legacy boot option for the specified entry of
+ BBS table, save it as variable, and append it to the boot
+ order list.
+
+ Arguments:
+
+ CurrentBbsEntry - Pointer to current BBS table.
+ CurrentBbsDevPath - Pointer to the Device Path Protocol instance of BBS
+ Index - Index of the specified entry in BBS table.
+ BootOrderList - On input, the original boot order list.
+ On output, the new boot order list attached with the
+ created node.
+ BootOrderListSize - On input, the original size of boot order list.
+ - On output, the size of new boot order list.
+
+ Returns:
+
+ EFI_SUCCESS - Boot Option successfully created.
+ EFI_OUT_OF_RESOURCES - Fail to allocate necessary memory.
+ Other - Error occurs while setting variable.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT16 CurrentBootOptionNo;
+ UINT16 BootString[10];
+ UINT16 BootDesc[100];
+ CHAR8 HelpString[100];
+ UINT16 *NewBootOrderList;
+ UINTN BufferSize;
+ UINTN StringLen;
+ VOID *Buffer;
+ UINT8 *Ptr;
+ UINT16 CurrentBbsDevPathSize;
+ UINTN BootOrderIndex;
+ UINTN BootOrderLastIndex;
+ UINTN ArrayIndex;
+ BOOLEAN IndexNotFound;
+ BBS_BBS_DEVICE_PATH *NewBbsDevPathNode;
+
+ if (NULL == (*BootOrderList)) {
+ CurrentBootOptionNo = 0;
+ } else {
+ for (ArrayIndex = 0; ArrayIndex < (UINTN) (*BootOrderListSize / sizeof (UINT16)); ArrayIndex++) {
+ IndexNotFound = TRUE;
+ for (BootOrderIndex = 0; BootOrderIndex < (UINTN) (*BootOrderListSize / sizeof (UINT16)); BootOrderIndex++) {
+ if ((*BootOrderList)[BootOrderIndex] == ArrayIndex) {
+ IndexNotFound = FALSE;
+ break;
+ }
+ }
+
+ if (!IndexNotFound) {
+ continue;
+ } else {
+ break;
+ }
+ }
+
+ CurrentBootOptionNo = (UINT16) ArrayIndex;
+ }
+
+ UnicodeSPrint (
+ BootString,
+ sizeof (BootString),
+ L"Boot%04x",
+ CurrentBootOptionNo
+ );
+
+ BdsBuildLegacyDevNameString (CurrentBbsEntry, Index, sizeof (BootDesc), BootDesc);
+
+ //
+ // Create new BBS device path node with description string
+ //
+ UnicodeToAscii (BootDesc, StrSize (BootDesc), HelpString);
+ StringLen = AsciiStrLen (HelpString);
+ NewBbsDevPathNode = EfiAllocateZeroPool (sizeof (BBS_BBS_DEVICE_PATH) + StringLen);
+ if (NewBbsDevPathNode == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ CopyMem (NewBbsDevPathNode, CurrentBbsDevPath, sizeof (BBS_BBS_DEVICE_PATH));
+ CopyMem (NewBbsDevPathNode->String, HelpString, StringLen + 1);
+ SetDevicePathNodeLength (&(NewBbsDevPathNode->Header), sizeof (BBS_BBS_DEVICE_PATH) + StringLen);
+
+ //
+ // Create entire new CurrentBbsDevPath with end node
+ //
+ CurrentBbsDevPath = AppendDevicePathNode (
+ EndDevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *) NewBbsDevPathNode
+ );
+ if (CurrentBbsDevPath == NULL) {
+ FreePool (NewBbsDevPathNode);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CurrentBbsDevPathSize = (UINT16) (GetDevicePathSize (CurrentBbsDevPath));
+
+ BufferSize = sizeof (UINT32) +
+ sizeof (UINT16) +
+ StrSize (BootDesc) +
+ CurrentBbsDevPathSize +
+ sizeof (BBS_TABLE) +
+ sizeof (UINT16);
+
+ Buffer = EfiAllocateZeroPool (BufferSize);
+ if (Buffer == NULL) {
+ FreePool (NewBbsDevPathNode);
+ FreePool (CurrentBbsDevPath);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Ptr = (UINT8 *) Buffer;
+
+ *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE;
+ Ptr += sizeof (UINT32);
+
+ *((UINT16 *) Ptr) = CurrentBbsDevPathSize;
+ Ptr += sizeof (UINT16);
+
+ CopyMem (
+ Ptr,
+ BootDesc,
+ StrSize (BootDesc)
+ );
+ Ptr += StrSize (BootDesc);
+
+ CopyMem (
+ Ptr,
+ CurrentBbsDevPath,
+ CurrentBbsDevPathSize
+ );
+ Ptr += CurrentBbsDevPathSize;
+
+ CopyMem (
+ Ptr,
+ CurrentBbsEntry,
+ sizeof (BBS_TABLE)
+ );
+
+ Ptr += sizeof (BBS_TABLE);
+ *((UINT16 *) Ptr) = (UINT16) Index;
+
+ Status = gRT->SetVariable (
+ BootString,
+ &gEfiGlobalVariableGuid,
+ VAR_FLAG,
+ BufferSize,
+ Buffer
+ );
+
+ SafeFreePool (Buffer);
+ Buffer = NULL;
+
+ NewBootOrderList = EfiAllocateZeroPool (*BootOrderListSize + sizeof (UINT16));
+ if (NULL == NewBootOrderList) {
+ FreePool (NewBbsDevPathNode);
+ FreePool (CurrentBbsDevPath);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (NULL != *BootOrderList) {
+ CopyMem (NewBootOrderList, *BootOrderList, *BootOrderListSize);
+ }
+
+ SafeFreePool (*BootOrderList);
+
+ BootOrderLastIndex = (UINTN) (*BootOrderListSize / sizeof (UINT16));
+ NewBootOrderList[BootOrderLastIndex] = CurrentBootOptionNo;
+ *BootOrderListSize += sizeof (UINT16);
+ *BootOrderList = NewBootOrderList;
+
+ FreePool (NewBbsDevPathNode);
+ FreePool (CurrentBbsDevPath);
+ return Status;
+}
+
+BOOLEAN
+BdsIsLegacyBootOption (
+ IN UINT8 *BootOptionVar,
+ OUT BBS_TABLE **BbsEntry,
+ OUT UINT16 *BbsIndex
+ )
+{
+ UINT8 *Ptr;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ BOOLEAN Ret;
+ UINT16 DevPathLen;
+
+ Ptr = BootOptionVar;
+ Ptr += sizeof (UINT32);
+ DevPathLen = *(UINT16 *) Ptr;
+ Ptr += sizeof (UINT16);
+ Ptr += StrSize ((UINT16 *) Ptr);
+ DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
+ if ((BBS_DEVICE_PATH == DevicePath->Type) && (BBS_BBS_DP == DevicePath->SubType)) {
+ Ptr += DevPathLen;
+ *BbsEntry = (BBS_TABLE *) Ptr;
+ Ptr += sizeof (BBS_TABLE);
+ *BbsIndex = *(UINT16 *) Ptr;
+ Ret = TRUE;
+ } else {
+ *BbsEntry = NULL;
+ Ret = FALSE;
+ }
+
+ return Ret;
+}
+
+EFI_STATUS
+BdsDeleteBootOption (
+ IN UINTN OptionNumber,
+ IN OUT UINT16 *BootOrder,
+ IN OUT UINTN *BootOrderSize
+ )
+{
+ UINT16 BootOption[100];
+ UINTN Index;
+ EFI_STATUS Status;
+ UINTN Index2Del;
+
+ Status = EFI_SUCCESS;
+ Index2Del = 0;
+
+ UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", OptionNumber);
+ Status = EfiLibDeleteVariable (BootOption, &gEfiGlobalVariableGuid);
+ //
+ // adjust boot order array
+ //
+ for (Index = 0; Index < *BootOrderSize / sizeof (UINT16); Index++) {
+ if (BootOrder[Index] == OptionNumber) {
+ Index2Del = Index;
+ break;
+ }
+ }
+
+ if (Index != *BootOrderSize / sizeof (UINT16)) {
+ for (Index = 0; Index < *BootOrderSize / sizeof (UINT16) - 1; Index++) {
+ if (Index >= Index2Del) {
+ BootOrder[Index] = BootOrder[Index + 1];
+ }
+ }
+
+ *BootOrderSize -= sizeof (UINT16);
+ }
+
+ return Status;
+
+}
+
+EFI_STATUS
+BdsDeleteAllInvalidLegacyBootOptions (
+ VOID
+ )
+/*++
+
+ Routine Description:
+
+ Delete all the invalid legacy boot options.
+
+ Arguments:
+
+ None.
+
+ Returns:
+
+ EFI_SUCCESS - All invalide legacy boot options are deleted.
+ EFI_OUT_OF_RESOURCES - Fail to allocate necessary memory.
+ EFI_NOT_FOUND - Fail to retrive variable of boot order.
+ Other - Error occurs while setting variable or locating
+ protocol.
+
+--*/
+{
+ UINT16 *BootOrder;
+ UINT8 *BootOptionVar;
+ UINTN BootOrderSize;
+ UINTN BootOptionSize;
+ EFI_STATUS Status;
+ UINT16 HddCount;
+ UINT16 BbsCount;
+ HDD_INFO *LocalHddInfo;
+ BBS_TABLE *LocalBbsTable;
+ BBS_TABLE *BbsEntry;
+ UINT16 BbsIndex;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ UINTN Index;
+ UINT16 BootOption[10];
+ UINT16 BootDesc[100];
+ BOOLEAN DescStringMatch;
+
+ Status = EFI_SUCCESS;
+ BootOrder = NULL;
+ BootOrderSize = 0;
+ HddCount = 0;
+ BbsCount = 0;
+ LocalHddInfo = NULL;
+ LocalBbsTable = NULL;
+ BbsEntry = NULL;
+
+ Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ LegacyBios->GetBbsInfo (
+ LegacyBios,
+ &HddCount,
+ &LocalHddInfo,
+ &BbsCount,
+ &LocalBbsTable
+ );
+
+ BootOrder = BdsLibGetVariableAndSize (
+ L"BootOrder",
+ &gEfiGlobalVariableGuid,
+ &BootOrderSize
+ );
+ if (NULL == BootOrder) {
+ return EFI_NOT_FOUND;
+ }
+
+ Index = 0;
+ while (Index < BootOrderSize / sizeof (UINT16)) {
+ UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);
+ BootOptionVar = BdsLibGetVariableAndSize (
+ BootOption,
+ &gEfiGlobalVariableGuid,
+ &BootOptionSize
+ );
+ if (NULL == BootOptionVar) {
+ SafeFreePool (BootOrder);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, &BbsIndex)) {
+ SafeFreePool (BootOptionVar);
+ Index++;
+ continue;
+ }
+
+ //
+ // Check if BBS Description String is changed
+ //
+ DescStringMatch = FALSE;
+
+ BdsBuildLegacyDevNameString (
+ &LocalBbsTable[BbsIndex],
+ BbsIndex,
+ sizeof(BootDesc),
+ BootDesc
+ );
+
+ if (StrCmp (BootDesc, (UINT16*)(BootOptionVar + sizeof (UINT32) + sizeof (UINT16))) == 0) {
+ DescStringMatch = TRUE;
+ }
+
+ if (!((LocalBbsTable[BbsIndex].BootPriority == BBS_IGNORE_ENTRY) ||
+ (LocalBbsTable[BbsIndex].BootPriority == BBS_DO_NOT_BOOT_FROM)) &&
+ (LocalBbsTable[BbsIndex].DeviceType == BbsEntry->DeviceType) &&
+ DescStringMatch) {
+ Index++;
+ continue;
+ }
+
+ SafeFreePool (BootOptionVar);
+ //
+ // should delete
+ //
+ BdsDeleteBootOption (
+ BootOrder[Index],
+ BootOrder,
+ &BootOrderSize
+ );
+ }
+
+ if (BootOrderSize) {
+ Status = gRT->SetVariable (
+ L"BootOrder",
+ &gEfiGlobalVariableGuid,
+ VAR_FLAG,
+ BootOrderSize,
+ BootOrder
+ );
+ } else {
+ EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);
+ }
+
+ SafeFreePool (BootOrder);
+
+ return Status;
+}
+
+BOOLEAN
+BdsFindLegacyBootOptionByDevType (
+ IN UINT16 *BootOrder,
+ IN UINTN BootOptionNum,
+ IN UINT16 DevType,
+ OUT UINT32 *Attribute,
+ OUT UINT16 *BbsIndex,
+ OUT UINTN *OptionNumber
+ )
+{
+ UINTN Index;
+ UINTN BootOrderIndex;
+ UINT16 BootOption[100];
+ UINTN BootOptionSize;
+ UINT8 *BootOptionVar;
+ BBS_TABLE *BbsEntry;
+ BOOLEAN Found;
+
+ BbsEntry = NULL;
+ Found = FALSE;
+
+ if (NULL == BootOrder) {
+ return Found;
+ }
+
+ for (BootOrderIndex = 0; BootOrderIndex < BootOptionNum; BootOrderIndex++) {
+ Index = (UINTN) BootOrder[BootOrderIndex];
+ UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", Index);
+ BootOptionVar = BdsLibGetVariableAndSize (
+ BootOption,
+ &gEfiGlobalVariableGuid,
+ &BootOptionSize
+ );
+ if (NULL == BootOptionVar) {
+ continue;
+ }
+
+ if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, BbsIndex)) {
+ SafeFreePool (BootOptionVar);
+ continue;
+ }
+
+ if (BbsEntry->DeviceType != DevType) {
+ SafeFreePool (BootOptionVar);
+ continue;
+ }
+
+ *Attribute = *(UINT32 *) BootOptionVar;
+ *OptionNumber = Index;
+ Found = TRUE;
+ SafeFreePool (BootOptionVar);
+ break;
+ }
+
+ return Found;
+}
+
+EFI_STATUS
+BdsCreateOneLegacyBootOption (
+ IN BBS_TABLE *BbsItem,
+ IN UINTN Index,
+ IN OUT UINT16 **BootOrderList,
+ IN OUT UINTN *BootOrderListSize
+ )
+{
+ BBS_BBS_DEVICE_PATH BbsDevPathNode;
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DevPath;
+
+ DevPath = NULL;
+
+ BbsDevPathNode.Header.Type = BBS_DEVICE_PATH;
+ BbsDevPathNode.Header.SubType = BBS_BBS_DP;
+ SetDevicePathNodeLength (&BbsDevPathNode.Header, sizeof (BBS_BBS_DEVICE_PATH));
+ BbsDevPathNode.DeviceType = BbsItem->DeviceType;
+ CopyMem (&BbsDevPathNode.StatusFlag, &BbsItem->StatusFlags, sizeof (UINT16));
+
+ DevPath = AppendDevicePathNode (
+ EndDevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *) &BbsDevPathNode
+ );
+ if (NULL == DevPath) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = BdsCreateLegacyBootOption (
+ BbsItem,
+ DevPath,
+ Index,
+ BootOrderList,
+ BootOrderListSize
+ );
+ BbsItem->BootPriority = 0x00;
+
+ FreePool (DevPath);
+
+ return Status;
+}
+
+EFI_STATUS
+BdsAddNonExistingLegacyBootOptions (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Add the legacy boot options from BBS table if they do not exist.
+
+Arguments:
+
+ None.
+
+Returns:
+
+ EFI_SUCCESS - The boot options are added successfully or they are already in boot options.
+ others - An error occurred when creating legacy boot options.
+
+--*/
+{
+ UINT16 *BootOrder;
+ UINTN BootOrderSize;
+ EFI_STATUS Status;
+ UINT16 HddCount;
+ UINT16 BbsCount;
+ HDD_INFO *LocalHddInfo;
+ BBS_TABLE *LocalBbsTable;
+ UINT16 BbsIndex;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ UINTN Index;
+ UINT32 Attribute;
+ UINTN OptionNumber;
+ BOOLEAN Ret;
+
+ BootOrder = NULL;
+ HddCount = 0;
+ BbsCount = 0;
+ LocalHddInfo = NULL;
+ LocalBbsTable = NULL;
+
+ Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ LegacyBios->GetBbsInfo (
+ LegacyBios,
+ &HddCount,
+ &LocalHddInfo,
+ &BbsCount,
+ &LocalBbsTable
+ );
+
+ BootOrder = BdsLibGetVariableAndSize (
+ L"BootOrder",
+ &gEfiGlobalVariableGuid,
+ &BootOrderSize
+ );
+ if (NULL == BootOrder) {
+ BootOrderSize = 0;
+ }
+
+ for (Index = 0; Index < BbsCount; Index++) {
+ if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||
+ (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)
+ ) {
+ continue;
+ }
+
+ Ret = BdsFindLegacyBootOptionByDevType (
+ BootOrder,
+ BootOrderSize / sizeof (UINT16),
+ LocalBbsTable[Index].DeviceType,
+ &Attribute,
+ &BbsIndex,
+ &OptionNumber
+ );
+ if (Ret) {
+ continue;
+ }
+
+ //
+ // Not found such type of legacy device in boot options or we found but it's disabled
+ // so we have to create one and put it to the tail of boot order list
+ //
+ Status = BdsCreateOneLegacyBootOption (
+ &LocalBbsTable[Index],
+ Index,
+ &BootOrder,
+ &BootOrderSize
+ );
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ }
+
+ if (BootOrderSize > 0) {
+ Status = gRT->SetVariable (
+ L"BootOrder",
+ &gEfiGlobalVariableGuid,
+ VAR_FLAG,
+ BootOrderSize,
+ BootOrder
+ );
+ } else {
+ EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);
+ }
+
+ if (BootOrder != NULL) {
+ SafeFreePool (BootOrder);
+ }
+
+ return Status;
+}
+
+UINT16 *
+BdsFillDevOrderBuf (
+ IN BBS_TABLE *BbsTable,
+ IN BBS_TYPE BbsType,
+ IN UINTN BbsCount,
+ IN UINT16 *Buf
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < BbsCount; Index++) {
+ if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) {
+ continue;
+ }
+
+ if (BbsTable[Index].DeviceType != BbsType) {
+ continue;
+ }
+
+ *Buf = (UINT16) (Index & 0xFF);
+ Buf++;
+ }
+
+ return Buf;
+}
+
+EFI_STATUS
+BdsCreateDevOrder (
+ IN BBS_TABLE *BbsTable,
+ IN UINT16 BbsCount
+ )
+{
+ UINTN Index;
+ UINTN FDCount;
+ UINTN HDCount;
+ UINTN CDCount;
+ UINTN NETCount;
+ UINTN BEVCount;
+ UINTN TotalSize;
+ UINTN HeaderSize;
+ UINT8 *DevOrder;
+ UINT8 *Ptr;
+ EFI_STATUS Status;
+
+ FDCount = 0;
+ HDCount = 0;
+ CDCount = 0;
+ NETCount = 0;
+ BEVCount = 0;
+ TotalSize = 0;
+ HeaderSize = sizeof (BBS_TYPE) + sizeof (UINT16);
+ DevOrder = NULL;
+ Ptr = NULL;
+ Status = EFI_SUCCESS;
+
+ for (Index = 0; Index < BbsCount; Index++) {
+ if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) {
+ continue;
+ }
+
+ switch (BbsTable[Index].DeviceType) {
+ case BBS_FLOPPY:
+ FDCount++;
+ break;
+
+ case BBS_HARDDISK:
+ HDCount++;
+ break;
+
+ case BBS_CDROM:
+ CDCount++;
+ break;
+
+ case BBS_EMBED_NETWORK:
+ NETCount++;
+ break;
+
+ case BBS_BEV_DEVICE:
+ BEVCount++;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ TotalSize += (HeaderSize + sizeof (UINT16) * FDCount);
+ TotalSize += (HeaderSize + sizeof (UINT16) * HDCount);
+ TotalSize += (HeaderSize + sizeof (UINT16) * CDCount);
+ TotalSize += (HeaderSize + sizeof (UINT16) * NETCount);
+ TotalSize += (HeaderSize + sizeof (UINT16) * BEVCount);
+
+ DevOrder = EfiAllocateZeroPool (TotalSize);
+ if (NULL == DevOrder) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Ptr = DevOrder;
+
+ *((BBS_TYPE *) Ptr) = BBS_FLOPPY;
+ Ptr += sizeof (BBS_TYPE);
+ *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + FDCount * sizeof (UINT16));
+ Ptr += sizeof (UINT16);
+ if (FDCount) {
+ Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_FLOPPY, BbsCount, (UINT16 *) Ptr);
+ }
+
+ *((BBS_TYPE *) Ptr) = BBS_HARDDISK;
+ Ptr += sizeof (BBS_TYPE);
+ *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));
+ Ptr += sizeof (UINT16);
+ if (HDCount) {
+ Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_HARDDISK, BbsCount, (UINT16 *) Ptr);
+ }
+
+ *((BBS_TYPE *) Ptr) = BBS_CDROM;
+ Ptr += sizeof (BBS_TYPE);
+ *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));
+ Ptr += sizeof (UINT16);
+ if (CDCount) {
+ Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_CDROM, BbsCount, (UINT16 *) Ptr);
+ }
+
+ *((BBS_TYPE *) Ptr) = BBS_EMBED_NETWORK;
+ Ptr += sizeof (BBS_TYPE);
+ *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));
+ Ptr += sizeof (UINT16);
+ if (NETCount) {
+ Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_EMBED_NETWORK, BbsCount, (UINT16 *) Ptr);
+ }
+
+ *((BBS_TYPE *) Ptr) = BBS_BEV_DEVICE;
+ Ptr += sizeof (BBS_TYPE);
+ *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));
+ Ptr += sizeof (UINT16);
+ if (BEVCount) {
+ Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_BEV_DEVICE, BbsCount, (UINT16 *) Ptr);
+ }
+
+ Status = gRT->SetVariable (
+ VarLegacyDevOrder,
+ &EfiLegacyDevOrderGuid,
+ VAR_FLAG,
+ TotalSize,
+ DevOrder
+ );
+ SafeFreePool (DevOrder);
+
+ return Status;
+}
+
+EFI_STATUS
+BdsUpdateLegacyDevOrder (
+ VOID
+ )
+/*++
+Format of LegacyDevOrder variable:
+|-----------------------------------------------------------------------------------------------------------------
+| BBS_FLOPPY | Length | Index0 | Index1 | ... | BBS_HARDDISK | Length | Index0 | Index1 | ... | BBS_CDROM | Length | Index0 | ...
+|-----------------------------------------------------------------------------------------------------------------
+
+Length is a 16 bit integer, it indicates how many Indexes follows, including the size of itself.
+Index# is a 16 bit integer, the low byte of it stands for the index in BBS table
+ the high byte of it only have two value 0 and 0xFF, 0xFF means this device has been
+ disabled by user.
+--*/
+{
+ UINT8 *DevOrder;
+ UINT8 *NewDevOrder;
+ UINTN DevOrderSize;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ EFI_STATUS Status;
+ UINT16 HddCount;
+ UINT16 BbsCount;
+ HDD_INFO *LocalHddInfo;
+ BBS_TABLE *LocalBbsTable;
+ UINTN Index;
+ UINTN Index2;
+ UINTN *Idx;
+ UINTN FDCount;
+ UINTN HDCount;
+ UINTN CDCount;
+ UINTN NETCount;
+ UINTN BEVCount;
+ UINTN TotalSize;
+ UINTN HeaderSize;
+ UINT8 *Ptr;
+ UINT8 *NewPtr;
+ UINT16 *NewFDPtr;
+ UINT16 *NewHDPtr;
+ UINT16 *NewCDPtr;
+ UINT16 *NewNETPtr;
+ UINT16 *NewBEVPtr;
+ UINT16 *NewDevPtr;
+ UINT16 Length;
+ UINT16 tmp;
+ UINTN FDIndex;
+ UINTN HDIndex;
+ UINTN CDIndex;
+ UINTN NETIndex;
+ UINTN BEVIndex;
+
+ LocalHddInfo = NULL;
+ LocalBbsTable = NULL;
+ Idx = NULL;
+ FDCount = 0;
+ HDCount = 0;
+ CDCount = 0;
+ NETCount = 0;
+ BEVCount = 0;
+ TotalSize = 0;
+ HeaderSize = sizeof (BBS_TYPE) + sizeof (UINT16);
+ FDIndex = 0;
+ HDIndex = 0;
+ CDIndex = 0;
+ NETIndex = 0;
+ BEVIndex = 0;
+ NewDevPtr = NULL;
+
+ Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ LegacyBios->GetBbsInfo (
+ LegacyBios,
+ &HddCount,
+ &LocalHddInfo,
+ &BbsCount,
+ &LocalBbsTable
+ );
+
+ DevOrder = (UINT8 *) BdsLibGetVariableAndSize (
+ VarLegacyDevOrder,
+ &EfiLegacyDevOrderGuid,
+ &DevOrderSize
+ );
+ if (NULL == DevOrder) {
+ return BdsCreateDevOrder (LocalBbsTable, BbsCount);
+ }
+ //
+ // First we figure out how many boot devices with same device type respectively
+ //
+ for (Index = 0; Index < BbsCount; Index++) {
+ if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||
+ (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)
+ ) {
+ continue;
+ }
+
+ switch (LocalBbsTable[Index].DeviceType) {
+ case BBS_FLOPPY:
+ FDCount++;
+ break;
+
+ case BBS_HARDDISK:
+ HDCount++;
+ break;
+
+ case BBS_CDROM:
+ CDCount++;
+ break;
+
+ case BBS_EMBED_NETWORK:
+ NETCount++;
+ break;
+
+ case BBS_BEV_DEVICE:
+ BEVCount++;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ TotalSize += (HeaderSize + FDCount * sizeof (UINT16));
+ TotalSize += (HeaderSize + HDCount * sizeof (UINT16));
+ TotalSize += (HeaderSize + CDCount * sizeof (UINT16));
+ TotalSize += (HeaderSize + NETCount * sizeof (UINT16));
+ TotalSize += (HeaderSize + BEVCount * sizeof (UINT16));
+
+ NewDevOrder = EfiAllocateZeroPool (TotalSize);
+ if (NULL == NewDevOrder) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NewFDPtr = (UINT16 *) (NewDevOrder + HeaderSize);
+ NewHDPtr = (UINT16 *) ((UINT8 *) NewFDPtr + FDCount * sizeof (UINT16) + HeaderSize);
+ NewCDPtr = (UINT16 *) ((UINT8 *) NewHDPtr + HDCount * sizeof (UINT16) + HeaderSize);
+ NewNETPtr = (UINT16 *) ((UINT8 *) NewCDPtr + CDCount * sizeof (UINT16) + HeaderSize);
+ NewBEVPtr = (UINT16 *) ((UINT8 *) NewNETPtr + NETCount * sizeof (UINT16) + HeaderSize);
+
+ //
+ // copy FD
+ //
+ Ptr = DevOrder;
+ NewPtr = NewDevOrder;
+ *((BBS_TYPE *) NewPtr) = *((BBS_TYPE *) Ptr);
+ Ptr += sizeof (BBS_TYPE);
+ NewPtr += sizeof (BBS_TYPE);
+ Length = *((UINT16 *) Ptr);
+ *((UINT16 *) NewPtr) = (UINT16) (sizeof (UINT16) + FDCount * sizeof (UINT16));
+ Ptr += sizeof (UINT16);
+
+ for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {
+ if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||
+ LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||
+ LocalBbsTable[*Ptr].DeviceType != BBS_FLOPPY
+ ) {
+ Ptr += sizeof (UINT16);
+ continue;
+ }
+
+ NewFDPtr[FDIndex] = *(UINT16 *) Ptr;
+ FDIndex++;
+ Ptr += sizeof (UINT16);
+ }
+ //
+ // copy HD
+ //
+ NewPtr = (UINT8 *) NewHDPtr - HeaderSize;
+ *((BBS_TYPE *) NewPtr) = *((BBS_TYPE *) Ptr);
+ Ptr += sizeof (BBS_TYPE);
+ NewPtr += sizeof (BBS_TYPE);
+ Length = *((UINT16 *) Ptr);
+ *((UINT16 *) NewPtr) = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));
+ Ptr += sizeof (UINT16);
+
+ for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {
+ if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||
+ LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||
+ LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||
+ LocalBbsTable[*Ptr].DeviceType != BBS_HARDDISK
+ ) {
+ Ptr += sizeof (UINT16);
+ continue;
+ }
+
+ NewHDPtr[HDIndex] = *(UINT16 *) Ptr;
+ HDIndex++;
+ Ptr += sizeof (UINT16);
+ }
+ //
+ // copy CD
+ //
+ NewPtr = (UINT8 *) NewCDPtr - HeaderSize;
+ *((BBS_TYPE *) NewPtr) = *((BBS_TYPE *) Ptr);
+ Ptr += sizeof (BBS_TYPE);
+ NewPtr += sizeof (BBS_TYPE);
+ Length = *((UINT16 *) Ptr);
+ *((UINT16 *) NewPtr) = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));
+ Ptr += sizeof (UINT16);
+
+ for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {
+ if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||
+ LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||
+ LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||
+ LocalBbsTable[*Ptr].DeviceType != BBS_CDROM
+ ) {
+ Ptr += sizeof (UINT16);
+ continue;
+ }
+
+ NewCDPtr[CDIndex] = *(UINT16 *) Ptr;
+ CDIndex++;
+ Ptr += sizeof (UINT16);
+ }
+ //
+ // copy NET
+ //
+ NewPtr = (UINT8 *) NewNETPtr - HeaderSize;
+ *((BBS_TYPE *) NewPtr) = *((BBS_TYPE *) Ptr);
+ Ptr += sizeof (BBS_TYPE);
+ NewPtr += sizeof (BBS_TYPE);
+ Length = *((UINT16 *) Ptr);
+ *((UINT16 *) NewPtr) = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));
+ Ptr += sizeof (UINT16);
+
+ for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {
+ if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||
+ LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||
+ LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||
+ LocalBbsTable[*Ptr].DeviceType != BBS_EMBED_NETWORK
+ ) {
+ Ptr += sizeof (UINT16);
+ continue;
+ }
+
+ NewNETPtr[NETIndex] = *(UINT16 *) Ptr;
+ NETIndex++;
+ Ptr += sizeof (UINT16);
+ }
+ //
+ // copy BEV
+ //
+ NewPtr = (UINT8 *) NewBEVPtr - HeaderSize;
+ *((BBS_TYPE *) NewPtr) = *((BBS_TYPE *) Ptr);
+ Ptr += sizeof (BBS_TYPE);
+ NewPtr += sizeof (BBS_TYPE);
+ Length = *((UINT16 *) Ptr);
+ *((UINT16 *) NewPtr) = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));
+ Ptr += sizeof (UINT16);
+
+ for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {
+ if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||
+ LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||
+ LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||
+ LocalBbsTable[*Ptr].DeviceType != BBS_BEV_DEVICE
+ ) {
+ Ptr += sizeof (UINT16);
+ continue;
+ }
+
+ NewBEVPtr[BEVIndex] = *(UINT16 *) Ptr;
+ BEVIndex++;
+ Ptr += sizeof (UINT16);
+ }
+
+ for (Index = 0; Index < BbsCount; Index++) {
+ if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||
+ (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)
+ ) {
+ continue;
+ }
+
+ switch (LocalBbsTable[Index].DeviceType) {
+ case BBS_FLOPPY:
+ Idx = &FDIndex;
+ NewDevPtr = NewFDPtr;
+ break;
+
+ case BBS_HARDDISK:
+ Idx = &HDIndex;
+ NewDevPtr = NewHDPtr;
+ break;
+
+ case BBS_CDROM:
+ Idx = &CDIndex;
+ NewDevPtr = NewCDPtr;
+ break;
+
+ case BBS_EMBED_NETWORK:
+ Idx = &NETIndex;
+ NewDevPtr = NewNETPtr;
+ break;
+
+ case BBS_BEV_DEVICE:
+ Idx = &BEVIndex;
+ NewDevPtr = NewBEVPtr;
+ break;
+
+ default:
+ Idx = NULL;
+ break;
+ }
+ //
+ // at this point we have copied those valid indexes to new buffer
+ // and we should check if there is any new appeared boot device
+ //
+ if (Idx) {
+ for (Index2 = 0; Index2 < *Idx; Index2++) {
+ if ((NewDevPtr[Index2] & 0xFF) == (UINT16) Index) {
+ break;
+ }
+ }
+
+ if (Index2 == *Idx) {
+ //
+ // Index2 == *Idx means we didn't find Index
+ // so Index is a new appeared device's index in BBS table
+ // save it.
+ //
+ NewDevPtr[*Idx] = (UINT16) (Index & 0xFF);
+ (*Idx)++;
+ }
+ }
+ }
+
+ if (FDCount) {
+ //
+ // Just to make sure that disabled indexes are all at the end of the array
+ //
+ for (Index = 0; Index < FDIndex - 1; Index++) {
+ if (0xFF00 != (NewFDPtr[Index] & 0xFF00)) {
+ continue;
+ }
+
+ for (Index2 = Index + 1; Index2 < FDIndex; Index2++) {
+ if (0 == (NewFDPtr[Index2] & 0xFF00)) {
+ tmp = NewFDPtr[Index];
+ NewFDPtr[Index] = NewFDPtr[Index2];
+ NewFDPtr[Index2] = tmp;
+ break;
+ }
+ }
+ }
+ }
+
+ if (HDCount) {
+ //
+ // Just to make sure that disabled indexes are all at the end of the array
+ //
+ for (Index = 0; Index < HDIndex - 1; Index++) {
+ if (0xFF00 != (NewHDPtr[Index] & 0xFF00)) {
+ continue;
+ }
+
+ for (Index2 = Index + 1; Index2 < HDIndex; Index2++) {
+ if (0 == (NewHDPtr[Index2] & 0xFF00)) {
+ tmp = NewHDPtr[Index];
+ NewHDPtr[Index] = NewHDPtr[Index2];
+ NewHDPtr[Index2] = tmp;
+ break;
+ }
+ }
+ }
+ }
+
+ if (CDCount) {
+ //
+ // Just to make sure that disabled indexes are all at the end of the array
+ //
+ for (Index = 0; Index < CDIndex - 1; Index++) {
+ if (0xFF00 != (NewCDPtr[Index] & 0xFF00)) {
+ continue;
+ }
+
+ for (Index2 = Index + 1; Index2 < CDIndex; Index2++) {
+ if (0 == (NewCDPtr[Index2] & 0xFF00)) {
+ tmp = NewCDPtr[Index];
+ NewCDPtr[Index] = NewCDPtr[Index2];
+ NewCDPtr[Index2] = tmp;
+ break;
+ }
+ }
+ }
+ }
+
+ if (NETCount) {
+ //
+ // Just to make sure that disabled indexes are all at the end of the array
+ //
+ for (Index = 0; Index < NETIndex - 1; Index++) {
+ if (0xFF00 != (NewNETPtr[Index] & 0xFF00)) {
+ continue;
+ }
+
+ for (Index2 = Index + 1; Index2 < NETIndex; Index2++) {
+ if (0 == (NewNETPtr[Index2] & 0xFF00)) {
+ tmp = NewNETPtr[Index];
+ NewNETPtr[Index] = NewNETPtr[Index2];
+ NewNETPtr[Index2] = tmp;
+ break;
+ }
+ }
+ }
+ }
+
+ if (BEVCount) {
+ //
+ // Just to make sure that disabled indexes are all at the end of the array
+ //
+ for (Index = 0; Index < BEVIndex - 1; Index++) {
+ if (0xFF00 != (NewBEVPtr[Index] & 0xFF00)) {
+ continue;
+ }
+
+ for (Index2 = Index + 1; Index2 < BEVIndex; Index2++) {
+ if (0 == (NewBEVPtr[Index2] & 0xFF00)) {
+ tmp = NewBEVPtr[Index];
+ NewBEVPtr[Index] = NewBEVPtr[Index2];
+ NewBEVPtr[Index2] = tmp;
+ break;
+ }
+ }
+ }
+ }
+
+ SafeFreePool (DevOrder);
+
+ Status = gRT->SetVariable (
+ VarLegacyDevOrder,
+ &EfiLegacyDevOrderGuid,
+ VAR_FLAG,
+ TotalSize,
+ NewDevOrder
+ );
+ SafeFreePool (NewDevOrder);
+
+ return Status;
+}
+
+EFI_STATUS
+BdsSetBootPriority4SameTypeDev (
+ IN UINT16 DeviceType,
+ IN OUT BBS_TABLE *LocalBbsTable,
+ IN OUT UINT16 *Priority
+ )
+/*++
+DeviceType - BBS_FLOPPY, BBS_HARDDISK, BBS_CDROM and so on
+LocalBbsTable - BBS table instance
+Priority - As input arg, it is the start point of boot priority, as output arg, it is the start point of boot
+ priority can be used next time.
+--*/
+{
+ UINT8 *DevOrder;
+
+ UINT8 *OrigBuffer;
+ UINT16 *DevIndex;
+ UINTN DevOrderSize;
+ UINTN DevCount;
+ UINTN Index;
+
+ DevOrder = BdsLibGetVariableAndSize (
+ VarLegacyDevOrder,
+ &EfiLegacyDevOrderGuid,
+ &DevOrderSize
+ );
+ if (NULL == DevOrder) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ OrigBuffer = DevOrder;
+ while (DevOrder < OrigBuffer + DevOrderSize) {
+ if (DeviceType == * (BBS_TYPE *) DevOrder) {
+ break;
+ }
+
+ DevOrder += sizeof (BBS_TYPE);
+ DevOrder += *(UINT16 *) DevOrder;
+ }
+
+ if (DevOrder >= OrigBuffer + DevOrderSize) {
+ SafeFreePool (OrigBuffer);
+ return EFI_NOT_FOUND;
+ }
+
+ DevOrder += sizeof (BBS_TYPE);
+ DevCount = (*((UINT16 *) DevOrder) - sizeof (UINT16)) / sizeof (UINT16);
+ DevIndex = (UINT16 *) (DevOrder + sizeof (UINT16));
+ //
+ // If the high byte of the DevIndex is 0xFF, it indicates that this device has been disabled.
+ //
+ for (Index = 0; Index < DevCount; Index++) {
+ if ((DevIndex[Index] & 0xFF00) == 0xFF00) {
+ //
+ // LocalBbsTable[DevIndex[Index] & 0xFF].BootPriority = BBS_DISABLED_ENTRY;
+ //
+ } else {
+ LocalBbsTable[DevIndex[Index] & 0xFF].BootPriority = *Priority;
+ (*Priority)++;
+ }
+ }
+
+ SafeFreePool (OrigBuffer);
+ return EFI_SUCCESS;
+}
+
+VOID
+PrintBbsTable (
+ IN BBS_TABLE *LocalBbsTable
+ )
+{
+ UINT16 Idx;
+
+ DEBUG ((DEBUG_ERROR, "\n"));
+ DEBUG ((DEBUG_ERROR, " NO Prio bb/dd/ff cl/sc Type Stat segm:offs\n"));
+ DEBUG ((DEBUG_ERROR, "=============================================\n"));
+ for (Idx = 0; Idx < MAX_BBS_ENTRIES; Idx++) {
+ if ((LocalBbsTable[Idx].BootPriority == BBS_IGNORE_ENTRY) ||
+ (LocalBbsTable[Idx].BootPriority == BBS_DO_NOT_BOOT_FROM) ||
+ (LocalBbsTable[Idx].BootPriority == BBS_LOWEST_PRIORITY)
+ ) {
+ continue;
+ }
+
+ DEBUG (
+ (DEBUG_ERROR,
+ " %02x: %04x %02x/%02x/%02x %02x/02%x %04x %04x %04x:%04x\n",
+ (UINTN) Idx,
+ (UINTN) LocalBbsTable[Idx].BootPriority,
+ (UINTN) LocalBbsTable[Idx].Bus,
+ (UINTN) LocalBbsTable[Idx].Device,
+ (UINTN) LocalBbsTable[Idx].Function,
+ (UINTN) LocalBbsTable[Idx].Class,
+ (UINTN) LocalBbsTable[Idx].SubClass,
+ (UINTN) LocalBbsTable[Idx].DeviceType,
+ (UINTN) * (UINT16 *) &LocalBbsTable[Idx].StatusFlags,
+ (UINTN) LocalBbsTable[Idx].BootHandlerSegment,
+ (UINTN) LocalBbsTable[Idx].BootHandlerOffset,
+ (UINTN) ((LocalBbsTable[Idx].MfgStringSegment << 4) + LocalBbsTable[Idx].MfgStringOffset),
+ (UINTN) ((LocalBbsTable[Idx].DescStringSegment << 4) + LocalBbsTable[Idx].DescStringOffset))
+ );
+ }
+
+ DEBUG ((DEBUG_ERROR, "\n"));
+}
+
+EFI_STATUS
+BdsRefreshBbsTableForBoot (
+ IN BDS_COMMON_OPTION *Entry
+ )
+{
+ EFI_STATUS Status;
+ UINT16 HddCount;
+ UINT16 BbsCount;
+ HDD_INFO *LocalHddInfo;
+ BBS_TABLE *LocalBbsTable;
+ UINT16 DevType;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ UINTN Index;
+ UINT16 Priority;
+ UINT16 *BootOrder;
+ UINTN BootOrderSize;
+ UINT8 *BootOptionVar;
+ UINTN BootOptionSize;
+ UINT16 BootOption[100];
+ UINT8 *Ptr;
+ UINT16 DevPathLen;
+ EFI_DEVICE_PATH_PROTOCOL *DevPath;
+
+ HddCount = 0;
+ BbsCount = 0;
+ LocalHddInfo = NULL;
+ LocalBbsTable = NULL;
+ DevType = BBS_UNKNOWN;
+
+ Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ LegacyBios->GetBbsInfo (
+ LegacyBios,
+ &HddCount,
+ &LocalHddInfo,
+ &BbsCount,
+ &LocalBbsTable
+ );
+ //
+ // First, set all the present devices' boot priority to BBS_UNPRIORITIZED_ENTRY
+ // We will set them according to the settings setup by user
+ //
+ for (Index = 0; Index < BbsCount; Index++) {
+ if (!((BBS_IGNORE_ENTRY == LocalBbsTable[Index].BootPriority) ||
+ (BBS_DO_NOT_BOOT_FROM == LocalBbsTable[Index].BootPriority) ||
+ (BBS_LOWEST_PRIORITY == LocalBbsTable[Index].BootPriority))) {
+ LocalBbsTable[Index].BootPriority = BBS_UNPRIORITIZED_ENTRY;
+ }
+ }
+ //
+ // boot priority always starts at 0
+ //
+ Priority = 0;
+ if (Entry->LoadOptionsSize == sizeof (BBS_TABLE) + sizeof (UINT16)) {
+ //
+ // If Entry stands for a legacy boot option, we prioritize the devices with the same type first.
+ //
+ DevType = ((BBS_TABLE *) Entry->LoadOptions)->DeviceType;
+ Status = BdsSetBootPriority4SameTypeDev (
+ DevType,
+ LocalBbsTable,
+ &Priority
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+ //
+ // we have to set the boot priority for other BBS entries with different device types
+ //
+ BootOrder = (UINT16 *) BdsLibGetVariableAndSize (
+ L"BootOrder",
+ &gEfiGlobalVariableGuid,
+ &BootOrderSize
+ );
+ for (Index = 0; BootOrder && Index < BootOrderSize / sizeof (UINT16); Index++) {
+ UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);
+ BootOptionVar = BdsLibGetVariableAndSize (
+ BootOption,
+ &gEfiGlobalVariableGuid,
+ &BootOptionSize
+ );
+ if (NULL == BootOptionVar) {
+ continue;
+ }
+
+ Ptr = BootOptionVar;
+
+ Ptr += sizeof (UINT32);
+ DevPathLen = *(UINT16 *) Ptr;
+ Ptr += sizeof (UINT16);
+ Ptr += StrSize ((UINT16 *) Ptr);
+ DevPath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
+ if (BBS_DEVICE_PATH != DevPath->Type || BBS_BBS_DP != DevPath->SubType) {
+ SafeFreePool (BootOptionVar);
+ continue;
+ }
+
+ Ptr += DevPathLen;
+ if (DevType == ((BBS_TABLE *) Ptr)->DeviceType) {
+ //
+ // We don't want to process twice for a device type
+ //
+ SafeFreePool (BootOptionVar);
+ continue;
+ }
+
+ Status = BdsSetBootPriority4SameTypeDev (
+ ((BBS_TABLE *) Ptr)->DeviceType,
+ LocalBbsTable,
+ &Priority
+ );
+ SafeFreePool (BootOptionVar);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ }
+
+ if (BootOrder) {
+ SafeFreePool (BootOrder);
+ }
+ //
+ // For debug
+ //
+ PrintBbsTable (LocalBbsTable);
+
+ return Status;
+}
diff --git a/MdeModulePkg/Universal/BdsDxe/BootMaint/BBSsupport.h b/MdeModulePkg/Universal/BdsDxe/BootMaint/BBSsupport.h new file mode 100644 index 0000000000..532223fa80 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/BootMaint/BBSsupport.h @@ -0,0 +1,78 @@ +/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ BBSsupport.h
+
+Abstract:
+
+ declares interface functions
+
+Revision History
+
+--*/
+
+#ifndef _EFI_BDS_BBS_SUPPORT_H
+#define _EFI_BDS_BBS_SUPPORT_H
+
+#include "BootMaint.h"
+//
+// Bugbug: Candidate for a PCD entries
+//
+#define MAX_BBS_ENTRIES 0x100
+
+VOID
+BdsBuildLegacyDevNameString (
+ IN BBS_TABLE *CurBBSEntry,
+ IN UINTN Index,
+ IN UINTN BufSize,
+ OUT CHAR16 *BootString
+ );
+
+EFI_STATUS
+BdsDeleteAllInvalidLegacyBootOptions (
+ VOID
+ );
+
+EFI_STATUS
+BdsAddNonExistingLegacyBootOptions (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Add the legacy boot options from BBS table if they do not exist.
+
+Arguments:
+
+ None.
+
+Returns:
+
+ EFI_SUCCESS - The boot options are added successfully or they are already in boot options.
+ others - An error occurred when creating legacy boot options.
+
+--*/
+;
+
+EFI_STATUS
+BdsUpdateLegacyDevOrder (
+ VOID
+ );
+
+EFI_STATUS
+BdsRefreshBbsTableForBoot (
+ IN BDS_COMMON_OPTION *Entry
+ );
+
+#endif
diff --git a/MdeModulePkg/Universal/BdsDxe/BootMaint/Bm.vfr b/MdeModulePkg/Universal/BdsDxe/BootMaint/Bm.vfr new file mode 100644 index 0000000000..93cbbeaf8f --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/BootMaint/Bm.vfr @@ -0,0 +1,391 @@ +// *++
+//
+// Copyright (c) 2004 - 2007, Intel Corporation
+// 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.
+//
+// Module Name:
+//
+// bm.vfr
+//
+// Abstract:
+//
+// Boot Maintenance Utility Formset
+//
+// Revision History:
+//
+// --*/
+
+#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;
diff --git a/MdeModulePkg/Universal/BdsDxe/BootMaint/BmLib.c b/MdeModulePkg/Universal/BdsDxe/BootMaint/BmLib.c new file mode 100644 index 0000000000..e9a7409371 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/BootMaint/BmLib.c @@ -0,0 +1,563 @@ +/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ bmlib.c
+
+AgBStract:
+
+ Boot Maintainence Helper functions
+
+--*/
+
+#include "BootMaint.h"
+
+VOID *
+EfiAllocateZeroPool (
+ IN UINTN Size
+ )
+/*++
+
+Routine Description:
+ Wrap original AllocatePool gBS call
+ and ZeroMem gBS call into a single
+ function in order to decrease code length
+
+Arguments:
+
+Returns:
+ Valid pointer to the allocated buffer
+ Null for failure
+
+--*/
+{
+ EFI_STATUS Status;
+ VOID *Ptr;
+ Status = gBS->AllocatePool (EfiBootServicesData, Size, &Ptr);
+ if (EFI_ERROR (Status)) {
+ Ptr = NULL;
+ return Ptr;
+ }
+
+ ZeroMem (Ptr, Size);
+ return Ptr;
+}
+
+EFI_STATUS
+EfiLibLocateProtocol (
+ IN EFI_GUID *ProtocolGuid,
+ OUT VOID **Interface
+ )
+/*++
+
+Routine Description:
+
+ Find the first instance of this Protocol
+ in the system and return it's interface
+
+Arguments:
+
+ ProtocolGuid - Provides the protocol to search for
+ Interface - On return, a pointer to the first interface
+ that matches ProtocolGuid
+
+Returns:
+
+ EFI_SUCCESS - A protocol instance matching ProtocolGuid was found
+
+ EFI_NOT_FOUND - No protocol instances were found that match ProtocolGuid
+
+--*/
+{
+ EFI_STATUS Status;
+
+ Status = gBS->LocateProtocol (
+ ProtocolGuid,
+ NULL,
+ (VOID **) Interface
+ );
+ return Status;
+}
+
+EFI_FILE_HANDLE
+EfiLibOpenRoot (
+ IN EFI_HANDLE DeviceHandle
+ )
+/*++
+
+Routine Description:
+
+ Function opens and returns a file handle to the root directory of a volume.
+
+Arguments:
+
+ DeviceHandle - A handle for a device
+
+Returns:
+
+ A valid file handle or NULL is returned
+
+--*/
+{
+ 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;
+}
+
+BOOLEAN
+EfiGrowBuffer (
+ IN OUT EFI_STATUS *Status,
+ IN OUT VOID **Buffer,
+ IN UINTN BufferSize
+ )
+/*++
+
+Routine Description:
+
+ Helper function called as part of the code needed
+ to allocate the proper sized buffer for various
+ EFI interfaces.
+
+Arguments:
+
+ Status - Current status
+
+ Buffer - Current allocated buffer, or NULL
+
+ BufferSize - Current buffer size needed
+
+Returns:
+
+ TRUE - if the buffer was reallocated and the caller
+ should try the API again.
+
+--*/
+{
+ BOOLEAN TryAgain;
+
+ //
+ // If this is an initial request, buffer will be null with a new buffer size
+ //
+ if (!*Buffer && BufferSize) {
+ *Status = EFI_BUFFER_TOO_SMALL;
+ }
+ //
+ // If the status code is "buffer too small", resize the buffer
+ //
+ TryAgain = FALSE;
+ if (*Status == EFI_BUFFER_TOO_SMALL) {
+
+ SafeFreePool (*Buffer);
+
+ *Buffer = EfiAllocateZeroPool (BufferSize);
+
+ if (*Buffer) {
+ TryAgain = TRUE;
+ } else {
+ *Status = EFI_OUT_OF_RESOURCES;
+ }
+ }
+ //
+ // If there's an error, free the buffer
+ //
+ if (!TryAgain && EFI_ERROR (*Status) && *Buffer) {
+ SafeFreePool (*Buffer);
+ *Buffer = NULL;
+ }
+
+ return TryAgain;
+}
+
+VOID *
+EfiLibGetVariable (
+ IN CHAR16 *Name,
+ IN EFI_GUID *VendorGuid
+ )
+/*++
+
+Routine Description:
+ Function returns the value of the specified variable.
+
+Arguments:
+ Name - A Null-terminated Unicode string that is
+ the name of the vendor's variable.
+
+ VendorGuid - A unique identifier for the vendor.
+
+Returns:
+
+ None
+
+--*/
+{
+ UINTN VarSize;
+
+ return BdsLibGetVariableAndSize (Name, VendorGuid, &VarSize);
+}
+
+EFI_STATUS
+EfiLibDeleteVariable (
+ IN CHAR16 *VarName,
+ IN EFI_GUID *VarGuid
+ )
+/*++
+
+Routine Description:
+ Function deletes the variable specified by VarName and VarGuid.
+
+Arguments:
+ VarName - A Null-terminated Unicode string that is
+ the name of the vendor's variable.
+
+ VendorGuid - A unique identifier for the vendor.
+
+Returns:
+
+ EFI_SUCCESS - The variable was found and removed
+
+ EFI_UNSUPPORTED - The variable store was inaccessible
+
+ EFI_OUT_OF_RESOURCES - The temporary buffer was not available
+
+ EFI_NOT_FOUND - The variable was not found
+
+--*/
+{
+ VOID *VarBuf;
+ EFI_STATUS Status;
+
+ VarBuf = EfiLibGetVariable (VarName, VarGuid);
+ Status = EFI_NOT_FOUND;
+
+ if (VarBuf) {
+ //
+ // Delete variable from Storage
+ //
+ Status = gRT->SetVariable (VarName, VarGuid, VAR_FLAG, 0, NULL);
+ ASSERT (!EFI_ERROR (Status));
+ SafeFreePool (VarBuf);
+ }
+
+ return Status;
+}
+
+EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *
+EfiLibFileSystemVolumeLabelInfo (
+ IN EFI_FILE_HANDLE FHand
+ )
+/*++
+
+Routine Description:
+
+ Function gets the file system information from an open file descriptor,
+ and stores it in a buffer allocated from pool.
+
+Arguments:
+
+ Fhand - A file handle
+
+Returns:
+
+ A pointer to a buffer with file information or NULL is returned
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *Buffer;
+ UINTN BufferSize;
+ //
+ // Initialize for GrowBuffer loop
+ //
+ Buffer = NULL;
+ BufferSize = SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL_INFO + 200;
+
+ //
+ // Call the real function
+ //
+ while (EfiGrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
+ Status = FHand->GetInfo (
+ FHand,
+ &gEfiFileSystemVolumeLabelInfoIdGuid,
+ &BufferSize,
+ Buffer
+ );
+ }
+
+ return Buffer;
+}
+
+CHAR16 *
+EfiStrDuplicate (
+ IN CHAR16 *Src
+ )
+{
+ CHAR16 *Dest;
+ UINTN Size;
+
+ Size = StrSize (Src);
+ Dest = EfiAllocateZeroPool (Size);
+ ASSERT (Dest != NULL);
+ if (Dest) {
+ CopyMem (Dest, Src, Size);
+ }
+
+ return Dest;
+}
+
+EFI_FILE_INFO *
+EfiLibFileInfo (
+ IN EFI_FILE_HANDLE FHand
+ )
+/*++
+
+Routine Description:
+
+ Function gets the file information from an open file descriptor, and stores it
+ in a buffer allocated from pool.
+
+Arguments:
+
+ Fhand - A file handle
+
+Returns:
+
+ A pointer to a buffer with file information or NULL is returned
+
+--*/
+{
+ 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;
+}
+
+UINTN
+EfiDevicePathInstanceCount (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+Routine Description:
+ Function is used to determine the number of device path instances
+ that exist in a device path.
+
+Arguments:
+ DevicePath - A pointer to a device path data structure.
+
+Returns:
+
+ This function counts and returns the number of device path instances
+ in DevicePath.
+
+--*/
+{
+ UINTN Count;
+ UINTN Size;
+
+ Count = 0;
+ while (GetNextDevicePathInstance (&DevicePath, &Size)) {
+ Count += 1;
+ }
+
+ return Count;
+}
+
+VOID *
+EfiReallocatePool (
+ IN VOID *OldPool,
+ IN UINTN OldSize,
+ IN UINTN NewSize
+ )
+/*++
+
+Routine Description:
+ Adjusts the size of a previously allocated buffer.
+
+Arguments:
+ OldPool - A pointer to the buffer whose size is being adjusted.
+ OldSize - The size of the current buffer.
+ NewSize - The size of the new buffer.
+
+Returns:
+
+ EFI_SUCEESS - The requested number of bytes were allocated.
+
+ EFI_OUT_OF_RESOURCES - The pool requested could not be allocated.
+
+ EFI_INVALID_PARAMETER - The buffer was invalid.
+
+--*/
+{
+ VOID *NewPool;
+
+ NewPool = NULL;
+ if (NewSize) {
+ NewPool = EfiAllocateZeroPool (NewSize);
+ }
+
+ if (OldPool) {
+ if (NewPool) {
+ CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize);
+ }
+
+ SafeFreePool (OldPool);
+ }
+
+ return NewPool;
+}
+
+BOOLEAN
+TimeCompare (
+ IN EFI_TIME *FirstTime,
+ IN EFI_TIME *SecondTime
+ )
+/*++
+
+Routine Description:
+ Compare two EFI_TIME data.
+
+Arguments:
+
+ FirstTime - A pointer to the first EFI_TIME data.
+ SecondTime - A pointer to the second EFI_TIME data.
+
+Returns:
+ TRUE The FirstTime is not later than the SecondTime.
+ FALSE The FirstTime is later than the 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);
+}
+
+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_SUBCLASS_GUID;
+ EFI_MISC_ONBOARD_DEVICE_DATA *ob;
+ EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA *Port;
+ EFI_TIME CurTime;
+
+ 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;
+}
diff --git a/MdeModulePkg/Universal/BdsDxe/BootMaint/Bmstring.uni b/MdeModulePkg/Universal/BdsDxe/BootMaint/Bmstring.uni Binary files differnew file mode 100644 index 0000000000..a332fb6ea3 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/BootMaint/Bmstring.uni diff --git a/MdeModulePkg/Universal/BdsDxe/BootMaint/BootMaint.c b/MdeModulePkg/Universal/BdsDxe/BootMaint/BootMaint.c new file mode 100644 index 0000000000..9cf2a9d09a --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/BootMaint/BootMaint.c @@ -0,0 +1,1331 @@ +/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ BootMaint.c
+
+Abstract:
+
+ Boot Maintainence Main File
+
+--*/
+
+#include "BootMaint.h"
+#include "FormGuid.h"
+#include "Bds.h"
+#include "FrontPage.h"
+
+EFI_GUID EfiLegacyDevOrderGuid = EFI_LEGACY_DEV_ORDER_VARIABLE_GUID;
+EFI_GUID mBootMaintGuid = BOOT_MAINT_FORMSET_GUID;
+EFI_GUID mFileExplorerGuid = FILE_EXPLORE_FORMSET_GUID;
+
+CHAR16 mBootMaintStorageName[] = L"BmData";
+CHAR16 mFileExplorerStorageName[] = L"FeData";
+
+VOID
+InitAllMenu (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+VOID
+FreeAllMenu (
+ VOID
+ );
+
+EFI_STATUS
+CreateMenuStringToken (
+ IN BMM_CALLBACK_DATA *CallbackData,
+ IN EFI_HII_HANDLE HiiHandle,
+ IN BM_MENU_OPTION *MenuOption
+ )
+/*++
+
+Routine Description:
+ Create string tokens for a menu from its help strings and display strings
+
+Arguments:
+ HiiHandle - Hii Handle of the package to be updated.
+ MenuOption - The Menu whose string tokens need to be created
+
+Returns:
+ EFI_SUCCESS - string tokens created successfully
+ others - contain some errors
+
+--*/
+{
+ BM_MENU_ENTRY *NewMenuEntry;
+ UINTN Index;
+
+ for (Index = 0; Index < MenuOption->MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (MenuOption, Index);
+
+ IfrLibNewString (
+ HiiHandle,
+ &NewMenuEntry->DisplayStringToken,
+ NewMenuEntry->DisplayString
+ );
+
+ if (NULL == NewMenuEntry->HelpString) {
+ NewMenuEntry->HelpStringToken = NewMenuEntry->DisplayStringToken;
+ } else {
+ IfrLibNewString (
+ HiiHandle,
+ &NewMenuEntry->HelpStringToken,
+ NewMenuEntry->HelpString
+ );
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BootMaintExtractConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Request,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+ )
+/*++
+
+ Routine Description:
+ This function allows a caller to extract the current configuration for one
+ or more named elements from the target driver.
+
+ Arguments:
+ This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ Request - A null-terminated Unicode string in <ConfigRequest> format.
+ 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.
+ 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.
+
+ Returns:
+ EFI_SUCCESS - The Results is filled with the requested values.
+ EFI_OUT_OF_RESOURCES - Not enough memory to store the results.
+ EFI_INVALID_PARAMETER - Request is NULL, illegal syntax, or unknown name.
+ EFI_NOT_FOUND - Routing data doesn't match any storage in this driver.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ BMM_CALLBACK_DATA *Private;
+
+ Private = BMM_CALLBACK_DATA_FROM_THIS (This);
+
+ //
+ // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
+ //
+ BufferSize = sizeof (BMM_FAKE_NV_DATA);
+ Status = gHiiConfigRouting->BlockToConfig (
+ gHiiConfigRouting,
+ Request,
+ (UINT8 *) &Private->BmmFakeNvData,
+ BufferSize,
+ Results,
+ Progress
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+BootMaintCallback (
+ 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
+ )
+/*++
+
+ Routine Description:
+ This function processes the results of changes in configuration.
+
+ Arguments:
+ This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ Action - Specifies the type of action taken by the browser.
+ QuestionId - A unique value which is sent to the original exporting driver
+ so that it can identify the type of data to expect.
+ Type - The type of value for the question.
+ Value - A pointer to the data being sent to the original exporting driver.
+ ActionRequest - On return, points to the action requested by the callback function.
+
+ Returns:
+ EFI_SUCCESS - The callback successfully handled the action.
+ EFI_OUT_OF_RESOURCES - Not enough storage is available to hold the variable and its data.
+ EFI_DEVICE_ERROR - The variable could not be saved.
+ EFI_UNSUPPORTED - The specified Action is not supported by the callback.
+
+--*/
+{
+ BMM_CALLBACK_DATA *Private;
+ BM_MENU_ENTRY *NewMenuEntry;
+ BMM_FAKE_NV_DATA *CurrentFakeNVMap;
+ EFI_STATUS Status;
+ UINTN OldValue;
+ UINTN NewValue;
+ UINTN Number;
+ UINTN Pos;
+ UINTN Bit;
+ UINT16 NewValuePos;
+ UINT16 Index2;
+ UINT16 Index;
+ UINT8 *OldLegacyDev;
+ UINT8 *NewLegacyDev;
+ UINT8 *DisMap;
+ EFI_FORM_ID FormId;
+ UINTN BufferSize;
+
+ if ((Value == NULL) || (ActionRequest == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldValue = 0;
+ NewValue = 0;
+ Number = 0;
+ OldLegacyDev = NULL;
+ NewLegacyDev = NULL;
+ NewValuePos = 0;
+ DisMap = NULL;
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
+
+ Private = BMM_CALLBACK_DATA_FROM_THIS (This);
+ UpdatePageId (Private, QuestionId);
+
+ //
+ // Retrive uncommitted data from Form Browser
+ //
+ CurrentFakeNVMap = &Private->BmmFakeNvData;
+ BufferSize = sizeof (BMM_FAKE_NV_DATA);
+ Status = GetBrowserData (NULL, NULL, &BufferSize, (UINT8 *) CurrentFakeNVMap);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // need to be subtituded.
+ //
+ // Update Select FD/HD/CD/NET/BEV Order Form
+ //
+ if (FORM_SET_FD_ORDER_ID == Private->BmmPreviousPageId ||
+ FORM_SET_HD_ORDER_ID == Private->BmmPreviousPageId ||
+ FORM_SET_CD_ORDER_ID == Private->BmmPreviousPageId ||
+ FORM_SET_NET_ORDER_ID == Private->BmmPreviousPageId ||
+ FORM_SET_BEV_ORDER_ID == Private->BmmPreviousPageId ||
+ ((FORM_BOOT_SETUP_ID == Private->BmmPreviousPageId) &&
+ (QuestionId >= LEGACY_FD_QUESTION_ID) &&
+ (QuestionId < (LEGACY_BEV_QUESTION_ID + 100)) )
+ ) {
+
+ DisMap = Private->BmmOldFakeNVData.DisableMap;
+
+ FormId = Private->BmmPreviousPageId;
+ if (FormId == FORM_BOOT_SETUP_ID) {
+ FormId = Private->BmmCurrentPageId;
+ }
+
+ switch (FormId) {
+ case FORM_SET_FD_ORDER_ID:
+ Number = (UINT16) LegacyFDMenu.MenuNumber;
+ OldLegacyDev = Private->BmmOldFakeNVData.LegacyFD;
+ NewLegacyDev = CurrentFakeNVMap->LegacyFD;
+ break;
+
+ case FORM_SET_HD_ORDER_ID:
+ Number = (UINT16) LegacyHDMenu.MenuNumber;
+ OldLegacyDev = Private->BmmOldFakeNVData.LegacyHD;
+ NewLegacyDev = CurrentFakeNVMap->LegacyHD;
+ break;
+
+ case FORM_SET_CD_ORDER_ID:
+ Number = (UINT16) LegacyCDMenu.MenuNumber;
+ OldLegacyDev = Private->BmmOldFakeNVData.LegacyCD;
+ NewLegacyDev = CurrentFakeNVMap->LegacyCD;
+ break;
+
+ case FORM_SET_NET_ORDER_ID:
+ Number = (UINT16) LegacyNETMenu.MenuNumber;
+ OldLegacyDev = Private->BmmOldFakeNVData.LegacyNET;
+ NewLegacyDev = CurrentFakeNVMap->LegacyNET;
+ break;
+
+ case FORM_SET_BEV_ORDER_ID:
+ Number = (UINT16) LegacyBEVMenu.MenuNumber;
+ OldLegacyDev = Private->BmmOldFakeNVData.LegacyBEV;
+ NewLegacyDev = CurrentFakeNVMap->LegacyBEV;
+ break;
+
+ default:
+ break;
+ }
+ //
+ // First, find the different position
+ // if there is change, it should be only one
+ //
+ for (Index = 0; Index < Number; Index++) {
+ if (OldLegacyDev[Index] != NewLegacyDev[Index]) {
+ OldValue = OldLegacyDev[Index];
+ NewValue = NewLegacyDev[Index];
+ break;
+ }
+ }
+
+ if (Index != Number) {
+ //
+ // there is change, now process
+ //
+ if (0xFF == NewValue) {
+ //
+ // This item will be disable
+ // Just move the items behind this forward to overlap it
+ //
+ Pos = OldValue / 8;
+ Bit = 7 - (OldValue % 8);
+ DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));
+ for (Index2 = Index; Index2 < Number - 1; Index2++) {
+ NewLegacyDev[Index2] = NewLegacyDev[Index2 + 1];
+ }
+
+ NewLegacyDev[Index2] = 0xFF;
+ } else {
+ for (Index2 = 0; Index2 < Number; Index2++) {
+ if (Index2 == Index) {
+ continue;
+ }
+
+ if (OldLegacyDev[Index2] == NewValue) {
+ //
+ // If NewValue is in OldLegacyDev array
+ // remember its old position
+ //
+ NewValuePos = Index2;
+ break;
+ }
+ }
+
+ if (Index2 != Number) {
+ //
+ // We will change current item to an existing item
+ // (It's hard to describe here, please read code, it's like a cycle-moving)
+ //
+ for (Index2 = NewValuePos; Index2 != Index;) {
+ if (NewValuePos < Index) {
+ NewLegacyDev[Index2] = OldLegacyDev[Index2 + 1];
+ Index2++;
+ } else {
+ NewLegacyDev[Index2] = OldLegacyDev[Index2 - 1];
+ Index2--;
+ }
+ }
+ } else {
+ //
+ // If NewValue is not in OldlegacyDev array, we are changing to a disabled item
+ // so we should modify DisMap to reflect the change
+ //
+ Pos = NewValue / 8;
+ Bit = 7 - (NewValue % 8);
+ DisMap[Pos] = (UINT8) (DisMap[Pos] & (~ (UINT8) (1 << Bit)));
+ if (0xFF != OldValue) {
+ //
+ // Because NewValue is a item that was disabled before
+ // so after changing the OldValue should be disabled
+ // actually we are doing a swap of enable-disable states of two items
+ //
+ Pos = OldValue / 8;
+ Bit = 7 - (OldValue % 8);
+ DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));
+ }
+ }
+ }
+ //
+ // To prevent DISABLE appears in the middle of the list
+ // we should perform a re-ordering
+ //
+ Index = 0;
+ while (Index < Number) {
+ if (0xFF != NewLegacyDev[Index]) {
+ Index++;
+ continue;
+ }
+
+ Index2 = Index;
+ Index2++;
+ while (Index2 < Number) {
+ if (0xFF != NewLegacyDev[Index2]) {
+ break;
+ }
+
+ Index2++;
+ }
+
+ if (Index2 < Number) {
+ NewLegacyDev[Index] = NewLegacyDev[Index2];
+ NewLegacyDev[Index2] = 0xFF;
+ }
+
+ Index++;
+ }
+
+ CopyMem (
+ OldLegacyDev,
+ NewLegacyDev,
+ Number
+ );
+ }
+ }
+
+ if (QuestionId < FILE_OPTION_OFFSET) {
+ if (QuestionId < CONFIG_OPTION_OFFSET) {
+ switch (QuestionId) {
+ case KEY_VALUE_BOOT_FROM_FILE:
+ Private->FeCurrentState = BOOT_FROM_FILE_STATE;
+
+ //
+ // Exit Bmm main formset to send File Explorer formset.
+ //
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
+ break;
+
+ case FORM_BOOT_ADD_ID:
+ Private->FeCurrentState = ADD_BOOT_OPTION_STATE;
+
+ //
+ // Exit Bmm main formset to send File Explorer formset.
+ //
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
+ break;
+
+ case FORM_DRV_ADD_FILE_ID:
+ Private->FeCurrentState = ADD_DRIVER_OPTION_STATE;
+
+ //
+ // Exit Bmm main formset to send File Explorer formset.
+ //
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
+ break;
+
+ case FORM_DRV_ADD_HANDLE_ID:
+ CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);
+ UpdateDrvAddHandlePage (Private);
+ break;
+
+ case FORM_BOOT_DEL_ID:
+ CleanUpPage (FORM_BOOT_DEL_ID, Private);
+ UpdateBootDelPage (Private);
+ break;
+
+ case FORM_BOOT_CHG_ID:
+ case FORM_DRV_CHG_ID:
+ UpdatePageBody (QuestionId, Private);
+ break;
+
+ case FORM_DRV_DEL_ID:
+ CleanUpPage (FORM_DRV_DEL_ID, Private);
+ UpdateDrvDelPage (Private);
+ break;
+
+ case FORM_BOOT_NEXT_ID:
+ CleanUpPage (FORM_BOOT_NEXT_ID, Private);
+ UpdateBootNextPage (Private);
+ break;
+
+ case FORM_TIME_OUT_ID:
+ CleanUpPage (FORM_TIME_OUT_ID, Private);
+ UpdateTimeOutPage (Private);
+ break;
+
+ case FORM_RESET:
+ gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
+ return EFI_UNSUPPORTED;
+
+ case FORM_CON_IN_ID:
+ case FORM_CON_OUT_ID:
+ case FORM_CON_ERR_ID:
+ UpdatePageBody (QuestionId, Private);
+ break;
+
+ case FORM_CON_MODE_ID:
+ CleanUpPage (FORM_CON_MODE_ID, Private);
+ UpdateConModePage (Private);
+ break;
+
+ case FORM_CON_COM_ID:
+ CleanUpPage (FORM_CON_COM_ID, Private);
+ UpdateConCOMPage (Private);
+ break;
+
+ case FORM_SET_FD_ORDER_ID:
+ case FORM_SET_HD_ORDER_ID:
+ case FORM_SET_CD_ORDER_ID:
+ case FORM_SET_NET_ORDER_ID:
+ case FORM_SET_BEV_ORDER_ID:
+ CleanUpPage (QuestionId, Private);
+ UpdateSetLegacyDeviceOrderPage (QuestionId, Private);
+ break;
+
+ case KEY_VALUE_SAVE_AND_EXIT:
+ case KEY_VALUE_NO_SAVE_AND_EXIT:
+
+ if (QuestionId == KEY_VALUE_SAVE_AND_EXIT) {
+ Status = ApplyChangeHandler (Private, CurrentFakeNVMap, Private->BmmPreviousPageId);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT) {
+ DiscardChangeHandler (Private, CurrentFakeNVMap);
+ }
+
+ //
+ // Tell browser not to ask for confirmation of changes,
+ // since we have already applied or discarded.
+ //
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
+ break;
+
+ default:
+ break;
+ }
+ } else if ((QuestionId >= TERMINAL_OPTION_OFFSET) && (QuestionId < CONSOLE_OPTION_OFFSET)) {
+ Index2 = (UINT16) (QuestionId - TERMINAL_OPTION_OFFSET);
+ Private->CurrentTerminal = Index2;
+
+ CleanUpPage (FORM_CON_COM_SETUP_ID, Private);
+ UpdateTerminalPage (Private);
+
+ } else if (QuestionId >= HANDLE_OPTION_OFFSET) {
+ Index2 = (UINT16) (QuestionId - HANDLE_OPTION_OFFSET);
+
+ NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index2);
+ ASSERT (NewMenuEntry != NULL);
+ Private->HandleContext = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;
+
+ CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);
+
+ Private->MenuEntry = NewMenuEntry;
+ Private->LoadContext->FilePathList = Private->HandleContext->DevicePath;
+
+ UpdateDriverAddHandleDescPage (Private);
+ }
+ }
+
+ //
+ // Pass changed uncommitted data back to Form Browser
+ //
+ BufferSize = sizeof (BMM_FAKE_NV_DATA);
+ Status = SetBrowserData (NULL, NULL, BufferSize, (UINT8 *) CurrentFakeNVMap, NULL);
+
+ return Status;
+}
+
+EFI_STATUS
+ApplyChangeHandler (
+ IN BMM_CALLBACK_DATA *Private,
+ IN BMM_FAKE_NV_DATA *CurrentFakeNVMap,
+ IN EFI_FORM_ID FormId
+ )
+/*++
+
+Routine Description:
+ Function handling request to apply changes for BMM pages.
+
+Arguments:
+ Private - Pointer to callback data buffer.
+ CurrentFakeNVMap - Pointer to buffer holding data of various values used by BMM
+ FormId - ID of the form which has sent the request to apply change.
+
+Returns:
+ EFI_SUCCESS - Change successfully applied.
+ Other - Error occurs while trying to apply changes.
+
+--*/
+{
+ BM_CONSOLE_CONTEXT *NewConsoleContext;
+ BM_TERMINAL_CONTEXT *NewTerminalContext;
+ BM_LOAD_CONTEXT *NewLoadContext;
+ BM_MENU_ENTRY *NewMenuEntry;
+ EFI_STATUS Status;
+ UINT16 Index;
+
+ Status = EFI_SUCCESS;
+
+ switch (FormId) {
+ case FORM_SET_FD_ORDER_ID:
+ case FORM_SET_HD_ORDER_ID:
+ case FORM_SET_CD_ORDER_ID:
+ case FORM_SET_NET_ORDER_ID:
+ case FORM_SET_BEV_ORDER_ID:
+ Var_UpdateBBSOption (Private);
+ break;
+
+ case FORM_BOOT_DEL_ID:
+ for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
+ NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
+ NewLoadContext->Deleted = CurrentFakeNVMap->BootOptionDel[Index];
+ }
+
+ Var_DelBootOption ();
+ break;
+
+ case FORM_DRV_DEL_ID:
+ for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
+ NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
+ NewLoadContext->Deleted = CurrentFakeNVMap->DriverOptionDel[Index];
+ }
+
+ Var_DelDriverOption ();
+ break;
+
+ case FORM_BOOT_CHG_ID:
+ Status = Var_UpdateBootOrder (Private);
+ break;
+
+ case FORM_DRV_CHG_ID:
+ Status = Var_UpdateDriverOrder (Private);
+ break;
+
+ case FORM_TIME_OUT_ID:
+ Status = gRT->SetVariable (
+ L"Timeout",
+ &gEfiGlobalVariableGuid,
+ VAR_FLAG,
+ sizeof (UINT16),
+ &(CurrentFakeNVMap->BootTimeOut)
+ );
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+ Private->BmmOldFakeNVData.BootTimeOut = CurrentFakeNVMap->BootTimeOut;
+ break;
+
+ case FORM_BOOT_NEXT_ID:
+ Status = Var_UpdateBootNext (Private);
+ break;
+
+ case FORM_CON_MODE_ID:
+ Status = Var_UpdateConMode (Private);
+ break;
+
+ case FORM_CON_COM_SETUP_ID:
+ NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Private->CurrentTerminal);
+
+ ASSERT (NewMenuEntry != NULL);
+
+ NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
+
+ NewTerminalContext->BaudRateIndex = CurrentFakeNVMap->COMBaudRate;
+ NewTerminalContext->BaudRate = BaudRateList[CurrentFakeNVMap->COMBaudRate].Value;
+ NewTerminalContext->DataBitsIndex = CurrentFakeNVMap->COMDataRate;
+ NewTerminalContext->DataBits = (UINT8) DataBitsList[CurrentFakeNVMap->COMDataRate].Value;
+ NewTerminalContext->StopBitsIndex = CurrentFakeNVMap->COMStopBits;
+ NewTerminalContext->StopBits = (UINT8) StopBitsList[CurrentFakeNVMap->COMStopBits].Value;
+ NewTerminalContext->ParityIndex = CurrentFakeNVMap->COMParity;
+ NewTerminalContext->Parity = (UINT8) ParityList[CurrentFakeNVMap->COMParity].Value;
+ NewTerminalContext->TerminalType = CurrentFakeNVMap->COMTerminalType;
+
+ ChangeTerminalDevicePath (
+ NewTerminalContext->DevicePath,
+ FALSE
+ );
+
+ Var_UpdateConsoleInpOption ();
+ Var_UpdateConsoleOutOption ();
+ Var_UpdateErrorOutOption ();
+ break;
+
+ case FORM_CON_IN_ID:
+ for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);
+ NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
+ NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];
+ }
+
+ for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
+ NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
+ NewTerminalContext->IsConIn = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleInpMenu.MenuNumber];
+ }
+
+ Var_UpdateConsoleInpOption ();
+ break;
+
+ case FORM_CON_OUT_ID:
+ for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);
+ NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
+ NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];
+ }
+
+ for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
+ NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
+ NewTerminalContext->IsConOut = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleOutMenu.MenuNumber];
+ }
+
+ Var_UpdateConsoleOutOption ();
+ break;
+
+ case FORM_CON_ERR_ID:
+ for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);
+ NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
+ NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];
+ }
+
+ for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
+ NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
+ NewTerminalContext->IsStdErr = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleErrMenu.MenuNumber];
+ }
+
+ Var_UpdateErrorOutOption ();
+ break;
+
+ case FORM_DRV_ADD_HANDLE_DESC_ID:
+ Status = Var_UpdateDriverOption (
+ Private,
+ Private->BmmHiiHandle,
+ CurrentFakeNVMap->DriverAddHandleDesc,
+ CurrentFakeNVMap->DriverAddHandleOptionalData,
+ CurrentFakeNVMap->DriverAddForceReconnect
+ );
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+ BOpt_GetDriverOptions (Private);
+ CreateMenuStringToken (Private, Private->BmmHiiHandle, &DriverOptionMenu);
+ break;
+
+ default:
+ break;
+ }
+
+Error:
+ return Status;
+}
+
+VOID
+DiscardChangeHandler (
+ IN BMM_CALLBACK_DATA *Private,
+ IN BMM_FAKE_NV_DATA *CurrentFakeNVMap
+ )
+{
+ UINT16 Index;
+
+ switch (Private->BmmPreviousPageId) {
+ case FORM_BOOT_CHG_ID:
+ case FORM_DRV_CHG_ID:
+ CopyMem (CurrentFakeNVMap->OptionOrder, Private->BmmOldFakeNVData.OptionOrder, 100);
+ break;
+
+ case FORM_BOOT_DEL_ID:
+ for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
+ CurrentFakeNVMap->BootOptionDel[Index] = 0x00;
+ }
+ break;
+
+ case FORM_DRV_DEL_ID:
+ for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
+ CurrentFakeNVMap->DriverOptionDel[Index] = 0x00;
+ }
+ break;
+
+ case FORM_BOOT_NEXT_ID:
+ CurrentFakeNVMap->BootNext = Private->BmmOldFakeNVData.BootNext;
+ break;
+
+ case FORM_TIME_OUT_ID:
+ CurrentFakeNVMap->BootTimeOut = Private->BmmOldFakeNVData.BootTimeOut;
+ break;
+
+ case FORM_DRV_ADD_HANDLE_DESC_ID:
+ case FORM_DRV_ADD_FILE_ID:
+ case FORM_DRV_ADD_HANDLE_ID:
+ CurrentFakeNVMap->DriverAddHandleDesc[0] = 0x0000;
+ CurrentFakeNVMap->DriverAddHandleOptionalData[0] = 0x0000;
+ break;
+
+ default:
+ break;
+ }
+}
+
+EFI_STATUS
+InitializeBM (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Initialize the Boot Maintenance Utitliy
+
+Arguments:
+ ImageHandle - caller provided handle
+ SystemTable - caller provided system tables
+
+Returns:
+ EFI_SUCCESS - utility ended successfully
+ others - contain some errors
+
+--*/
+{
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ EFI_HII_PACKAGE_LIST_HEADER *PackageList;
+ BMM_CALLBACK_DATA *BmmCallbackInfo;
+ EFI_STATUS Status;
+ UINT8 *Ptr;
+
+ Status = EFI_SUCCESS;
+
+ //
+ // Create CallbackData structures for Driver Callback
+ //
+ BmmCallbackInfo = EfiAllocateZeroPool (sizeof (BMM_CALLBACK_DATA));
+ if (BmmCallbackInfo == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Create LoadOption in BmmCallbackInfo for Driver Callback
+ //
+ Ptr = EfiAllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));
+ if (!Ptr) {
+ SafeFreePool (BmmCallbackInfo);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Initialize Bmm callback data.
+ //
+ BmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;
+ Ptr += sizeof (BM_LOAD_CONTEXT);
+
+ BmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;
+ Ptr += sizeof (BM_FILE_CONTEXT);
+
+ BmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;
+ Ptr += sizeof (BM_HANDLE_CONTEXT);
+
+ BmmCallbackInfo->MenuEntry = (BM_MENU_ENTRY *) Ptr;
+
+ BmmCallbackInfo->Signature = BMM_CALLBACK_DATA_SIGNATURE;
+ BmmCallbackInfo->BmmConfigAccess.ExtractConfig = BootMaintExtractConfig;
+ BmmCallbackInfo->BmmConfigAccess.RouteConfig = FakeRouteConfig;
+ BmmCallbackInfo->BmmConfigAccess.Callback = BootMaintCallback;
+ BmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;
+ BmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;
+ BmmCallbackInfo->FeConfigAccess.ExtractConfig = FakeExtractConfig;
+ BmmCallbackInfo->FeConfigAccess.RouteConfig = FakeRouteConfig;
+ BmmCallbackInfo->FeConfigAccess.Callback = FileExplorerCallback;
+ BmmCallbackInfo->FeCurrentState = INACTIVE_STATE;
+ BmmCallbackInfo->FeDisplayContext = UNKNOWN_CONTEXT;
+
+ //
+ // Create driver handle used by HII database
+ //
+ Status = HiiLibCreateHiiDriverHandle (&BmmCallbackInfo->BmmDriverHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Install Config Access protocol to driver handle
+ //
+ Status = gBS->InstallProtocolInterface (
+ &BmmCallbackInfo->BmmDriverHandle,
+ &gEfiHiiConfigAccessProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &BmmCallbackInfo->BmmConfigAccess
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Create driver handle used by HII database
+ //
+ Status = HiiLibCreateHiiDriverHandle (&BmmCallbackInfo->FeDriverHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Install Config Access protocol to driver handle
+ //
+ Status = gBS->InstallProtocolInterface (
+ &BmmCallbackInfo->FeDriverHandle,
+ &gEfiHiiConfigAccessProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &BmmCallbackInfo->FeConfigAccess
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Post our Boot Maint VFR binnary to the HII database.
+ //
+ PackageList = PreparePackageList (2, &mBootMaintGuid, BmBin, BdsStrings);
+ ASSERT (PackageList != NULL);
+
+ Status = gHiiDatabase->NewPackageList (
+ gHiiDatabase,
+ PackageList,
+ BmmCallbackInfo->BmmDriverHandle,
+ &BmmCallbackInfo->BmmHiiHandle
+ );
+ FreePool (PackageList);
+
+ //
+ // Post our File Explorer VFR binary to the HII database.
+ //
+ PackageList = PreparePackageList (2, &mFileExplorerGuid, FEBin, BdsStrings);
+ ASSERT (PackageList != NULL);
+
+ Status = gHiiDatabase->NewPackageList (
+ gHiiDatabase,
+ PackageList,
+ BmmCallbackInfo->FeDriverHandle,
+ &BmmCallbackInfo->FeHiiHandle
+ );
+ FreePool (PackageList);
+
+ //
+ // Allocate space for creation of Buffer
+ //
+ gUpdateData.BufferSize = UPDATE_DATA_SIZE;
+ gUpdateData.Data = EfiAllocateZeroPool (UPDATE_DATA_SIZE);
+ if (gUpdateData.Data == NULL) {
+ SafeFreePool (BmmCallbackInfo->LoadContext);
+ SafeFreePool (BmmCallbackInfo);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ InitializeStringDepository ();
+
+ InitAllMenu (BmmCallbackInfo);
+
+ CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleInpMenu);
+ CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleOutMenu);
+ CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleErrMenu);
+ CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &BootOptionMenu);
+ CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverOptionMenu);
+ CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &TerminalMenu);
+ CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverMenu);
+
+ UpdateBootDelPage (BmmCallbackInfo);
+ UpdateDrvDelPage (BmmCallbackInfo);
+
+ if (TerminalMenu.MenuNumber > 0) {
+ BmmCallbackInfo->CurrentTerminal = 0;
+ UpdateTerminalPage (BmmCallbackInfo);
+ }
+
+ Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);
+ if (!EFI_ERROR (Status)) {
+ RefreshUpdateData ();
+
+ //
+ // If LegacyBios Protocol is installed, add 3 tags about legacy boot option
+ // in BootOption form: legacy FD/HD/CD/NET/BEV
+ //
+ CreateGotoOpCode (
+ FORM_SET_FD_ORDER_ID,
+ STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),
+ STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),
+ EFI_IFR_FLAG_CALLBACK,
+ FORM_SET_FD_ORDER_ID,
+ &gUpdateData
+ );
+
+ CreateGotoOpCode (
+ FORM_SET_HD_ORDER_ID,
+ STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),
+ STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),
+ EFI_IFR_FLAG_CALLBACK,
+ FORM_SET_HD_ORDER_ID,
+ &gUpdateData
+ );
+
+ CreateGotoOpCode (
+ FORM_SET_CD_ORDER_ID,
+ STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),
+ STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),
+ EFI_IFR_FLAG_CALLBACK,
+ FORM_SET_CD_ORDER_ID,
+ &gUpdateData
+ );
+
+ CreateGotoOpCode (
+ FORM_SET_NET_ORDER_ID,
+ STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),
+ STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),
+ EFI_IFR_FLAG_CALLBACK,
+ FORM_SET_NET_ORDER_ID,
+ &gUpdateData
+ );
+
+ CreateGotoOpCode (
+ FORM_SET_BEV_ORDER_ID,
+ STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),
+ STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),
+ EFI_IFR_FLAG_CALLBACK,
+ FORM_SET_BEV_ORDER_ID,
+ &gUpdateData
+ );
+
+ IfrLibUpdateForm (
+ BmmCallbackInfo->BmmHiiHandle,
+ &mBootMaintGuid,
+ FORM_MAIN_ID,
+ FORM_BOOT_LEGACY_DEVICE_ID,
+ FALSE,
+ &gUpdateData
+ );
+ }
+
+ //
+ // Dispatch BMM main formset and File Explorer formset.
+ //
+ FormSetDispatcher (BmmCallbackInfo);
+
+ //
+ // Remove our IFR data from HII database
+ //
+ gHiiDatabase->RemovePackageList (gHiiDatabase, BmmCallbackInfo->BmmHiiHandle);
+ gHiiDatabase->RemovePackageList (gHiiDatabase, BmmCallbackInfo->FeHiiHandle);
+
+ CleanUpStringDepository ();
+
+ FreeAllMenu ();
+
+ SafeFreePool (BmmCallbackInfo->LoadContext);
+ SafeFreePool (BmmCallbackInfo);
+ SafeFreePool (gUpdateData.Data);
+ gUpdateData.Data = NULL;
+
+ return Status;
+}
+
+VOID
+InitAllMenu (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+{
+ InitializeListHead (&BootOptionMenu.Head);
+ InitializeListHead (&DriverOptionMenu.Head);
+ BOpt_GetBootOptions (CallbackData);
+ BOpt_GetDriverOptions (CallbackData);
+ BOpt_GetLegacyOptions ();
+ InitializeListHead (&FsOptionMenu.Head);
+ BOpt_FindDrivers ();
+ InitializeListHead (&DirectoryMenu.Head);
+ InitializeListHead (&ConsoleInpMenu.Head);
+ InitializeListHead (&ConsoleOutMenu.Head);
+ InitializeListHead (&ConsoleErrMenu.Head);
+ InitializeListHead (&TerminalMenu.Head);
+ LocateSerialIo ();
+ GetAllConsoles ();
+}
+
+VOID
+FreeAllMenu (
+ VOID
+ )
+{
+ BOpt_FreeMenu (&DirectoryMenu);
+ BOpt_FreeMenu (&FsOptionMenu);
+ BOpt_FreeMenu (&BootOptionMenu);
+ BOpt_FreeMenu (&DriverOptionMenu);
+ BOpt_FreeMenu (&DriverMenu);
+ BOpt_FreeLegacyOptions ();
+ FreeAllConsoles ();
+}
+
+VOID
+InitializeStringDepository (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Intialize all the string depositories.
+
+Arguments:
+ None.
+
+Returns:
+ None.
+
+--*/
+{
+ STRING_DEPOSITORY *StringDepository;
+ StringDepository = EfiAllocateZeroPool (sizeof (STRING_DEPOSITORY) * STRING_DEPOSITORY_NUMBER);
+ FileOptionStrDepository = StringDepository++;
+ ConsoleOptionStrDepository = StringDepository++;
+ BootOptionStrDepository = StringDepository++;
+ BootOptionHelpStrDepository = StringDepository++;
+ DriverOptionStrDepository = StringDepository++;
+ DriverOptionHelpStrDepository = StringDepository++;
+ TerminalStrDepository = StringDepository;
+}
+
+EFI_STRING_ID
+GetStringTokenFromDepository (
+ IN BMM_CALLBACK_DATA *CallbackData,
+ IN STRING_DEPOSITORY *StringDepository
+ )
+/*++
+
+Routine Description:
+ Fetch a usable string node from the string depository and return the string token.
+
+Arguments:
+ StringDepository - Pointer of the string depository.
+
+Returns:
+ EFI_STRING_ID - String token.
+
+--*/
+{
+ STRING_LIST_NODE *CurrentListNode;
+ STRING_LIST_NODE *NextListNode;
+
+ CurrentListNode = StringDepository->CurrentNode;
+
+ if ((NULL != CurrentListNode) && (NULL != CurrentListNode->Next)) {
+ //
+ // Fetch one reclaimed node from the list.
+ //
+ NextListNode = StringDepository->CurrentNode->Next;
+ } else {
+ //
+ // If there is no usable node in the list, update the list.
+ //
+ NextListNode = EfiAllocateZeroPool (sizeof (STRING_LIST_NODE));
+
+ IfrLibNewString (CallbackData->BmmHiiHandle, &(NextListNode->StringToken), L" ");
+ ASSERT (NextListNode->StringToken != 0);
+
+ StringDepository->TotalNodeNumber++;
+
+ if (NULL == CurrentListNode) {
+ StringDepository->ListHead = NextListNode;
+ } else {
+ CurrentListNode->Next = NextListNode;
+ }
+ }
+
+ StringDepository->CurrentNode = NextListNode;
+
+ return StringDepository->CurrentNode->StringToken;
+}
+
+VOID
+ReclaimStringDepository (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Reclaim string depositories by moving the current node pointer to list head..
+
+Arguments:
+ None.
+
+Returns:
+ None.
+
+--*/
+{
+ UINTN DepositoryIndex;
+ STRING_DEPOSITORY *StringDepository;
+
+ StringDepository = FileOptionStrDepository;
+ for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {
+ StringDepository->CurrentNode = StringDepository->ListHead;
+ StringDepository++;
+ }
+}
+
+VOID
+CleanUpStringDepository (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Release resource for all the string depositories.
+
+Arguments:
+ None.
+
+Returns:
+ None.
+
+--*/
+{
+ UINTN NodeIndex;
+ UINTN DepositoryIndex;
+ STRING_LIST_NODE *CurrentListNode;
+ STRING_LIST_NODE *NextListNode;
+ STRING_DEPOSITORY *StringDepository;
+
+ //
+ // Release string list nodes.
+ //
+ StringDepository = FileOptionStrDepository;
+ for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {
+ CurrentListNode = StringDepository->ListHead;
+ for (NodeIndex = 0; NodeIndex < StringDepository->TotalNodeNumber; NodeIndex++) {
+ NextListNode = CurrentListNode->Next;
+ SafeFreePool (CurrentListNode);
+ CurrentListNode = NextListNode;
+ }
+
+ StringDepository++;
+ }
+ //
+ // Release string depository.
+ //
+ SafeFreePool (FileOptionStrDepository);
+}
+
+EFI_STATUS
+BdsStartBootMaint (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Start boot maintenance manager
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ EFI_STATUS Status;
+ LIST_ENTRY BdsBootOptionList;
+
+ InitializeListHead (&BdsBootOptionList);
+
+ //
+ // Connect all prior to entering the platform setup menu.
+ //
+ if (!gConnectAllHappened) {
+ BdsLibConnectAllDriversToAllControllers ();
+ gConnectAllHappened = TRUE;
+ }
+ //
+ // Have chance to enumerate boot device
+ //
+ BdsLibEnumerateAllBootOption (&BdsBootOptionList);
+
+ //
+ // Drop the TPL level from TPL_APPLICATION to TPL_APPLICATION
+ //
+ gBS->RestoreTPL (TPL_APPLICATION);
+
+ //
+ // Init the BMM
+ //
+ Status = InitializeBM ();
+
+ //
+ // Raise the TPL level back to TPL_APPLICATION
+ //
+ gBS->RaiseTPL (TPL_APPLICATION);
+
+ return Status;
+}
+
+EFI_STATUS
+FormSetDispatcher (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+/*++
+
+Routine Description:
+ Dispatch BMM formset and FileExplorer formset.
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_BROWSER_ACTION_REQUEST ActionRequest;
+
+ while (TRUE) {
+ UpdatePageId (CallbackData, FORM_MAIN_ID);
+
+ ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
+ Status = gFormBrowser2->SendForm (
+ gFormBrowser2,
+ &CallbackData->BmmHiiHandle,
+ 1,
+ NULL,
+ 0,
+ NULL,
+ &ActionRequest
+ );
+ if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
+ EnableResetRequired ();
+ }
+
+ ReclaimStringDepository ();
+
+ //
+ // When this Formset returns, check if we are going to explore files.
+ //
+ if (INACTIVE_STATE != CallbackData->FeCurrentState) {
+ UpdateFileExplorer (CallbackData, 0);
+
+ ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
+ Status = gFormBrowser2->SendForm (
+ gFormBrowser2,
+ &CallbackData->FeHiiHandle,
+ 1,
+ NULL,
+ 0,
+ NULL,
+ &ActionRequest
+ );
+ if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
+ EnableResetRequired ();
+ }
+
+ CallbackData->FeCurrentState = INACTIVE_STATE;
+ CallbackData->FeDisplayContext = UNKNOWN_CONTEXT;
+ ReclaimStringDepository ();
+ } else {
+ break;
+ }
+ }
+
+ return Status;
+}
+
diff --git a/MdeModulePkg/Universal/BdsDxe/BootMaint/BootMaint.h b/MdeModulePkg/Universal/BdsDxe/BootMaint/BootMaint.h new file mode 100644 index 0000000000..0de7b05dae --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/BootMaint/BootMaint.h @@ -0,0 +1,1087 @@ +/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ BootMaint.h
+
+Abstract:
+
+Revision History
+
+--*/
+
+#ifndef _BOOT_MAINT_H
+#define _BOOT_MAINT_H
+
+#include "Bds.h"
+#include "BBSsupport.h"
+#include "FormGuid.h"
+#include "FrontPage.h"
+
+//
+// Constants which are variable names used to access variables
+//
+#define VarLegacyDevOrder L"LegacyDevOrder"
+
+#define VarConOutMode L"ConOutMode"
+
+//
+// Guid of a NV Variable which store the information about the
+// FD/HD/CD/NET/BEV order
+//
+#define EFI_LEGACY_DEV_ORDER_VARIABLE_GUID \
+ { \
+ 0xa56074db, 0x65fe, 0x45f7, {0xbd, 0x21, 0x2d, 0x2b, 0xdd, 0x8e, 0x96, 0x52} \
+ }
+
+//
+// String Contant
+//
+#define StrFloppy L"Floppy Drive #%02x"
+#define StrHardDisk L"HardDisk Drive #%02x"
+#define StrCDROM L"ATAPI CDROM Drive #%02x"
+#define StrNET L"NET Drive #%02x"
+#define StrBEV L"BEV Drive #%02x"
+#define StrFloppyHelp L"Select Floppy Drive #%02x"
+#define StrHardDiskHelp L"Select HardDisk Drive #%02x"
+#define StrCDROMHelp L"Select ATAPI CDROM Drive #%02x"
+#define StrNETHelp L"NET Drive #%02x"
+#define StrBEVHelp L"BEV Drive #%02x"
+
+//
+// Variable created with this flag will be "Efi:...."
+//
+#define VAR_FLAG EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE
+
+//
+// Define Maxmim characters that will be accepted
+//
+#define MAX_CHAR 480
+#define MAX_CHAR_SIZE (MAX_CHAR * 2)
+
+//
+// Check to see if current build support option active feature of
+// some driver option
+//
+#ifndef LOAD_OPTION_ACTIVE
+#define LOAD_OPTION_ACTIVE 0x00000001
+#endif
+
+//
+// Check to see if current build support force reconnect feature of
+// some driver option
+//
+#ifndef LOAD_OPTION_FORCE_RECONNECT
+#define LOAD_OPTION_FORCE_RECONNECT 0x00000002
+#endif
+
+extern EFI_GUID mBootMaintGuid;
+extern EFI_GUID mFileExplorerGuid;
+
+//
+// These are the VFR compiler generated data representing our VFR data.
+//
+extern UINT8 BmBin[];
+extern UINT8 FEBin[];
+
+//
+// Below are the number of options in Baudrate, Databits,
+// Parity and Stopbits selection for serial ports.
+//
+#define BM_COM_ATTR_BUADRATE 19
+#define BM_COM_ATTR_DATABITS 4
+#define BM_COM_ATTR_PARITY 5
+#define BM_COM_ATTR_STOPBITS 3
+
+//
+// Callback function helper
+//
+#define BMM_CALLBACK_DATA_SIGNATURE EFI_SIGNATURE_32 ('C', 'b', 'c', 'k')
+#define BMM_CALLBACK_DATA_FROM_THIS(a) CR (a, BMM_CALLBACK_DATA, BmmConfigAccess, BMM_CALLBACK_DATA_SIGNATURE)
+
+#define FE_CALLBACK_DATA_FROM_THIS(a) CR (a, BMM_CALLBACK_DATA, FeConfigAccess, BMM_CALLBACK_DATA_SIGNATURE)
+
+//
+// Enumeration type definition
+//
+typedef UINT8 BBS_TYPE;
+
+typedef enum {
+ PC_ANSI = 0,
+ VT_100,
+ VT_100_PLUS,
+ VT_UTF8
+} TYPE_OF_TERMINAL;
+
+typedef enum {
+ COM1 = 0,
+ COM2,
+ UNKNOW_COM
+} TYPE_OF_COM;
+
+typedef enum {
+ CONIN = 0,
+ CONOUT,
+ CONERR,
+ UNKNOWN_CON
+} TYPE_OF_CON;
+
+typedef enum {
+ BAUDRATE = 0,
+ DATABITS,
+ PARITY,
+ STOPBITS,
+ UNKNOW_ATTR
+} TYPE_OF_ATTRIBUTE;
+
+typedef enum {
+ MANNER_GOTO = 0,
+ MANNER_CHECK,
+ MANNER_ONEOF,
+ MANNER_USER_DEFINE
+} TYPE_OF_UPATE_MANNER;
+
+typedef enum {
+ INACTIVE_STATE = 0,
+ BOOT_FROM_FILE_STATE,
+ ADD_BOOT_OPTION_STATE,
+ ADD_DRIVER_OPTION_STATE,
+ UNKNOWN_STATE
+} FILE_EXPLORER_STATE;
+
+typedef enum {
+ FILE_SYSTEM,
+ DIRECTORY,
+ UNKNOWN_CONTEXT
+} FILE_EXPLORER_DISPLAY_CONTEXT;
+
+//
+// All of the signatures that will be used in list structure
+//
+#define BM_MENU_OPTION_SIGNATURE 'menu'
+#define BM_LOAD_OPTION_SIGNATURE 'load'
+#define BM_CONSOLE_OPTION_SIGNATURE 'cnsl'
+#define BM_FILE_OPTION_SIGNATURE 'file'
+#define BM_HANDLE_OPTION_SIGNATURE 'hndl'
+#define BM_TERMINAL_OPTION_SIGNATURE 'trml'
+#define BM_MENU_ENTRY_SIGNATURE 'entr'
+
+#define BM_LOAD_CONTEXT_SELECT 0x0
+#define BM_CONSOLE_CONTEXT_SELECT 0x1
+#define BM_FILE_CONTEXT_SELECT 0x2
+#define BM_HANDLE_CONTEXT_SELECT 0x3
+#define BM_TERMINAL_CONTEXT_SELECT 0x5
+
+#define BM_CONSOLE_IN_CONTEXT_SELECT 0x6
+#define BM_CONSOLE_OUT_CONTEXT_SELECT 0x7
+#define BM_CONSOLE_ERR_CONTEXT_SELECT 0x8
+#define BM_LEGACY_DEV_CONTEXT_SELECT 0x9
+
+//
+// Buffer size for update data
+//
+#define UPDATE_DATA_SIZE 0x100000
+
+//
+// Namespace of callback keys used in display and file system navigation
+//
+#define MAX_BBS_OFFSET 0xE000
+#define NET_OPTION_OFFSET 0xD800
+#define BEV_OPTION_OFFSET 0xD000
+#define FD_OPTION_OFFSET 0xC000
+#define HD_OPTION_OFFSET 0xB000
+#define CD_OPTION_OFFSET 0xA000
+#define FILE_OPTION_OFFSET 0x8000
+#define FILE_OPTION_MASK 0x7FFF
+#define HANDLE_OPTION_OFFSET 0x7000
+#define CONSOLE_OPTION_OFFSET 0x6000
+#define TERMINAL_OPTION_OFFSET 0x5000
+#define CONFIG_OPTION_OFFSET 0x1200
+#define KEY_VALUE_OFFSET 0x1100
+#define FORM_ID_OFFSET 0x1000
+
+//
+// VarOffset that will be used to create question
+// all these values are computed from the structure
+// defined below
+//
+#define VAR_OFFSET(Field) ((UINT16) ((UINTN) &(((BMM_FAKE_NV_DATA *) 0)->Field)))
+
+//
+// Question Id of Zero is invalid, so add an offset to it
+//
+#define QUESTION_ID(Field) (VAR_OFFSET (Field) + CONFIG_OPTION_OFFSET)
+
+#define BOOT_TIME_OUT_VAR_OFFSET VAR_OFFSET (BootTimeOut)
+#define BOOT_NEXT_VAR_OFFSET VAR_OFFSET (BootNext)
+#define COM1_BAUD_RATE_VAR_OFFSET VAR_OFFSET (COM1BaudRate)
+#define COM1_DATA_RATE_VAR_OFFSET VAR_OFFSET (COM1DataRate)
+#define COM1_STOP_BITS_VAR_OFFSET VAR_OFFSET (COM1StopBits)
+#define COM1_PARITY_VAR_OFFSET VAR_OFFSET (COM1Parity)
+#define COM1_TERMINAL_VAR_OFFSET VAR_OFFSET (COM2TerminalType)
+#define COM2_BAUD_RATE_VAR_OFFSET VAR_OFFSET (COM2BaudRate)
+#define COM2_DATA_RATE_VAR_OFFSET VAR_OFFSET (COM2DataRate)
+#define COM2_STOP_BITS_VAR_OFFSET VAR_OFFSET (COM2StopBits)
+#define COM2_PARITY_VAR_OFFSET VAR_OFFSET (COM2Parity)
+#define COM2_TERMINAL_VAR_OFFSET VAR_OFFSET (COM2TerminalType)
+#define DRV_ADD_HANDLE_DESC_VAR_OFFSET VAR_OFFSET (DriverAddHandleDesc)
+#define DRV_ADD_ACTIVE_VAR_OFFSET VAR_OFFSET (DriverAddActive)
+#define DRV_ADD_RECON_VAR_OFFSET VAR_OFFSET (DriverAddForceReconnect)
+#define CON_IN_COM1_VAR_OFFSET VAR_OFFSET (ConsoleInputCOM1)
+#define CON_IN_COM2_VAR_OFFSET VAR_OFFSET (ConsoleInputCOM2)
+#define CON_OUT_COM1_VAR_OFFSET VAR_OFFSET (ConsoleOutputCOM1)
+#define CON_OUT_COM2_VAR_OFFSET VAR_OFFSET (ConsoleOutputCOM2)
+#define CON_ERR_COM1_VAR_OFFSET VAR_OFFSET (ConsoleErrorCOM1)
+#define CON_ERR_COM2_VAR_OFFSET VAR_OFFSET (ConsoleErrorCOM2)
+#define CON_MODE_VAR_OFFSET VAR_OFFSET (ConsoleOutMode)
+#define CON_DEVICE_VAR_OFFSET VAR_OFFSET (ConsoleCheck)
+#define OPTION_ORDER_VAR_OFFSET VAR_OFFSET (OptionOrder)
+#define DRIVER_OPTION_ORDER_VAR_OFFSET VAR_OFFSET (DriverOptionToBeDeleted)
+#define BOOT_OPTION_DEL_VAR_OFFSET VAR_OFFSET (BootOptionDel)
+#define DRIVER_OPTION_DEL_VAR_OFFSET VAR_OFFSET (DriverOptionDel)
+#define DRIVER_ADD_OPTION_VAR_OFFSET VAR_OFFSET (DriverAddHandleOptionalData)
+#define COM_BAUD_RATE_VAR_OFFSET VAR_OFFSET (COMBaudRate)
+#define COM_DATA_RATE_VAR_OFFSET VAR_OFFSET (COMDataRate)
+#define COM_STOP_BITS_VAR_OFFSET VAR_OFFSET (COMStopBits)
+#define COM_PARITY_VAR_OFFSET VAR_OFFSET (COMParity)
+#define COM_TERMINAL_VAR_OFFSET VAR_OFFSET (COMTerminalType)
+#define LEGACY_FD_VAR_OFFSET VAR_OFFSET (LegacyFD)
+#define LEGACY_HD_VAR_OFFSET VAR_OFFSET (LegacyHD)
+#define LEGACY_CD_VAR_OFFSET VAR_OFFSET (LegacyCD)
+#define LEGACY_NET_VAR_OFFSET VAR_OFFSET (LegacyNET)
+#define LEGACY_BEV_VAR_OFFSET VAR_OFFSET (LegacyBEV)
+
+#define BOOT_TIME_OUT_QUESTION_ID QUESTION_ID (BootTimeOut)
+#define BOOT_NEXT_QUESTION_ID QUESTION_ID (BootNext)
+#define COM1_BAUD_RATE_QUESTION_ID QUESTION_ID (COM1BaudRate)
+#define COM1_DATA_RATE_QUESTION_ID QUESTION_ID (COM1DataRate)
+#define COM1_STOP_BITS_QUESTION_ID QUESTION_ID (COM1StopBits)
+#define COM1_PARITY_QUESTION_ID QUESTION_ID (COM1Parity)
+#define COM1_TERMINAL_QUESTION_ID QUESTION_ID (COM2TerminalType)
+#define COM2_BAUD_RATE_QUESTION_ID QUESTION_ID (COM2BaudRate)
+#define COM2_DATA_RATE_QUESTION_ID QUESTION_ID (COM2DataRate)
+#define COM2_STOP_BITS_QUESTION_ID QUESTION_ID (COM2StopBits)
+#define COM2_PARITY_QUESTION_ID QUESTION_ID (COM2Parity)
+#define COM2_TERMINAL_QUESTION_ID QUESTION_ID (COM2TerminalType)
+#define DRV_ADD_HANDLE_DESC_QUESTION_ID QUESTION_ID (DriverAddHandleDesc)
+#define DRV_ADD_ACTIVE_QUESTION_ID QUESTION_ID (DriverAddActive)
+#define DRV_ADD_RECON_QUESTION_ID QUESTION_ID (DriverAddForceReconnect)
+#define CON_IN_COM1_QUESTION_ID QUESTION_ID (ConsoleInputCOM1)
+#define CON_IN_COM2_QUESTION_ID QUESTION_ID (ConsoleInputCOM2)
+#define CON_OUT_COM1_QUESTION_ID QUESTION_ID (ConsoleOutputCOM1)
+#define CON_OUT_COM2_QUESTION_ID QUESTION_ID (ConsoleOutputCOM2)
+#define CON_ERR_COM1_QUESTION_ID QUESTION_ID (ConsoleErrorCOM1)
+#define CON_ERR_COM2_QUESTION_ID QUESTION_ID (ConsoleErrorCOM2)
+#define CON_MODE_QUESTION_ID QUESTION_ID (ConsoleOutMode)
+#define CON_DEVICE_QUESTION_ID QUESTION_ID (ConsoleCheck)
+#define OPTION_ORDER_QUESTION_ID QUESTION_ID (OptionOrder)
+#define DRIVER_OPTION_ORDER_QUESTION_ID QUESTION_ID (DriverOptionToBeDeleted)
+#define BOOT_OPTION_DEL_QUESTION_ID QUESTION_ID (BootOptionDel)
+#define DRIVER_OPTION_DEL_QUESTION_ID QUESTION_ID (DriverOptionDel)
+#define DRIVER_ADD_OPTION_QUESTION_ID QUESTION_ID (DriverAddHandleOptionalData)
+#define COM_BAUD_RATE_QUESTION_ID QUESTION_ID (COMBaudRate)
+#define COM_DATA_RATE_QUESTION_ID QUESTION_ID (COMDataRate)
+#define COM_STOP_BITS_QUESTION_ID QUESTION_ID (COMStopBits)
+#define COM_PARITY_QUESTION_ID QUESTION_ID (COMParity)
+#define COM_TERMINAL_QUESTION_ID QUESTION_ID (COMTerminalType)
+#define LEGACY_FD_QUESTION_ID QUESTION_ID (LegacyFD)
+#define LEGACY_HD_QUESTION_ID QUESTION_ID (LegacyHD)
+#define LEGACY_CD_QUESTION_ID QUESTION_ID (LegacyCD)
+#define LEGACY_NET_QUESTION_ID QUESTION_ID (LegacyNET)
+#define LEGACY_BEV_QUESTION_ID QUESTION_ID (LegacyBEV)
+
+#define STRING_DEPOSITORY_NUMBER 8
+
+//
+// #pragma pack(1)
+//
+// Serial Ports attributes, first one is the value for
+// return from callback function, stringtoken is used to
+// display the value properly
+//
+typedef struct {
+ UINTN Value;
+ UINT16 StringToken;
+} COM_ATTR;
+
+typedef struct {
+ BBS_TYPE BbsType;
+ //
+ // Length = sizeof (UINT16) + SIZEOF (Data)
+ //
+ UINT16 Length;
+ UINT16 *Data;
+} BM_LEGACY_DEV_ORDER_CONTEXT;
+
+typedef struct {
+ UINT64 BaudRate;
+ UINT8 DataBits;
+ UINT8 Parity;
+ UINT8 StopBits;
+
+ UINT8 BaudRateIndex;
+ UINT8 DataBitsIndex;
+ UINT8 ParityIndex;
+ UINT8 StopBitsIndex;
+
+ UINT8 IsConIn;
+ UINT8 IsConOut;
+ UINT8 IsStdErr;
+ UINT8 TerminalType;
+
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+} BM_TERMINAL_CONTEXT;
+
+typedef struct {
+ BOOLEAN IsBootNext;
+ BOOLEAN LoadOptionModified;
+ BOOLEAN Deleted;
+
+ BOOLEAN IsLegacy;
+ BOOLEAN IsActive;
+ BOOLEAN ForceReconnect;
+ UINTN OptionalDataSize;
+
+ UINTN LoadOptionSize;
+ UINT8 *LoadOption;
+
+ UINT32 Attributes;
+ UINT16 FilePathListLength;
+ UINT16 *Description;
+ EFI_DEVICE_PATH_PROTOCOL *FilePathList;
+ UINT8 *OptionalData;
+
+ UINT16 BbsIndex;
+} BM_LOAD_CONTEXT;
+
+typedef struct {
+ BBS_TABLE *BbsTable;
+ UINTN Index;
+ UINTN BbsCount;
+ UINT16 *Description;
+} BM_LEGACY_DEVICE_CONTEXT;
+
+typedef struct {
+
+ BOOLEAN IsActive;
+
+ BOOLEAN IsTerminal;
+
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+} BM_CONSOLE_CONTEXT;
+
+typedef struct {
+ UINTN Column;
+ UINTN Row;
+} CONSOLE_OUT_MODE;
+
+typedef struct {
+ EFI_HANDLE Handle;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_FILE_HANDLE FHandle;
+ UINT16 *FileName;
+ EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *Info;
+
+ BOOLEAN IsRoot;
+ BOOLEAN IsDir;
+ BOOLEAN IsRemovableMedia;
+ BOOLEAN IsLoadFile;
+ BOOLEAN IsBootLegacy;
+} BM_FILE_CONTEXT;
+
+typedef struct {
+ EFI_HANDLE Handle;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+} BM_HANDLE_CONTEXT;
+
+typedef struct {
+ UINTN Signature;
+ LIST_ENTRY Head;
+ UINTN MenuNumber;
+} BM_MENU_OPTION;
+
+typedef struct {
+ UINTN Signature;
+ LIST_ENTRY Link;
+ UINTN OptionNumber;
+ UINT16 *DisplayString;
+ UINT16 *HelpString;
+ EFI_STRING_ID DisplayStringToken;
+ EFI_STRING_ID HelpStringToken;
+ UINTN ContextSelection;
+ VOID *VariableContext;
+} BM_MENU_ENTRY;
+
+typedef struct {
+ //
+ // Shared callback data.
+ //
+ UINTN Signature;
+
+ BM_MENU_ENTRY *MenuEntry;
+ BM_HANDLE_CONTEXT *HandleContext;
+ BM_FILE_CONTEXT *FileContext;
+ BM_LOAD_CONTEXT *LoadContext;
+ BM_TERMINAL_CONTEXT *TerminalContext;
+ UINTN CurrentTerminal;
+ UINT8 BbsType;
+
+ //
+ // BMM main formset callback data.
+ //
+ EFI_HII_HANDLE BmmHiiHandle;
+ EFI_HANDLE BmmDriverHandle;
+ EFI_HII_CONFIG_ACCESS_PROTOCOL BmmConfigAccess;
+ EFI_FORM_ID BmmCurrentPageId;
+ EFI_FORM_ID BmmPreviousPageId;
+ BOOLEAN BmmAskSaveOrNot;
+ BMM_FAKE_NV_DATA BmmFakeNvData;
+ BMM_FAKE_NV_DATA BmmOldFakeNVData;
+
+ //
+ // File explorer formset callback data.
+ //
+ EFI_HII_HANDLE FeHiiHandle;
+ EFI_HANDLE FeDriverHandle;
+ EFI_HII_CONFIG_ACCESS_PROTOCOL FeConfigAccess;
+ FILE_EXPLORER_STATE FeCurrentState;
+ FILE_EXPLORER_DISPLAY_CONTEXT FeDisplayContext;
+ FILE_EXPLORER_NV_DATA FeFakeNvData;
+} BMM_CALLBACK_DATA;
+
+typedef struct _STRING_LIST_NODE {
+ EFI_STRING_ID StringToken;
+ struct _STRING_LIST_NODE *Next;
+} STRING_LIST_NODE;
+
+typedef struct _STRING_DEPOSITORY {
+ UINTN TotalNodeNumber;
+ STRING_LIST_NODE *CurrentNode;
+ STRING_LIST_NODE *ListHead;
+} STRING_DEPOSITORY;
+
+//
+// #pragma pack()
+//
+// For initializing File System menu
+//
+EFI_STATUS
+BOpt_FindFileSystem (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+;
+
+//
+// For cleaning up File System menu
+//
+VOID
+BOpt_FreeFileSystem (
+ VOID
+ )
+;
+
+//
+// For initializing File Navigation menu
+//
+EFI_STATUS
+BOpt_FindFiles (
+ IN BMM_CALLBACK_DATA *CallbackData,
+ IN BM_MENU_ENTRY *MenuEntry
+ )
+;
+
+//
+// For cleaning up File Navigation menu
+//
+VOID
+BOpt_FreeFiles (
+ VOID
+ )
+;
+
+//
+// For Initializing handle navigation menu
+//
+EFI_STATUS
+BOpt_FindDrivers (
+ VOID
+ )
+;
+
+//
+// For Cleaning up handle navigation menu
+//
+VOID
+BOpt_FreeDrivers(VOID);
+
+//
+// For initializing Boot Option menu
+//
+EFI_STATUS
+BOpt_GetBootOptions (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+//
+// For Initializing Driver option menu
+//
+EFI_STATUS
+BOpt_GetDriverOptions (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+//
+// For Cleaning up boot option menu
+//
+VOID
+BOpt_FreeBootOptions (VOID);
+
+//
+// For cleaning up driver option menu
+//
+VOID
+BOpt_FreeDriverOptions(VOID);
+
+//
+// For Initializing HD/FD/CD/NET/BEV option menu
+//
+EFI_STATUS
+BOpt_GetLegacyOptions(VOID);
+
+//
+// For cleaning up driver option menu
+//
+VOID
+BOpt_FreeLegacyOptions(VOID);
+
+//
+// this function is used to take place of all other free menu actions
+//
+VOID
+BOpt_FreeMenu (
+ BM_MENU_OPTION *FreeMenu
+ );
+
+
+//
+// Following are the helper functions used
+//
+CHAR16 *
+BOpt_AppendFileName (
+ IN CHAR16 *Str1,
+ IN CHAR16 *Str2
+ );
+
+BOOLEAN
+BOpt_IsEfiImageName (
+ IN UINT16 *FileName
+ );
+
+BOOLEAN
+BOpt_IsEfiApp (
+ IN EFI_FILE_HANDLE Dir,
+ IN UINT16 *FileName
+ );
+
+//
+// Get current unused boot option number
+//
+UINT16
+BOpt_GetBootOptionNumber (VOID);
+
+//
+// Get current unused driver option number
+//
+UINT16
+BOpt_GetDriverOptionNumber (VOID);
+
+BM_MENU_ENTRY *
+BOpt_CreateMenuEntry (
+ UINTN MenuType
+ );
+
+VOID
+BOpt_DestroyMenuEntry (
+ BM_MENU_ENTRY *MenuEntry
+ );
+
+BM_MENU_ENTRY *
+BOpt_GetMenuEntry (
+ BM_MENU_OPTION *MenuOption,
+ UINTN MenuNumber
+ );
+
+//
+// a helper function used to free pool type memory
+//
+VOID
+SafeFreePool (
+ IN VOID *Buffer
+ );
+
+//
+// Locate all serial io devices for console
+//
+EFI_STATUS
+LocateSerialIo (VOID);
+
+//
+// Initializing Console menu
+//
+EFI_STATUS
+GetAllConsoles(VOID);
+
+//
+// Get current mode information
+//
+VOID
+GetConsoleOutMode (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+//
+// Cleaning up console menu
+//
+EFI_STATUS
+FreeAllConsoles(VOID);
+
+VOID
+ChangeVariableDevicePath (
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath
+);
+
+EFI_STATUS
+ChangeTerminalDevicePath (
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ BOOLEAN ChangeTerminal
+);
+//
+// Variable operation by menu selection
+//
+EFI_STATUS
+Var_UpdateBootOption (
+ IN BMM_CALLBACK_DATA *CallbackData,
+ IN FILE_EXPLORER_NV_DATA *NvRamMap
+ );
+
+EFI_STATUS
+Var_DelBootOption (VOID);
+
+EFI_STATUS
+Var_ChangeBootOrder (VOID);
+
+EFI_STATUS
+Var_UpdateDriverOption (
+ IN BMM_CALLBACK_DATA *CallbackData,
+ IN EFI_HII_HANDLE HiiHandle,
+ IN UINT16 *DescriptionData,
+ IN UINT16 *OptionalData,
+ IN UINT8 ForceReconnect
+ );
+
+EFI_STATUS
+Var_DelDriverOption (VOID);
+
+EFI_STATUS
+Var_ChangeDriverOrder (VOID);
+
+EFI_STATUS
+Var_UpdateConsoleInpOption (VOID);
+
+EFI_STATUS
+Var_UpdateConsoleOutOption (VOID);
+
+EFI_STATUS
+Var_UpdateErrorOutOption (VOID);
+
+VOID
+Var_UpdateAllConsoleOption (VOID);
+
+EFI_STATUS
+Var_UpdateBootNext (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+EFI_STATUS
+Var_UpdateBootOrder (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+EFI_STATUS
+Var_UpdateDriverOrder (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+EFI_STATUS
+Var_UpdateBBSOption (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+EFI_STATUS
+Var_UpdateConMode (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+//
+// Following are page create and refresh functions
+//
+VOID
+RefreshUpdateData (
+ VOID
+ );
+
+VOID
+CleanUpPage (
+ IN UINT16 LabelId,
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+EFI_STATUS
+UpdatePage (
+ IN BMM_CALLBACK_DATA *CallbackData,
+ IN BM_MENU_OPTION *UpdatingMenu,
+ IN UINT16 UpdatingPage,
+ IN UINT16 UpdatingManner,
+ IN UINT16 QuestionIdStart,
+ IN UINT16 GotoForm,
+ IN UINT16 GotoAlternateForm,
+ IN EFI_STRING_ID DisplayTokenStart,
+ IN EFI_STRING_ID HelpTokenStart,
+ IN UINT16 KeyValueStart
+ );
+
+VOID
+UpdateBootAddPage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+VOID
+UpdateBootDelPage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+VOID
+UpdateDrvAddFilePage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+VOID
+UpdateDrvAddHandlePage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+VOID
+UpdateDrvDelPage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+VOID
+UpdateDriverAddHandleDescPage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+VOID
+UpdateBootTimeOut (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+VOID
+UpdateConInPage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+VOID
+UpdateConOutPage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+VOID
+UpdateStdErrPage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+VOID
+UpdatePageBody (
+ IN UINT16 UpdatePageId,
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+VOID
+UpdateCOM1Page (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+VOID
+UpdateCOM2Page (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+VOID
+UpdateBootOrderPage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+VOID
+UpdateDriverOrderPage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+VOID
+UpdateBootNextPage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+VOID
+UpdateTimeOutPage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+VOID
+UpdateTerminalPage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+VOID
+UpdateConModePage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+VOID
+UpdateConCOMPage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+VOID
+UpdateSetLegacyDeviceOrderPage (
+ IN UINT16 UpdatePageId,
+ IN BMM_CALLBACK_DATA *CallbackData
+);
+
+EFI_STATUS
+BootLegacy (
+ IN UINT16 BbsType,
+ IN UINT16 BbsFlag
+);
+
+BM_MENU_ENTRY *
+GetCurrentTerminal (
+ UINTN TerminalNumber
+);
+
+EFI_FILE_HANDLE
+EfiLibOpenRoot (
+ IN EFI_HANDLE DeviceHandle
+ );
+
+EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *
+EfiLibFileSystemVolumeLabelInfo (
+ IN EFI_FILE_HANDLE FHand
+ );
+
+EFI_FILE_INFO *
+EfiLibFileInfo (
+ IN EFI_FILE_HANDLE FHand
+ );
+
+UINTN
+UnicodeToAscii (
+ IN CHAR16 *UStr,
+ IN UINTN Length,
+ OUT CHAR8 *AStr
+ );
+
+CHAR16 *
+DevicePathToStr (
+ EFI_DEVICE_PATH_PROTOCOL *DevPath
+ );
+
+VOID *
+EfiAllocateZeroPool (
+ IN UINTN Size
+ );
+
+EFI_STATUS
+EfiLibLocateProtocol (
+ IN EFI_GUID *ProtocolGuid,
+ OUT VOID **Interface
+ );
+
+VOID *
+EfiReallocatePool (
+ IN VOID *OldPool,
+ IN UINTN OldSize,
+ IN UINTN NewSize
+ );
+
+CHAR16 *
+DevicePathToStr (
+ EFI_DEVICE_PATH_PROTOCOL *DevPath
+ );
+
+VOID *
+BdsLibGetVariableAndSize (
+ IN CHAR16 *Name,
+ IN EFI_GUID *VendorGuid,
+ OUT UINTN *VarSize
+ );
+
+EFI_STATUS
+EfiLibDeleteVariable (
+ IN CHAR16 *VarName,
+ IN EFI_GUID *VarGuid
+ );
+
+CHAR16 *
+EfiStrDuplicate (
+ IN CHAR16 *Src
+ );
+
+BOOLEAN
+EfiLibMatchDevicePaths (
+ IN EFI_DEVICE_PATH_PROTOCOL *Multi,
+ IN EFI_DEVICE_PATH_PROTOCOL *Single
+ );
+
+UINTN
+EfiDevicePathInstanceCount (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+EFI_STATUS
+CreateMenuStringToken (
+ IN BMM_CALLBACK_DATA *CallbackData,
+ IN EFI_HII_HANDLE HiiHandle,
+ IN BM_MENU_OPTION *MenuOption
+ );
+
+UINT16 *
+EfiLibStrFromDatahub (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevPath
+ );
+
+VOID *
+GetLegacyBootOptionVar (
+ IN UINTN DeviceType,
+ OUT UINTN *OptionIndex,
+ OUT UINTN *OptionSize
+ );
+
+EFI_STATUS
+InitializeBM (
+ VOID
+ );
+
+EFI_STATUS
+BdsStartBootMaint (
+ VOID
+ );
+
+VOID
+InitializeStringDepository (VOID);
+
+EFI_STRING_ID
+GetStringTokenFromDepository (
+ IN BMM_CALLBACK_DATA *CallbackData,
+ IN STRING_DEPOSITORY *StringDepository
+ );
+
+VOID
+ReclaimStringDepository (
+ VOID
+ );
+
+VOID
+CleanUpStringDepository (
+ VOID
+ );
+
+EFI_STATUS
+ApplyChangeHandler (
+ IN BMM_CALLBACK_DATA *Private,
+ IN BMM_FAKE_NV_DATA *CurrentFakeNVMap,
+ IN EFI_FORM_ID FormId
+ );
+
+VOID
+DiscardChangeHandler (
+ IN BMM_CALLBACK_DATA *Private,
+ IN BMM_FAKE_NV_DATA *CurrentFakeNVMap
+ );
+
+VOID
+UpdatePageId (
+ BMM_CALLBACK_DATA *Private,
+ UINT16 NewPageId
+ );
+
+EFI_STATUS
+BootThisFile (
+ IN BM_FILE_CONTEXT *FileContext
+ );
+
+BOOLEAN
+UpdateFileExplorer (
+ IN BMM_CALLBACK_DATA *CallbackData,
+ IN UINT16 KeyValue
+ );
+
+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
+ );
+
+EFI_STATUS
+FormSetDispatcher (
+ IN BMM_CALLBACK_DATA *CallbackData
+ );
+
+//
+// Global variable in this program (defined in data.c)
+//
+extern BM_MENU_OPTION BootOptionMenu;
+extern BM_MENU_OPTION DriverOptionMenu;
+extern BM_MENU_OPTION FsOptionMenu;
+extern BM_MENU_OPTION ConsoleInpMenu;
+extern BM_MENU_OPTION ConsoleOutMenu;
+extern BM_MENU_OPTION ConsoleErrMenu;
+extern BM_MENU_OPTION DirectoryMenu;
+extern BM_MENU_OPTION DriverMenu;
+extern BM_MENU_OPTION TerminalMenu;
+extern BM_MENU_OPTION LegacyFDMenu;
+extern BM_MENU_OPTION LegacyHDMenu;
+extern BM_MENU_OPTION LegacyCDMenu;
+extern BM_MENU_OPTION LegacyNETMenu;
+extern BM_MENU_OPTION LegacyBEVMenu;
+extern UINT16 TerminalType[];
+extern COM_ATTR BaudRateList[19];
+extern COM_ATTR DataBitsList[4];
+extern COM_ATTR ParityList[5];
+extern COM_ATTR StopBitsList[3];
+extern EFI_GUID Guid[4];
+extern EFI_HII_UPDATE_DATA gUpdateData;
+extern STRING_DEPOSITORY *FileOptionStrDepository;
+extern STRING_DEPOSITORY *ConsoleOptionStrDepository;
+extern STRING_DEPOSITORY *BootOptionStrDepository;
+extern STRING_DEPOSITORY *BootOptionHelpStrDepository;
+extern STRING_DEPOSITORY *DriverOptionStrDepository;
+extern STRING_DEPOSITORY *DriverOptionHelpStrDepository;
+extern STRING_DEPOSITORY *TerminalStrDepository;
+extern EFI_DEVICE_PATH_PROTOCOL EndDevicePath[];
+extern EFI_GUID EfiLegacyDevOrderGuid;
+
+#endif
diff --git a/MdeModulePkg/Universal/BdsDxe/BootMaint/BootOption.c b/MdeModulePkg/Universal/BdsDxe/BootMaint/BootOption.c new file mode 100644 index 0000000000..9a2273cfc4 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/BootMaint/BootOption.c @@ -0,0 +1,1697 @@ +/*++
+Copyright (c) 2004 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ bootoption.c
+
+Abstract:
+
+ Provide boot option support for Application "BootMaint"
+
+ Include file system navigation, system handle selection
+
+ Boot option manipulation
+
+Revision History
+
+--*/
+
+#include "BootMaint.h"
+#include "BBSsupport.h"
+
+BM_MENU_ENTRY *
+BOpt_CreateMenuEntry (
+ UINTN MenuType
+ )
+/*++
+
+Routine Description
+ Create Menu Entry for future use, make all types together
+ in order to reduce code size
+
+Arguments:
+ MenuType Use this parameter to identify current
+ Menu type
+
+Returns:
+ NULL Cannot allocate memory for current menu
+ entry
+ Others A valid pointer pointing to the allocated
+ memory pool for current menu entry
+
+--*/
+{
+ BM_MENU_ENTRY *MenuEntry;
+ UINTN ContextSize;
+
+ switch (MenuType) {
+ case BM_LOAD_CONTEXT_SELECT:
+ ContextSize = sizeof (BM_LOAD_CONTEXT);
+ break;
+
+ case BM_FILE_CONTEXT_SELECT:
+ ContextSize = sizeof (BM_FILE_CONTEXT);
+ break;
+
+ case BM_CONSOLE_CONTEXT_SELECT:
+ ContextSize = sizeof (BM_CONSOLE_CONTEXT);
+ break;
+
+ case BM_TERMINAL_CONTEXT_SELECT:
+ ContextSize = sizeof (BM_TERMINAL_CONTEXT);
+ break;
+
+ case BM_HANDLE_CONTEXT_SELECT:
+ ContextSize = sizeof (BM_HANDLE_CONTEXT);
+ break;
+
+ case BM_LEGACY_DEV_CONTEXT_SELECT:
+ ContextSize = sizeof (BM_LEGACY_DEVICE_CONTEXT);
+ break;
+
+ default:
+ ContextSize = 0;
+ break;
+
+ }
+
+ if (0 == ContextSize) {
+ return NULL;
+ }
+
+ MenuEntry = EfiAllocateZeroPool (sizeof (BM_MENU_ENTRY));
+ if (NULL == MenuEntry) {
+ return MenuEntry;
+ }
+
+ MenuEntry->VariableContext = EfiAllocateZeroPool (ContextSize);
+ if (NULL == MenuEntry->VariableContext) {
+ SafeFreePool (MenuEntry);
+ MenuEntry = NULL;
+ return MenuEntry;
+ }
+
+ MenuEntry->Signature = BM_MENU_ENTRY_SIGNATURE;
+ MenuEntry->ContextSelection = MenuType;
+ return MenuEntry;
+}
+
+VOID
+BOpt_DestroyMenuEntry (
+ BM_MENU_ENTRY *MenuEntry
+ )
+/*++
+ Routine Description :
+ Destroy the menu entry passed in
+
+ Arguments :
+ The menu entry need to be destroyed
+
+ Returns :
+ None
+
+--*/
+{
+ BM_LOAD_CONTEXT *LoadContext;
+ BM_FILE_CONTEXT *FileContext;
+ BM_CONSOLE_CONTEXT *ConsoleContext;
+ BM_TERMINAL_CONTEXT *TerminalContext;
+ BM_HANDLE_CONTEXT *HandleContext;
+ BM_LEGACY_DEVICE_CONTEXT *LegacyDevContext;
+
+ //
+ // Select by the type in Menu entry for current context type
+ //
+ switch (MenuEntry->ContextSelection) {
+ case BM_LOAD_CONTEXT_SELECT:
+ LoadContext = (BM_LOAD_CONTEXT *) MenuEntry->VariableContext;
+ SafeFreePool (LoadContext->FilePathList);
+ SafeFreePool (LoadContext->LoadOption);
+ SafeFreePool (LoadContext->OptionalData);
+ SafeFreePool (LoadContext);
+ break;
+
+ case BM_FILE_CONTEXT_SELECT:
+ FileContext = (BM_FILE_CONTEXT *) MenuEntry->VariableContext;
+
+ if (!FileContext->IsRoot) {
+ SafeFreePool (FileContext->DevicePath);
+ } else {
+ if (FileContext->FHandle != NULL) {
+ FileContext->FHandle->Close (FileContext->FHandle);
+ }
+ }
+
+ SafeFreePool (FileContext->FileName);
+ SafeFreePool (FileContext->Info);
+ SafeFreePool (FileContext);
+ break;
+
+ case BM_CONSOLE_CONTEXT_SELECT:
+ ConsoleContext = (BM_CONSOLE_CONTEXT *) MenuEntry->VariableContext;
+ SafeFreePool (ConsoleContext->DevicePath);
+ SafeFreePool (ConsoleContext);
+ break;
+
+ case BM_TERMINAL_CONTEXT_SELECT:
+ TerminalContext = (BM_TERMINAL_CONTEXT *) MenuEntry->VariableContext;
+ SafeFreePool (TerminalContext->DevicePath);
+ SafeFreePool (TerminalContext);
+ break;
+
+ case BM_HANDLE_CONTEXT_SELECT:
+ HandleContext = (BM_HANDLE_CONTEXT *) MenuEntry->VariableContext;
+ SafeFreePool (HandleContext);
+ break;
+
+ case BM_LEGACY_DEV_CONTEXT_SELECT:
+ LegacyDevContext = (BM_LEGACY_DEVICE_CONTEXT *) MenuEntry->VariableContext;
+ SafeFreePool (LegacyDevContext);
+
+ default:
+ break;
+ }
+
+ SafeFreePool (MenuEntry->DisplayString);
+ if (NULL != MenuEntry->HelpString) {
+ SafeFreePool (MenuEntry->HelpString);
+ }
+
+ SafeFreePool (MenuEntry);
+}
+
+BM_MENU_ENTRY *
+BOpt_GetMenuEntry (
+ BM_MENU_OPTION *MenuOption,
+ UINTN MenuNumber
+ )
+/*++
+ Rountine Description :
+ Use this routine to get one particular menu entry in specified
+ menu
+
+ Arguments :
+ MenuOption The menu that we will search
+
+ MenuNumber The menunubmer that we want
+
+ Returns :
+ The desired menu entry
+
+--*/
+{
+ BM_MENU_ENTRY *NewMenuEntry;
+ UINTN Index;
+ LIST_ENTRY *List;
+
+ if (MenuNumber >= MenuOption->MenuNumber) {
+ return NULL;
+ }
+
+ List = MenuOption->Head.ForwardLink;
+ for (Index = 0; Index < MenuNumber; Index++) {
+ List = List->ForwardLink;
+ }
+
+ NewMenuEntry = CR (List, BM_MENU_ENTRY, Link, BM_MENU_ENTRY_SIGNATURE);
+
+ return NewMenuEntry;
+}
+
+EFI_STATUS
+BOpt_FindFileSystem (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+/*++
+
+Routine Description
+ Find file systems for current Extensible Firmware
+ Including Handles that support Simple File System
+ protocol, Load File protocol.
+
+ Building up the FileSystem Menu for user selection
+ All file system will be stored in FsOptionMenu
+ for future use.
+
+Arguments:
+ CallbackData - BMM context data
+
+Returns:
+ EFI_SUCCESS - Success find the file system
+ EFI_OUT_OF_RESOURCES - Can not create menu entry
+
+--*/
+{
+ UINTN NoBlkIoHandles;
+ UINTN NoSimpleFsHandles;
+ UINTN NoLoadFileHandles;
+ EFI_HANDLE *BlkIoHandle;
+ EFI_HANDLE *SimpleFsHandle;
+ EFI_HANDLE *LoadFileHandle;
+ UINT16 *VolumeLabel;
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;
+ UINTN Index;
+ EFI_STATUS Status;
+ BM_MENU_ENTRY *MenuEntry;
+ BM_FILE_CONTEXT *FileContext;
+ UINT16 *TempStr;
+ UINTN OptionNumber;
+ VOID *Buffer;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ UINT16 DeviceType;
+ BBS_BBS_DEVICE_PATH BbsDevicePathNode;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ BOOLEAN RemovableMedia;
+
+
+ NoSimpleFsHandles = 0;
+ NoLoadFileHandles = 0;
+ OptionNumber = 0;
+ InitializeListHead (&FsOptionMenu.Head);
+
+ //
+ // Locate Handles that support BlockIo protocol
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiBlockIoProtocolGuid,
+ NULL,
+ &NoBlkIoHandles,
+ &BlkIoHandle
+ );
+ if (!EFI_ERROR (Status)) {
+
+ for (Index = 0; Index < NoBlkIoHandles; Index++) {
+ Status = gBS->HandleProtocol (
+ BlkIoHandle[Index],
+ &gEfiBlockIoProtocolGuid,
+ (VOID **) &BlkIo
+ );
+
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ //
+ // Issue a dummy read to trigger reinstall of BlockIo protocol for removable media
+ //
+ if (BlkIo->Media->RemovableMedia) {
+ Buffer = EfiAllocateZeroPool (BlkIo->Media->BlockSize);
+ if (NULL == Buffer) {
+ SafeFreePool (BlkIoHandle);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ BlkIo->ReadBlocks (
+ BlkIo,
+ BlkIo->Media->MediaId,
+ 0,
+ BlkIo->Media->BlockSize,
+ Buffer
+ );
+ SafeFreePool (Buffer);
+ }
+ }
+ SafeFreePool (BlkIoHandle);
+ }
+
+ //
+ // Locate Handles that support Simple File System protocol
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiSimpleFileSystemProtocolGuid,
+ NULL,
+ &NoSimpleFsHandles,
+ &SimpleFsHandle
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Find all the instances of the File System prototocol
+ //
+ for (Index = 0; Index < NoSimpleFsHandles; Index++) {
+ Status = gBS->HandleProtocol (
+ SimpleFsHandle[Index],
+ &gEfiBlockIoProtocolGuid,
+ (VOID **) &BlkIo
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // If no block IO exists assume it's NOT a removable media
+ //
+ RemovableMedia = FALSE;
+ } else {
+ //
+ // If block IO exists check to see if it's remobable media
+ //
+ RemovableMedia = BlkIo->Media->RemovableMedia;
+ }
+
+ //
+ // Allocate pool for this load option
+ //
+ MenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT);
+ if (NULL == MenuEntry) {
+ SafeFreePool (SimpleFsHandle);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ FileContext = (BM_FILE_CONTEXT *) MenuEntry->VariableContext;
+
+ FileContext->Handle = SimpleFsHandle[Index];
+ MenuEntry->OptionNumber = Index;
+ FileContext->FHandle = EfiLibOpenRoot (FileContext->Handle);
+ if (!FileContext->FHandle) {
+ BOpt_DestroyMenuEntry (MenuEntry);
+ continue;
+ }
+
+ MenuEntry->HelpString = DevicePathToStr (DevicePathFromHandle (FileContext->Handle));
+ FileContext->Info = EfiLibFileSystemVolumeLabelInfo (FileContext->FHandle);
+ FileContext->FileName = EfiStrDuplicate (L"\\");
+ FileContext->DevicePath = FileDevicePath (
+ FileContext->Handle,
+ FileContext->FileName
+ );
+ FileContext->IsDir = TRUE;
+ FileContext->IsRoot = TRUE;
+ FileContext->IsRemovableMedia = RemovableMedia;
+ FileContext->IsLoadFile = FALSE;
+
+ //
+ // Get current file system's Volume Label
+ //
+ if (FileContext->Info == NULL) {
+ VolumeLabel = L"NO FILE SYSTEM INFO";
+ } else {
+ if (FileContext->Info->VolumeLabel == NULL) {
+ VolumeLabel = L"NULL VOLUME LABEL";
+ } else {
+ VolumeLabel = FileContext->Info->VolumeLabel;
+ if (*VolumeLabel == 0x0000) {
+ VolumeLabel = L"NO VOLUME LABEL";
+ }
+ }
+ }
+
+ TempStr = MenuEntry->HelpString;
+ MenuEntry->DisplayString = EfiAllocateZeroPool (MAX_CHAR);
+ ASSERT (MenuEntry->DisplayString != NULL);
+ UnicodeSPrint (
+ MenuEntry->DisplayString,
+ MAX_CHAR,
+ L"%s, [%s]",
+ VolumeLabel,
+ TempStr
+ );
+ OptionNumber++;
+ InsertTailList (&FsOptionMenu.Head, &MenuEntry->Link);
+ }
+ }
+
+ if (NoSimpleFsHandles != 0) {
+ SafeFreePool (SimpleFsHandle);
+ }
+ //
+ // Searching for handles that support Load File protocol
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiLoadFileProtocolGuid,
+ NULL,
+ &NoLoadFileHandles,
+ &LoadFileHandle
+ );
+
+ if (!EFI_ERROR (Status)) {
+ for (Index = 0; Index < NoLoadFileHandles; Index++) {
+ MenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT);
+ if (NULL == MenuEntry) {
+ SafeFreePool (LoadFileHandle);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ FileContext = (BM_FILE_CONTEXT *) MenuEntry->VariableContext;
+ FileContext->IsRemovableMedia = FALSE;
+ FileContext->IsLoadFile = TRUE;
+ FileContext->Handle = LoadFileHandle[Index];
+ FileContext->IsRoot = TRUE;
+
+ FileContext->DevicePath = DevicePathFromHandle (FileContext->Handle);
+
+ MenuEntry->HelpString = DevicePathToStr (FileContext->DevicePath);
+
+ TempStr = MenuEntry->HelpString;
+ MenuEntry->DisplayString = EfiAllocateZeroPool (MAX_CHAR);
+ ASSERT (MenuEntry->DisplayString != NULL);
+ UnicodeSPrint (
+ MenuEntry->DisplayString,
+ MAX_CHAR,
+ L"Load File [%s]",
+ TempStr
+ );
+
+ MenuEntry->OptionNumber = OptionNumber;
+ OptionNumber++;
+ InsertTailList (&FsOptionMenu.Head, &MenuEntry->Link);
+ }
+ }
+
+ if (NoLoadFileHandles != 0) {
+ SafeFreePool (LoadFileHandle);
+ }
+
+ //
+ // Add Legacy Boot Option Support Here
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiLegacyBiosProtocolGuid,
+ NULL,
+ (VOID **) &LegacyBios
+ );
+ if (!EFI_ERROR (Status)) {
+
+ for (Index = BBS_TYPE_FLOPPY; Index <= BBS_TYPE_EMBEDDED_NETWORK; Index++) {
+ MenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT);
+ if (NULL == MenuEntry) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ FileContext = (BM_FILE_CONTEXT *) MenuEntry->VariableContext;
+
+ FileContext->IsRemovableMedia = FALSE;
+ FileContext->IsLoadFile = TRUE;
+ FileContext->IsBootLegacy = TRUE;
+ DeviceType = (UINT16) Index;
+ BbsDevicePathNode.Header.Type = BBS_DEVICE_PATH;
+ BbsDevicePathNode.Header.SubType = BBS_BBS_DP;
+ SetDevicePathNodeLength (
+ &BbsDevicePathNode.Header,
+ sizeof (BBS_BBS_DEVICE_PATH)
+ );
+ BbsDevicePathNode.DeviceType = DeviceType;
+ BbsDevicePathNode.StatusFlag = 0;
+ BbsDevicePathNode.String[0] = 0;
+ DevicePath = AppendDevicePathNode (
+ EndDevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *) &BbsDevicePathNode
+ );
+
+ FileContext->DevicePath = DevicePath;
+ MenuEntry->HelpString = DevicePathToStr (FileContext->DevicePath);
+
+ TempStr = MenuEntry->HelpString;
+ MenuEntry->DisplayString = EfiAllocateZeroPool (MAX_CHAR);
+ ASSERT (MenuEntry->DisplayString != NULL);
+ UnicodeSPrint (
+ MenuEntry->DisplayString,
+ MAX_CHAR,
+ L"Boot Legacy [%s]",
+ TempStr
+ );
+ MenuEntry->OptionNumber = OptionNumber;
+ OptionNumber++;
+ InsertTailList (&FsOptionMenu.Head, &MenuEntry->Link);
+ }
+ }
+ //
+ // Remember how many file system options are here
+ //
+ FsOptionMenu.MenuNumber = OptionNumber;
+ return EFI_SUCCESS;
+}
+
+VOID
+BOpt_FreeMenu (
+ BM_MENU_OPTION *FreeMenu
+ )
+/*++
+
+Routine Description
+ Free resources allocated in Allocate Rountine
+
+Arguments:
+ FreeMenu Menu to be freed
+
+Returns:
+ VOID
+
+--*/
+{
+ BM_MENU_ENTRY *MenuEntry;
+ while (!IsListEmpty (&FreeMenu->Head)) {
+ MenuEntry = CR (
+ FreeMenu->Head.ForwardLink,
+ BM_MENU_ENTRY,
+ Link,
+ BM_MENU_ENTRY_SIGNATURE
+ );
+ RemoveEntryList (&MenuEntry->Link);
+ BOpt_DestroyMenuEntry (MenuEntry);
+ }
+}
+
+EFI_STATUS
+BOpt_FindFiles (
+ IN BMM_CALLBACK_DATA *CallbackData,
+ IN BM_MENU_ENTRY *MenuEntry
+ )
+/*++
+
+Routine Description
+ Find files under current directory
+ All files and sub-directories in current directory
+ will be stored in DirectoryMenu for future use.
+
+Arguments:
+ FileOption -- Pointer for Dir to explore
+
+Returns:
+ TRUE -- Get files from current dir successfully
+ FALSE -- Can't get files from current dir
+
+--*/
+{
+ EFI_FILE_HANDLE NewDir;
+ EFI_FILE_HANDLE Dir;
+ EFI_FILE_INFO *DirInfo;
+ UINTN BufferSize;
+ UINTN DirBufferSize;
+ BM_MENU_ENTRY *NewMenuEntry;
+ BM_FILE_CONTEXT *FileContext;
+ BM_FILE_CONTEXT *NewFileContext;
+ UINTN Pass;
+ EFI_STATUS Status;
+ UINTN OptionNumber;
+
+ FileContext = (BM_FILE_CONTEXT *) MenuEntry->VariableContext;
+ Dir = FileContext->FHandle;
+ OptionNumber = 0;
+ //
+ // Open current directory to get files from it
+ //
+ Status = Dir->Open (
+ Dir,
+ &NewDir,
+ FileContext->FileName,
+ EFI_FILE_READ_ONLY,
+ 0
+ );
+ if (!FileContext->IsRoot) {
+ Dir->Close (Dir);
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DirInfo = EfiLibFileInfo (NewDir);
+ if (!DirInfo) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (!(DirInfo->Attribute & EFI_FILE_DIRECTORY)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FileContext->DevicePath = FileDevicePath (
+ FileContext->Handle,
+ FileContext->FileName
+ );
+
+ DirBufferSize = sizeof (EFI_FILE_INFO) + 1024;
+ DirInfo = EfiAllocateZeroPool (DirBufferSize);
+ if (!DirInfo) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Get all files in current directory
+ // Pass 1 to get Directories
+ // Pass 2 to get files that are EFI images
+ //
+ for (Pass = 1; Pass <= 2; Pass++) {
+ NewDir->SetPosition (NewDir, 0);
+ for (;;) {
+ BufferSize = DirBufferSize;
+ Status = NewDir->Read (NewDir, &BufferSize, DirInfo);
+ if (EFI_ERROR (Status) || BufferSize == 0) {
+ break;
+ }
+
+ if ((DirInfo->Attribute & EFI_FILE_DIRECTORY && Pass == 2) ||
+ (!(DirInfo->Attribute & EFI_FILE_DIRECTORY) && Pass == 1)
+ ) {
+ //
+ // Pass 1 is for Directories
+ // Pass 2 is for file names
+ //
+ continue;
+ }
+
+ if (!(BOpt_IsEfiImageName (DirInfo->FileName) || DirInfo->Attribute & EFI_FILE_DIRECTORY)) {
+ //
+ // Slip file unless it is a directory entry or a .EFI file
+ //
+ continue;
+ }
+
+ NewMenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT);
+ if (NULL == NewMenuEntry) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NewFileContext = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext;
+ NewFileContext->Handle = FileContext->Handle;
+ NewFileContext->FileName = BOpt_AppendFileName (
+ FileContext->FileName,
+ DirInfo->FileName
+ );
+ NewFileContext->FHandle = NewDir;
+ NewFileContext->DevicePath = FileDevicePath (
+ NewFileContext->Handle,
+ NewFileContext->FileName
+ );
+ NewMenuEntry->HelpString = NULL;
+
+ MenuEntry->DisplayStringToken = GetStringTokenFromDepository (
+ CallbackData,
+ FileOptionStrDepository
+ );
+
+ NewFileContext->IsDir = (BOOLEAN) ((DirInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY);
+
+ if (NewFileContext->IsDir) {
+ BufferSize = StrLen (DirInfo->FileName) * 2 + 6;
+ NewMenuEntry->DisplayString = EfiAllocateZeroPool (BufferSize);
+
+ UnicodeSPrint (
+ NewMenuEntry->DisplayString,
+ BufferSize,
+ L"<%s>",
+ DirInfo->FileName
+ );
+
+ } else {
+ NewMenuEntry->DisplayString = EfiStrDuplicate (DirInfo->FileName);
+ }
+
+ NewFileContext->IsRoot = FALSE;
+ NewFileContext->IsLoadFile = FALSE;
+ NewFileContext->IsRemovableMedia = FALSE;
+
+ NewMenuEntry->OptionNumber = OptionNumber;
+ OptionNumber++;
+ InsertTailList (&DirectoryMenu.Head, &NewMenuEntry->Link);
+ }
+ }
+
+ DirectoryMenu.MenuNumber = OptionNumber;
+ SafeFreePool (DirInfo);
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+BOpt_GetLegacyOptions (
+ VOID
+ )
+/*++
+Routine Description:
+
+ Build the LegacyFDMenu LegacyHDMenu LegacyCDMenu according to LegacyBios.GetBbsInfo().
+
+Arguments:
+ None
+
+Returns:
+ The device info of legacy device.
+
+--*/
+{
+ BM_MENU_ENTRY *NewMenuEntry;
+ BM_LEGACY_DEVICE_CONTEXT *NewLegacyDevContext;
+ EFI_STATUS Status;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ UINT16 HddCount;
+ HDD_INFO *HddInfo;
+ UINT16 BbsCount;
+ BBS_TABLE *BbsTable;
+ UINTN Index;
+ CHAR16 DescString[100];
+ UINTN FDNum;
+ UINTN HDNum;
+ UINTN CDNum;
+ UINTN NETNum;
+ UINTN BEVNum;
+
+ NewMenuEntry = NULL;
+ HddInfo = NULL;
+ BbsTable = NULL;
+ BbsCount = 0;
+
+ //
+ // Initialize Bbs Table Context from BBS info data
+ //
+ InitializeListHead (&LegacyFDMenu.Head);
+ InitializeListHead (&LegacyHDMenu.Head);
+ InitializeListHead (&LegacyCDMenu.Head);
+ InitializeListHead (&LegacyNETMenu.Head);
+ InitializeListHead (&LegacyBEVMenu.Head);
+
+ Status = gBS->LocateProtocol (
+ &gEfiLegacyBiosProtocolGuid,
+ NULL,
+ (VOID **) &LegacyBios
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = LegacyBios->GetBbsInfo (
+ LegacyBios,
+ &HddCount,
+ &HddInfo,
+ &BbsCount,
+ &BbsTable
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ FDNum = 0;
+ HDNum = 0;
+ CDNum = 0;
+ NETNum = 0;
+ BEVNum = 0;
+
+ for (Index = 0; Index < BbsCount; Index++) {
+ if ((BBS_IGNORE_ENTRY == BbsTable[Index].BootPriority) ||
+ (BBS_DO_NOT_BOOT_FROM == BbsTable[Index].BootPriority)
+ ) {
+ continue;
+ }
+
+ NewMenuEntry = BOpt_CreateMenuEntry (BM_LEGACY_DEV_CONTEXT_SELECT);
+ if (NULL == NewMenuEntry) {
+ break;
+ }
+
+ NewLegacyDevContext = (BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext;
+ NewLegacyDevContext->BbsTable = &BbsTable[Index];
+ NewLegacyDevContext->Index = Index;
+ NewLegacyDevContext->BbsCount = BbsCount;
+ BdsBuildLegacyDevNameString (
+ &BbsTable[Index],
+ Index,
+ sizeof (DescString),
+ DescString
+ );
+ NewLegacyDevContext->Description = EfiAllocateZeroPool (StrSize (DescString));
+ if (NULL == NewLegacyDevContext->Description) {
+ break;
+ }
+
+ CopyMem (NewLegacyDevContext->Description, DescString, StrSize (DescString));
+ NewMenuEntry->DisplayString = NewLegacyDevContext->Description;
+ NewMenuEntry->HelpString = NULL;
+
+ switch (BbsTable[Index].DeviceType) {
+ case BBS_FLOPPY:
+ InsertTailList (&LegacyFDMenu.Head, &NewMenuEntry->Link);
+ FDNum++;
+ break;
+
+ case BBS_HARDDISK:
+ InsertTailList (&LegacyHDMenu.Head, &NewMenuEntry->Link);
+ HDNum++;
+ break;
+
+ case BBS_CDROM:
+ InsertTailList (&LegacyCDMenu.Head, &NewMenuEntry->Link);
+ CDNum++;
+ break;
+
+ case BBS_EMBED_NETWORK:
+ InsertTailList (&LegacyNETMenu.Head, &NewMenuEntry->Link);
+ NETNum++;
+ break;
+
+ case BBS_BEV_DEVICE:
+ InsertTailList (&LegacyBEVMenu.Head, &NewMenuEntry->Link);
+ BEVNum++;
+ break;
+ }
+ }
+
+ if (Index != BbsCount) {
+ BOpt_FreeLegacyOptions ();
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ LegacyFDMenu.MenuNumber = FDNum;
+ LegacyHDMenu.MenuNumber = HDNum;
+ LegacyCDMenu.MenuNumber = CDNum;
+ LegacyNETMenu.MenuNumber = NETNum;
+ LegacyBEVMenu.MenuNumber = BEVNum;
+ return EFI_SUCCESS;
+}
+
+VOID
+BOpt_FreeLegacyOptions (
+ VOID
+ )
+{
+ BOpt_FreeMenu (&LegacyFDMenu);
+ BOpt_FreeMenu (&LegacyHDMenu);
+ BOpt_FreeMenu (&LegacyCDMenu);
+ BOpt_FreeMenu (&LegacyNETMenu);
+ BOpt_FreeMenu (&LegacyBEVMenu);
+}
+
+EFI_STATUS
+BOpt_GetBootOptions (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+/*++
+
+Routine Description:
+
+ Build the BootOptionMenu according to BootOrder Variable.
+ This Routine will access the Boot#### to get EFI_LOAD_OPTION
+
+Arguments:
+ None
+
+Returns:
+ The number of the Var Boot####
+
+--*/
+{
+ UINTN Index;
+ UINT16 BootString[10];
+ UINT8 *LoadOptionFromVar;
+ UINT8 *LoadOption;
+ UINTN BootOptionSize;
+ BOOLEAN BootNextFlag;
+ UINT16 *BootOrderList;
+ UINTN BootOrderListSize;
+ UINT16 *BootNext;
+ UINTN BootNextSize;
+ BM_MENU_ENTRY *NewMenuEntry;
+ BM_LOAD_CONTEXT *NewLoadContext;
+ UINT8 *LoadOptionPtr;
+ UINTN StringSize;
+ UINTN OptionalDataSize;
+ UINT8 *LoadOptionEnd;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ UINTN MenuCount;
+ UINT8 *Ptr;
+
+ MenuCount = 0;
+ BootOrderListSize = 0;
+ BootNextSize = 0;
+ BootOrderList = NULL;
+ BootNext = NULL;
+ LoadOptionFromVar = NULL;
+ BOpt_FreeMenu (&BootOptionMenu);
+ InitializeListHead (&BootOptionMenu.Head);
+
+ //
+ // Get the BootOrder from the Var
+ //
+ BootOrderList = BdsLibGetVariableAndSize (
+ L"BootOrder",
+ &gEfiGlobalVariableGuid,
+ &BootOrderListSize
+ );
+
+ //
+ // Get the BootNext from the Var
+ //
+ BootNext = BdsLibGetVariableAndSize (
+ L"BootNext",
+ &gEfiGlobalVariableGuid,
+ &BootNextSize
+ );
+
+ if (BootNext) {
+ if (BootNextSize != sizeof (UINT16)) {
+ SafeFreePool (BootNext);
+ BootNext = NULL;
+ }
+ }
+
+ for (Index = 0; Index < BootOrderListSize / sizeof (UINT16); Index++) {
+ UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", BootOrderList[Index]);
+ //
+ // Get all loadoptions from the VAR
+ //
+ LoadOptionFromVar = BdsLibGetVariableAndSize (
+ BootString,
+ &gEfiGlobalVariableGuid,
+ &BootOptionSize
+ );
+ if (!LoadOptionFromVar) {
+ continue;
+ }
+
+ LoadOption = EfiAllocateZeroPool (BootOptionSize);
+ if (!LoadOption) {
+ continue;
+ }
+
+ CopyMem (LoadOption, LoadOptionFromVar, BootOptionSize);
+ SafeFreePool (LoadOptionFromVar);
+
+ if (BootNext) {
+ BootNextFlag = (BOOLEAN) (*BootNext == BootOrderList[Index]);
+ } else {
+ BootNextFlag = FALSE;
+ }
+
+ if (0 == (*((UINT32 *) LoadOption) & LOAD_OPTION_ACTIVE)) {
+ SafeFreePool (LoadOption);
+ continue;
+ }
+ //
+ // BUGBUG: could not return EFI_OUT_OF_RESOURCES here directly.
+ // the buffer allocated already should be freed before returning.
+ //
+ NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);
+ if (NULL == NewMenuEntry) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
+
+ LoadOptionPtr = LoadOption;
+ LoadOptionEnd = LoadOption + BootOptionSize;
+
+ NewMenuEntry->OptionNumber = BootOrderList[Index];
+ NewLoadContext->LoadOptionModified = FALSE;
+ NewLoadContext->Deleted = FALSE;
+ NewLoadContext->IsBootNext = BootNextFlag;
+
+ //
+ // Is a Legacy Device?
+ //
+ Ptr = (UINT8 *) LoadOption;
+
+ //
+ // Attribute = *(UINT32 *)Ptr;
+ //
+ Ptr += sizeof (UINT32);
+
+ //
+ // FilePathSize = *(UINT16 *)Ptr;
+ //
+ Ptr += sizeof (UINT16);
+
+ //
+ // Description = (CHAR16 *)Ptr;
+ //
+ Ptr += StrSize ((CHAR16 *) Ptr);
+
+ //
+ // Now Ptr point to Device Path
+ //
+ DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
+ if ((BBS_DEVICE_PATH == DevicePath->Type) && (BBS_BBS_DP == DevicePath->SubType)) {
+ NewLoadContext->IsLegacy = TRUE;
+ } else {
+ NewLoadContext->IsLegacy = FALSE;
+ }
+ //
+ // LoadOption is a pointer type of UINT8
+ // for easy use with following LOAD_OPTION
+ // embedded in this struct
+ //
+ NewLoadContext->LoadOption = LoadOption;
+ NewLoadContext->LoadOptionSize = BootOptionSize;
+
+ NewLoadContext->Attributes = *(UINT32 *) LoadOptionPtr;
+ NewLoadContext->IsActive = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_ACTIVE);
+
+ NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT);
+
+ LoadOptionPtr += sizeof (UINT32);
+
+ NewLoadContext->FilePathListLength = *(UINT16 *) LoadOptionPtr;
+ LoadOptionPtr += sizeof (UINT16);
+
+ StringSize = StrSize ((UINT16 *) LoadOptionPtr);
+ NewLoadContext->Description = EfiAllocateZeroPool (StringSize);
+ ASSERT (NewLoadContext->Description != NULL);
+ CopyMem (
+ NewLoadContext->Description,
+ (UINT16 *) LoadOptionPtr,
+ StringSize
+ );
+ NewMenuEntry->DisplayString = NewLoadContext->Description;
+
+ LoadOptionPtr += StringSize;
+
+ NewLoadContext->FilePathList = EfiAllocateZeroPool (NewLoadContext->FilePathListLength);
+ ASSERT (NewLoadContext->FilePathList != NULL);
+ CopyMem (
+ NewLoadContext->FilePathList,
+ (EFI_DEVICE_PATH_PROTOCOL *) LoadOptionPtr,
+ NewLoadContext->FilePathListLength
+ );
+
+ NewMenuEntry->HelpString = DevicePathToStr (NewLoadContext->FilePathList);
+ NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository (
+ CallbackData,
+ BootOptionStrDepository
+ );
+ NewMenuEntry->HelpStringToken = GetStringTokenFromDepository (
+ CallbackData,
+ BootOptionHelpStrDepository
+ );
+ LoadOptionPtr += NewLoadContext->FilePathListLength;
+
+ if (LoadOptionPtr < LoadOptionEnd) {
+ OptionalDataSize = BootOptionSize -
+ sizeof (UINT32) -
+ sizeof (UINT16) -
+ StringSize -
+ NewLoadContext->FilePathListLength;
+
+ NewLoadContext->OptionalData = EfiAllocateZeroPool (OptionalDataSize);
+ ASSERT (NewLoadContext->OptionalData != NULL);
+ CopyMem (
+ NewLoadContext->OptionalData,
+ LoadOptionPtr,
+ OptionalDataSize
+ );
+
+ NewLoadContext->OptionalDataSize = OptionalDataSize;
+ }
+
+ InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link);
+ MenuCount++;
+ }
+
+ SafeFreePool (BootNext);
+ SafeFreePool (BootOrderList);
+ BootOptionMenu.MenuNumber = MenuCount;
+ return MenuCount;
+}
+
+CHAR16 *
+BOpt_AppendFileName (
+ IN CHAR16 *Str1,
+ IN CHAR16 *Str2
+ )
+/*++
+
+Routine Description
+ Append file name to existing file name.
+
+Arguments:
+ Str1 - existing file name
+ Str2 - file name to be appended
+
+Returns:
+ Allocate a new string to hold the appended result.
+ Caller is responsible to free the returned string.
+
+--*/
+{
+ UINTN Size1;
+ UINTN Size2;
+ CHAR16 *Str;
+ CHAR16 *Ptr;
+ CHAR16 *LastSlash;
+
+ Size1 = StrSize (Str1);
+ Size2 = StrSize (Str2);
+ Str = EfiAllocateZeroPool (Size1 + Size2 + sizeof (CHAR16));
+ ASSERT (Str != NULL);
+
+ StrCat (Str, Str1);
+ if (!((*Str == '\\') && (*(Str + 1) == 0))) {
+ StrCat (Str, L"\\");
+ }
+
+ StrCat (Str, Str2);
+
+ Ptr = Str;
+ LastSlash = Str;
+ while (*Ptr != 0) {
+ if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '.' && *(Ptr + 3) != 0) {
+ //
+ // Convert \Name\..\ to \
+ // DO NOT convert the .. if it is at the end of the string. This will
+ // break the .. behavior in changing directories.
+ //
+ StrCpy (LastSlash, Ptr + 3);
+ Ptr = LastSlash;
+ } else if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '\\') {
+ //
+ // Convert a \.\ to a \
+ //
+ StrCpy (Ptr, Ptr + 2);
+ Ptr = LastSlash;
+ } else if (*Ptr == '\\') {
+ LastSlash = Ptr;
+ }
+
+ Ptr++;
+ }
+
+ return Str;
+}
+
+BOOLEAN
+BOpt_IsEfiImageName (
+ IN UINT16 *FileName
+ )
+/*++
+
+Routine Description
+ Check whether current FileName point to a valid
+ Efi Image File.
+
+Arguments:
+ FileName - File need to be checked.
+
+Returns:
+ TRUE - Is Efi Image
+ FALSE - Not a valid Efi Image
+
+--*/
+{
+ //
+ // Search for ".efi" extension
+ //
+ while (*FileName) {
+ if (FileName[0] == '.') {
+ if (FileName[1] == 'e' || FileName[1] == 'E') {
+ if (FileName[2] == 'f' || FileName[2] == 'F') {
+ if (FileName[3] == 'i' || FileName[3] == 'I') {
+ return TRUE;
+ } else if (FileName[3] == 0x0000) {
+ return FALSE;
+ }
+ } else if (FileName[2] == 0x0000) {
+ return FALSE;
+ }
+ } else if (FileName[1] == 0x0000) {
+ return FALSE;
+ }
+ }
+
+ FileName += 1;
+ }
+
+ return FALSE;
+}
+
+BOOLEAN
+BOpt_IsEfiApp (
+ IN EFI_FILE_HANDLE Dir,
+ IN UINT16 *FileName
+ )
+/*++
+
+Routine Description:
+ Check whether current FileName point to a valid Efi Application
+
+Arguments:
+ Dir - Pointer to current Directory
+ FileName - Pointer to current File name.
+
+Returns:
+ TRUE - Is a valid Efi Application
+ FALSE - not a valid Efi Application
+
+--*/
+{
+ UINTN BufferSize;
+ EFI_IMAGE_DOS_HEADER DosHdr;
+ EFI_IMAGE_NT_HEADERS PeHdr;
+ EFI_IMAGE_OPTIONAL_HEADER32 *PeOpt32;
+ EFI_IMAGE_OPTIONAL_HEADER64 *PeOpt64;
+ UINT16 Subsystem;
+ EFI_FILE_HANDLE File;
+ EFI_STATUS Status;
+
+ Status = Dir->Open (Dir, &File, FileName, EFI_FILE_MODE_READ, 0);
+
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ BufferSize = sizeof (EFI_IMAGE_DOS_HEADER);
+ File->Read (File, &BufferSize, &DosHdr);
+ if (DosHdr.e_magic != EFI_IMAGE_DOS_SIGNATURE) {
+ File->Close (File);
+ return FALSE;
+ }
+
+ File->SetPosition (File, DosHdr.e_lfanew);
+ BufferSize = sizeof (EFI_IMAGE_NT_HEADERS);
+ File->Read (File, &BufferSize, &PeHdr);
+ if (PeHdr.Signature != EFI_IMAGE_NT_SIGNATURE) {
+ File->Close (File);
+ return FALSE;
+ }
+ //
+ // Determine PE type and read subsytem
+ // BugBug : We should be using EFI_IMAGE_MACHINE_TYPE_SUPPORTED (machine)
+ // macro to detect the machine type.
+ // We should not be using EFI_IMAGE_OPTIONAL_HEADER32 and
+ // EFI_IMAGE_OPTIONAL_HEADER64
+ //
+ if (PeHdr.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ PeOpt32 = (EFI_IMAGE_OPTIONAL_HEADER32 *) &(PeHdr.OptionalHeader);
+ Subsystem = PeOpt32->Subsystem;
+ } else if (PeHdr.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+ PeOpt64 = (EFI_IMAGE_OPTIONAL_HEADER64 *) &(PeHdr.OptionalHeader);
+ Subsystem = PeOpt64->Subsystem;
+ } else {
+ return FALSE;
+ }
+
+ if (Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {
+ File->Close (File);
+ return TRUE;
+ } else {
+ File->Close (File);
+ return FALSE;
+ }
+}
+
+EFI_STATUS
+BOpt_FindDrivers (
+ VOID
+ )
+/*++
+
+Routine Description
+ Find drivers that will be added as Driver#### variables from handles
+ in current system environment
+ All valid handles in the system except those consume SimpleFs, LoadFile
+ are stored in DriverMenu for future use.
+
+Arguments:
+ None
+
+Returns:
+ EFI_SUCCESS
+ Others
+
+--*/
+{
+ UINTN NoDevicePathHandles;
+ EFI_HANDLE *DevicePathHandle;
+ UINTN Index;
+ EFI_STATUS Status;
+ BM_MENU_ENTRY *NewMenuEntry;
+ BM_HANDLE_CONTEXT *NewHandleContext;
+ EFI_HANDLE CurHandle;
+ UINTN OptionNumber;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFs;
+ EFI_LOAD_FILE_PROTOCOL *LoadFile;
+
+ SimpleFs = NULL;
+ LoadFile = NULL;
+
+ InitializeListHead (&DriverMenu.Head);
+
+ //
+ // At first, get all handles that support Device Path
+ // protocol which is the basic requirement for
+ // Driver####
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiDevicePathProtocolGuid,
+ NULL,
+ &NoDevicePathHandles,
+ &DevicePathHandle
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ OptionNumber = 0;
+ for (Index = 0; Index < NoDevicePathHandles; Index++) {
+ CurHandle = DevicePathHandle[Index];
+
+ //
+ // Check whether this handle support
+ // driver binding
+ //
+ Status = gBS->HandleProtocol (
+ CurHandle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ (VOID **) &SimpleFs
+ );
+ if (Status == EFI_SUCCESS) {
+ continue;
+ }
+
+ Status = gBS->HandleProtocol (
+ CurHandle,
+ &gEfiLoadFileProtocolGuid,
+ (VOID **) &LoadFile
+ );
+ if (Status == EFI_SUCCESS) {
+ continue;
+ }
+
+ NewMenuEntry = BOpt_CreateMenuEntry (BM_HANDLE_CONTEXT_SELECT);
+ if (NULL == NewMenuEntry) {
+ SafeFreePool (DevicePathHandle);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NewHandleContext = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;
+ NewHandleContext->Handle = CurHandle;
+ NewHandleContext->DevicePath = DevicePathFromHandle (CurHandle);
+ NewMenuEntry->DisplayString = DevicePathToStr (NewHandleContext->DevicePath);
+ NewMenuEntry->HelpString = NULL;
+ NewMenuEntry->OptionNumber = OptionNumber;
+ OptionNumber++;
+ InsertTailList (&DriverMenu.Head, &NewMenuEntry->Link);
+
+ }
+ SafeFreePool (DevicePathHandle);
+
+ DriverMenu.MenuNumber = OptionNumber;
+ return EFI_SUCCESS;
+}
+
+UINT16
+BOpt_GetBootOptionNumber (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Get the Option Number that does not used
+
+Arguments:
+
+Returns:
+ The Option Number
+
+--*/
+{
+ BM_MENU_ENTRY *NewMenuEntry;
+ UINT16 *BootOrderList;
+ UINTN BootOrderListSize;
+ UINT16 Number;
+ UINTN Index;
+ UINTN Index2;
+ BOOLEAN Found;
+ CHAR16 StrTemp[100];
+ UINT16 *OptionBuffer;
+ UINTN OptionSize;
+
+ BootOrderListSize = 0;
+ BootOrderList = NULL;
+
+ BootOrderList = BdsLibGetVariableAndSize (
+ L"BootOrder",
+ &gEfiGlobalVariableGuid,
+ &BootOrderListSize
+ );
+ if (BootOrderList) {
+ //
+ // already have Boot####
+ //
+ // AlreadyBootNumbers = BootOrderListSize / sizeof(UINT16);
+ //
+ for (Index = 0; Index < BootOrderListSize / sizeof (UINT16); Index++) {
+ Found = TRUE;
+ for (Index2 = 0; Index2 < BootOptionMenu.MenuNumber; Index2++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index2);
+ if (Index == NewMenuEntry->OptionNumber) {
+ Found = FALSE;
+ break;
+ }
+ }
+
+ if (Found) {
+ UnicodeSPrint (StrTemp, 100, L"Boot%04x", Index);
+ DEBUG((DEBUG_ERROR,"INdex= %s\n", StrTemp));
+ OptionBuffer = BdsLibGetVariableAndSize (
+ StrTemp,
+ &gEfiGlobalVariableGuid,
+ &OptionSize
+ );
+ if (NULL == OptionBuffer)
+ break;
+ }
+ }
+ //
+ // end for Index
+ //
+ Number = (UINT16) Index;
+ } else {
+ //
+ // No Boot####
+ //
+ Number = 0;
+ }
+
+ return Number;
+}
+
+UINT16
+BOpt_GetDriverOptionNumber (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Get the Option Number that does not used
+
+Arguments:
+
+Returns:
+ The Option Number
+
+--*/
+{
+ BM_MENU_ENTRY *NewMenuEntry;
+ UINT16 *DriverOrderList;
+ UINTN DriverOrderListSize;
+ UINT16 Number;
+ UINTN Index;
+ UINTN Index2;
+ BOOLEAN Found;
+
+ DriverOrderListSize = 0;
+ DriverOrderList = NULL;
+
+ DriverOrderList = BdsLibGetVariableAndSize (
+ L"DriverOrder",
+ &gEfiGlobalVariableGuid,
+ &DriverOrderListSize
+ );
+ if (DriverOrderList) {
+ //
+ // already have Driver####
+ //
+ // AlreadyDriverNumbers = DriverOrderListSize / sizeof(UINT16);
+ //
+ for (Index = 0; Index < DriverOrderListSize / sizeof (UINT16); Index++) {
+ Found = TRUE;
+ for (Index2 = 0; Index2 < DriverOptionMenu.MenuNumber; Index2++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index2);
+ if (Index == NewMenuEntry->OptionNumber) {
+ Found = FALSE;
+ break;
+ }
+ }
+
+ if (Found) {
+ break;
+ }
+ }
+ //
+ // end for Index
+ //
+ Number = (UINT16) Index;
+ } else {
+ //
+ // No Driver####
+ //
+ Number = 0;
+ }
+
+ return Number;
+}
+
+EFI_STATUS
+BOpt_GetDriverOptions (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+/*++
+
+Routine Description:
+ Build up all DriverOptionMenu
+
+Arguments:
+
+Returns:
+ The Option Number
+
+--*/
+{
+ UINTN Index;
+ UINT16 DriverString[12];
+ UINT8 *LoadOptionFromVar;
+ UINT8 *LoadOption;
+ UINTN DriverOptionSize;
+
+ UINT16 *DriverOrderList;
+ UINTN DriverOrderListSize;
+ BM_MENU_ENTRY *NewMenuEntry;
+ BM_LOAD_CONTEXT *NewLoadContext;
+ UINT8 *LoadOptionPtr;
+ UINTN StringSize;
+ UINTN OptionalDataSize;
+ UINT8 *LoadOptionEnd;
+
+ DriverOrderListSize = 0;
+ DriverOrderList = NULL;
+ DriverOptionSize = 0;
+ LoadOptionFromVar = NULL;
+ BOpt_FreeMenu (&DriverOptionMenu);
+ InitializeListHead (&DriverOptionMenu.Head);
+ //
+ // Get the DriverOrder from the Var
+ //
+ DriverOrderList = BdsLibGetVariableAndSize (
+ L"DriverOrder",
+ &gEfiGlobalVariableGuid,
+ &DriverOrderListSize
+ );
+
+ for (Index = 0; Index < DriverOrderListSize / sizeof (UINT16); Index++) {
+ UnicodeSPrint (
+ DriverString,
+ sizeof (DriverString),
+ L"Driver%04x",
+ DriverOrderList[Index]
+ );
+ //
+ // Get all loadoptions from the VAR
+ //
+ LoadOptionFromVar = BdsLibGetVariableAndSize (
+ DriverString,
+ &gEfiGlobalVariableGuid,
+ &DriverOptionSize
+ );
+ if (!LoadOptionFromVar) {
+ continue;
+ }
+
+ LoadOption = EfiAllocateZeroPool (DriverOptionSize);
+ if (!LoadOption) {
+ continue;
+ }
+
+ CopyMem (LoadOption, LoadOptionFromVar, DriverOptionSize);
+ SafeFreePool (LoadOptionFromVar);
+
+ NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);
+ if (NULL == NewMenuEntry) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
+ LoadOptionPtr = LoadOption;
+ LoadOptionEnd = LoadOption + DriverOptionSize;
+ NewMenuEntry->OptionNumber = DriverOrderList[Index];
+ NewLoadContext->LoadOptionModified = FALSE;
+ NewLoadContext->Deleted = FALSE;
+ NewLoadContext->IsLegacy = FALSE;
+
+ //
+ // LoadOption is a pointer type of UINT8
+ // for easy use with following LOAD_OPTION
+ // embedded in this struct
+ //
+ NewLoadContext->LoadOption = LoadOption;
+ NewLoadContext->LoadOptionSize = DriverOptionSize;
+
+ NewLoadContext->Attributes = *(UINT32 *) LoadOptionPtr;
+ NewLoadContext->IsActive = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_ACTIVE);
+
+ NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT);
+
+ LoadOptionPtr += sizeof (UINT32);
+
+ NewLoadContext->FilePathListLength = *(UINT16 *) LoadOptionPtr;
+ LoadOptionPtr += sizeof (UINT16);
+
+ StringSize = StrSize ((UINT16 *) LoadOptionPtr);
+ NewLoadContext->Description = EfiAllocateZeroPool (StringSize);
+ ASSERT (NewLoadContext->Description != NULL);
+ CopyMem (
+ NewLoadContext->Description,
+ (UINT16 *) LoadOptionPtr,
+ StringSize
+ );
+ NewMenuEntry->DisplayString = NewLoadContext->Description;
+
+ LoadOptionPtr += StringSize;
+
+ NewLoadContext->FilePathList = EfiAllocateZeroPool (NewLoadContext->FilePathListLength);
+ ASSERT (NewLoadContext->FilePathList != NULL);
+ CopyMem (
+ NewLoadContext->FilePathList,
+ (EFI_DEVICE_PATH_PROTOCOL *) LoadOptionPtr,
+ NewLoadContext->FilePathListLength
+ );
+
+ NewMenuEntry->HelpString = DevicePathToStr (NewLoadContext->FilePathList);
+ NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository (
+ CallbackData,
+ DriverOptionStrDepository
+ );
+ NewMenuEntry->HelpStringToken = GetStringTokenFromDepository (
+ CallbackData,
+ DriverOptionHelpStrDepository
+ );
+ LoadOptionPtr += NewLoadContext->FilePathListLength;
+
+ if (LoadOptionPtr < LoadOptionEnd) {
+ OptionalDataSize = DriverOptionSize -
+ sizeof (UINT32) -
+ sizeof (UINT16) -
+ StringSize -
+ NewLoadContext->FilePathListLength;
+
+ NewLoadContext->OptionalData = EfiAllocateZeroPool (OptionalDataSize);
+ ASSERT (NewLoadContext->OptionalData != NULL);
+ CopyMem (
+ NewLoadContext->OptionalData,
+ LoadOptionPtr,
+ OptionalDataSize
+ );
+
+ NewLoadContext->OptionalDataSize = OptionalDataSize;
+ }
+
+ InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link);
+
+ }
+
+ SafeFreePool (DriverOrderList);
+ DriverOptionMenu.MenuNumber = Index;
+ return EFI_SUCCESS;
+
+}
+
diff --git a/MdeModulePkg/Universal/BdsDxe/BootMaint/ConsoleOption.c b/MdeModulePkg/Universal/BdsDxe/BootMaint/ConsoleOption.c new file mode 100644 index 0000000000..7239e6f679 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/BootMaint/ConsoleOption.c @@ -0,0 +1,992 @@ +/*++
+Copyright (c) 2004 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ consoleoption.c
+
+Abstract:
+
+ handles console redirection from boot manager
+
+
+Revision History
+
+--*/
+
+#include "BootMaint.h"
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevicePathInstanceDup (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevPath
+ );
+
+EFI_STATUS
+UpdateComAttributeFromVariable (
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+EFI_STATUS
+ChangeTerminalDevicePath (
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ 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);
+ if (NULL == NewMenuEntry) {
+ return EFI_NOT_FOUND;
+ }
+
+ 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;
+
+}
+
+VOID
+ChangeVariableDevicePath (
+ 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);
+ }
+
+ return ;
+}
+
+BOOLEAN
+RetrieveUartUid (
+ IN EFI_HANDLE Handle,
+ IN OUT UINT32 *AcpiUid
+ )
+/*++
+
+Routine Description:
+ Retrieve ACPI UID of UART from device path
+
+Arguments:
+ Handles - EFI_SERIAL_IO_PROTOCOL handle
+
+Returns:
+ TRUE - Find valid UID from device path
+ FALSE - Can't find
+
+--*/
+{
+ 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;
+ }
+}
+
+VOID
+SortedUartHandle (
+ IN EFI_HANDLE *Handles,
+ IN UINTN NoHandles
+ )
+/*++
+
+Routine Description:
+ Sort Uart handles array with Acpi->UID from low to high
+
+Arguments:
+ Handles - EFI_SERIAL_IO_PROTOCOL handle buffer
+ NoHandles - EFI_SERIAL_IO_PROTOCOL handle count
+
+Returns:
+ None
+
+--*/
+{
+ 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;
+ }
+}
+
+BOOLEAN
+IsTerminalDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ OUT TYPE_OF_TERMINAL *Termi,
+ OUT UINTN *Com
+ );
+
+EFI_STATUS
+LocateSerialIo (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Build a list containing all serial devices
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ 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) {
+ SafeFreePool (Handles);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
+ CopyMem (&NewMenuEntry->OptionNumber, &Acpi->UID, sizeof (UINT32));
+ NewTerminalContext->DevicePath = DevicePathInstanceDup (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++;
+ }
+ }
+ SafeFreePool (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) {
+ UpdateComAttributeFromVariable (OutDevicePath);
+ }
+
+ if (InpDevicePath) {
+ UpdateComAttributeFromVariable (InpDevicePath);
+ }
+
+ if (ErrDevicePath) {
+ 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, &Guid[Index2], sizeof (EFI_GUID));
+ SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH));
+ NewDevicePath = AppendDevicePathNode (
+ NewTerminalContext->DevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *) &Vendor
+ );
+ SafeFreePool (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;
+}
+
+EFI_STATUS
+UpdateComAttributeFromVariable (
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+Routine Description:
+ Update Com Ports attributes from DevicePath
+
+Arguments:
+ DevicePath - DevicePath that contains Com ports
+
+Returns:
+
+--*/
+{
+ 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;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevicePathInstanceDup (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevPath
+ )
+/*++
+
+Routine Description:
+ Function creates a device path data structure that identically matches the
+ device path passed in.
+
+Arguments:
+ DevPath - A pointer to a device path data structure.
+
+Returns:
+
+ The new copy of DevPath is created to identically match the input.
+ Otherwise, NULL is returned.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL *NewDevPath;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;
+ EFI_DEVICE_PATH_PROTOCOL *Temp;
+ UINT8 *Ptr;
+ UINTN Size;
+
+ //
+ // get the size of an instance from the input
+ //
+ Temp = DevPath;
+ DevicePathInst = GetNextDevicePathInstance (&Temp, &Size);
+
+ //
+ // Make a copy and set proper end type
+ //
+ NewDevPath = NULL;
+ if (Size) {
+ NewDevPath = EfiAllocateZeroPool (Size);
+ ASSERT (NewDevPath != NULL);
+ }
+
+ if (NewDevPath) {
+ CopyMem (NewDevPath, DevicePathInst, Size);
+ Ptr = (UINT8 *) NewDevPath;
+ Ptr += Size - sizeof (EFI_DEVICE_PATH_PROTOCOL);
+ Temp = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
+ SetDevicePathEndNode (Temp);
+ }
+
+ return NewDevPath;
+}
+
+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 Out Devices
+ //
+ 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 = DevicePathInstanceDup (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;
+}
+
+EFI_STATUS
+GetAllConsoles (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Build up ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu
+
+Arguments:
+
+Returns:
+ EFI_SUCCESS
+ Others
+
+--*/
+{
+ GetConsoleMenu (BM_CONSOLE_IN_CONTEXT_SELECT);
+ GetConsoleMenu (BM_CONSOLE_OUT_CONTEXT_SELECT);
+ GetConsoleMenu (BM_CONSOLE_ERR_CONTEXT_SELECT);
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FreeAllConsoles (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Free ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu
+
+Arguments:
+
+Returns:
+ EFI_SUCCESS
+ Others
+
+--*/
+{
+ BOpt_FreeMenu (&ConsoleOutMenu);
+ BOpt_FreeMenu (&ConsoleInpMenu);
+ BOpt_FreeMenu (&ConsoleErrMenu);
+ BOpt_FreeMenu (&TerminalMenu);
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+IsTerminalDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ OUT TYPE_OF_TERMINAL *Termi,
+ OUT UINTN *Com
+ )
+/*++
+
+Routine Description:
+ Test whether DevicePath is a valid Terminal
+
+Arguments:
+ DevicePath - DevicePath to be checked
+ Termi - If is terminal, give its type
+ Com - If is Com Port, give its type
+
+Returns:
+ TRUE - If DevicePath point to a Terminal
+ FALSE
+
+--*/
+{
+ 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, &Guid[0])) {
+ *Termi = PC_ANSI;
+ IsTerminal = TRUE;
+ } else {
+ if (CompareGuid (&TempGuid, &Guid[1])) {
+ *Termi = VT_100;
+ IsTerminal = TRUE;
+ } else {
+ if (CompareGuid (&TempGuid, &Guid[2])) {
+ *Termi = VT_100_PLUS;
+ IsTerminal = TRUE;
+ } else {
+ if (CompareGuid (&TempGuid, &Guid[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;
+}
+
+VOID
+GetConsoleOutMode (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+/*++
+
+Routine Description:
+ Get mode number according to column and row
+
+Arguments:
+ CallbackData - BMM_CALLBACK_DATA
+
+Returns:
+ None.
+
+--*/
+{
+ 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 (VarConOutMode, &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;
+ }
+ }
+ }
+ }
+ SafeFreePool (ModeInfo);
+}
diff --git a/MdeModulePkg/Universal/BdsDxe/BootMaint/Data.c b/MdeModulePkg/Universal/BdsDxe/BootMaint/Data.c new file mode 100644 index 0000000000..598d3c1075 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/BootMaint/Data.c @@ -0,0 +1,324 @@ +/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+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.
+
+Module Name:
+
+ Data.c
+
+Abstract:
+
+ Define some data used for Boot Maint
+
+Revision History
+
+--*/
+
+#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 Guid[4] = {
+ DEVICE_PATH_MESSAGING_PC_ANSI,
+ DEVICE_PATH_MESSAGING_VT_100,
+ DEVICE_PATH_MESSAGING_VT_100_PLUS,
+ DEVICE_PATH_MESSAGING_VT_UTF8
+};
diff --git a/MdeModulePkg/Universal/BdsDxe/BootMaint/FE.vfr b/MdeModulePkg/Universal/BdsDxe/BootMaint/FE.vfr new file mode 100644 index 0000000000..97d432185c --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/BootMaint/FE.vfr @@ -0,0 +1,134 @@ +// *++
+//
+// Copyright (c) 2004 - 2007, Intel Corporation
+// 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.
+//
+// Module Name:
+//
+// FE.vfr
+//
+// Abstract:
+//
+// File Explorer Formset
+//
+// Revision History:
+//
+// --*/
+
+#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;
\ No newline at end of file diff --git a/MdeModulePkg/Universal/BdsDxe/BootMaint/FileExplorer.c b/MdeModulePkg/Universal/BdsDxe/BootMaint/FileExplorer.c new file mode 100644 index 0000000000..811702f1d3 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/BootMaint/FileExplorer.c @@ -0,0 +1,327 @@ +/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ FileExplorer.c
+
+Abstract:
+
+ File explorer related functions.
+
+--*/
+
+#include "BootMaint.h"
+
+VOID
+UpdateFileExplorePage (
+ IN BMM_CALLBACK_DATA *CallbackData,
+ BM_MENU_OPTION *MenuOption
+ )
+/*++
+Routine Description:
+ Update the File Explore page.
+
+Arguments:
+ MenuOption - Pointer to menu options to display.
+
+Returns:
+ None.
+
+--*/
+{
+ 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
+ );
+}
+
+BOOLEAN
+UpdateFileExplorer (
+ IN BMM_CALLBACK_DATA *CallbackData,
+ IN UINT16 KeyValue
+ )
+/*++
+
+Routine Description:
+ Update the file explower page with the refershed file system.
+
+Arguments:
+ CallbackData - BMM context data
+ KeyValue - Key value to identify the type of data to expect.
+
+Returns:
+ TRUE - Inform the caller to create a callback packet to exit file explorer.
+ FALSE - Indicate that there is no need to exit file explorer.
+
+--*/
+{
+ 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;
+}
+
+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
+ )
+/*++
+
+ Routine Description:
+ This function processes the results of changes in configuration.
+
+ Arguments:
+ This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ Action - Specifies the type of action taken by the browser.
+ QuestionId - A unique value which is sent to the original exporting driver
+ so that it can identify the type of data to expect.
+ Type - The type of value for the question.
+ Value - A pointer to the data being sent to the original exporting driver.
+ ActionRequest - On return, points to the action requested by the callback function.
+
+ Returns:
+ EFI_SUCCESS - The callback successfully handled the action.
+ EFI_OUT_OF_RESOURCES - Not enough storage is available to hold the variable and its data.
+ EFI_DEVICE_ERROR - The variable could not be saved.
+ EFI_UNSUPPORTED - The specified Action is not supported by the callback.
+
+--*/
+{
+ 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;
+
+ //
+ // Retrive 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;
+}
diff --git a/MdeModulePkg/Universal/BdsDxe/BootMaint/FormGuid.h b/MdeModulePkg/Universal/BdsDxe/BootMaint/FormGuid.h new file mode 100644 index 0000000000..9c0adf2bba --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/BootMaint/FormGuid.h @@ -0,0 +1,216 @@ +/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+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.
+
+Module Name:
+
+ FormGuid.h
+
+Abstract:
+
+ Formset guids, form id and VarStore data structure for Boot Maintenance Manager.
+
+--*/
+#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
+
diff --git a/MdeModulePkg/Universal/BdsDxe/BootMaint/UpdatePage.c b/MdeModulePkg/Universal/BdsDxe/BootMaint/UpdatePage.c new file mode 100644 index 0000000000..d1608bf528 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/BootMaint/UpdatePage.c @@ -0,0 +1,1211 @@ +/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ UpdatePage.c
+
+Abstract:
+
+ Dynamically Update the pages
+
+--*/
+
+#include "BootMaint.h"
+
+EFI_GUID gTerminalDriverGuid = {
+ 0x10634d8e, 0x1c05, 0x46cb, {0xbb, 0xc, 0x5a, 0xfd, 0xc8, 0x29, 0xa8, 0xc8}
+};
+
+VOID
+RefreshUpdateData (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Refresh the global UpdateData structure.
+
+Arguments:
+ None.
+
+Returns:
+ None.
+
+--*/
+{
+ gUpdateData.Offset = 0;
+}
+
+VOID
+UpdatePageStart (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+{
+ RefreshUpdateData ();
+
+ if (!(CallbackData->BmmAskSaveOrNot)) {
+ //
+ // Add a "Go back to main page" tag in front of the form when there are no
+ // "Apply changes" and "Discard changes" tags in the end of the form.
+ //
+ CreateGotoOpCode (
+ FORM_MAIN_ID,
+ STRING_TOKEN (STR_FORM_GOTO_MAIN),
+ STRING_TOKEN (STR_FORM_GOTO_MAIN),
+ 0,
+ FORM_MAIN_ID,
+ &gUpdateData
+ );
+ }
+
+}
+
+VOID
+UpdatePageEnd (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+{
+ //
+ // Create the "Apply changes" and "Discard changes" tags.
+ //
+ if (CallbackData->BmmAskSaveOrNot) {
+ CreateSubTitleOpCode (
+ STRING_TOKEN (STR_NULL_STRING),
+ 0,
+ 0,
+ 0,
+ &gUpdateData
+ );
+
+ CreateGotoOpCode (
+ FORM_MAIN_ID,
+ STRING_TOKEN (STR_SAVE_AND_EXIT),
+ STRING_TOKEN (STR_NULL_STRING),
+ EFI_IFR_FLAG_CALLBACK,
+ KEY_VALUE_SAVE_AND_EXIT,
+ &gUpdateData
+ );
+ }
+
+ //
+ // Ensure user can return to the main page.
+ //
+ CreateGotoOpCode (
+ FORM_MAIN_ID,
+ STRING_TOKEN (STR_NO_SAVE_AND_EXIT),
+ STRING_TOKEN (STR_NULL_STRING),
+ EFI_IFR_FLAG_CALLBACK,
+ KEY_VALUE_NO_SAVE_AND_EXIT,
+ &gUpdateData
+ );
+
+ IfrLibUpdateForm (
+ CallbackData->BmmHiiHandle,
+ &mBootMaintGuid,
+ CallbackData->BmmCurrentPageId,
+ CallbackData->BmmCurrentPageId,
+ FALSE,
+ &gUpdateData
+ );
+}
+
+VOID
+CleanUpPage (
+ IN UINT16 LabelId,
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+{
+ RefreshUpdateData ();
+
+ //
+ // Remove all op-codes from dynamic page
+ //
+ IfrLibUpdateForm (
+ CallbackData->BmmHiiHandle,
+ &mBootMaintGuid,
+ LabelId,
+ LabelId,
+ FALSE,
+ &gUpdateData
+ );
+}
+
+EFI_STATUS
+BootThisFile (
+ IN BM_FILE_CONTEXT *FileContext
+ )
+{
+ EFI_STATUS Status;
+ UINTN ExitDataSize;
+ CHAR16 *ExitData;
+ BDS_COMMON_OPTION *Option;
+
+ Status = gBS->AllocatePool (EfiBootServicesData, sizeof (BDS_COMMON_OPTION), (VOID **) &Option);
+ Option->Description = FileContext->FileName;
+ Option->DevicePath = FileContext->DevicePath;
+ Option->LoadOptionsSize = 0;
+ Option->LoadOptions = NULL;
+
+ //
+ // Since current no boot from removable media directly is allowed */
+ //
+ gST->ConOut->ClearScreen (gST->ConOut);
+
+ gBS->RaiseTPL (TPL_APPLICATION);
+
+ ExitDataSize = 0;
+
+ Status = BdsLibBootViaBootOption (Option, Option->DevicePath, &ExitDataSize, &ExitData);
+
+ gBS->RestoreTPL (TPL_APPLICATION);
+
+ return Status;
+
+}
+
+VOID
+UpdateConCOMPage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+{
+ BM_MENU_ENTRY *NewMenuEntry;
+ UINT16 Index;
+ EFI_STATUS Status;
+ VOID *Interface;
+
+ CallbackData->BmmAskSaveOrNot = FALSE;
+
+ UpdatePageStart (CallbackData);
+
+ Status = EfiLibLocateProtocol (&gTerminalDriverGuid, (VOID **) &Interface);
+ if (!EFI_ERROR (Status)) {
+ for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
+
+ CreateGotoOpCode (
+ FORM_CON_COM_SETUP_ID,
+ NewMenuEntry->DisplayStringToken,
+ STRING_TOKEN (STR_NULL_STRING),
+ EFI_IFR_FLAG_CALLBACK,
+ (UINT16) (TERMINAL_OPTION_OFFSET + Index),
+ &gUpdateData
+ );
+ }
+ }
+
+ UpdatePageEnd (CallbackData);
+}
+
+VOID
+UpdateBootDelPage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+{
+ BM_MENU_ENTRY *NewMenuEntry;
+ BM_LOAD_CONTEXT *NewLoadContext;
+ UINT16 Index;
+
+ CallbackData->BmmAskSaveOrNot = TRUE;
+
+ UpdatePageStart (CallbackData);
+ CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, &BootOptionMenu);
+
+ for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
+ NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
+ if (NewLoadContext->IsLegacy) {
+ continue;
+ }
+
+ NewLoadContext->Deleted = FALSE;
+ CallbackData->BmmFakeNvData.BootOptionDel[Index] = 0x00;
+
+ CreateCheckBoxOpCode (
+ (EFI_QUESTION_ID) (BOOT_OPTION_DEL_QUESTION_ID + Index),
+ VARSTORE_ID_BOOT_MAINT,
+ (UINT16) (BOOT_OPTION_DEL_VAR_OFFSET + Index),
+ NewMenuEntry->DisplayStringToken,
+ NewMenuEntry->HelpStringToken,
+ 0,
+ 0,
+ &gUpdateData
+ );
+ }
+
+ UpdatePageEnd (CallbackData);
+}
+
+VOID
+UpdateDrvAddHandlePage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+{
+ BM_MENU_ENTRY *NewMenuEntry;
+ UINT16 Index;
+
+ CallbackData->BmmAskSaveOrNot = FALSE;
+
+ UpdatePageStart (CallbackData);
+
+ for (Index = 0; Index < DriverMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index);
+
+ CreateGotoOpCode (
+ FORM_DRV_ADD_HANDLE_DESC_ID,
+ NewMenuEntry->DisplayStringToken,
+ STRING_TOKEN (STR_NULL_STRING),
+ EFI_IFR_FLAG_CALLBACK,
+ (UINT16) (HANDLE_OPTION_OFFSET + Index),
+ &gUpdateData
+ );
+ }
+
+ UpdatePageEnd (CallbackData);
+}
+
+VOID
+UpdateDrvDelPage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+{
+ BM_MENU_ENTRY *NewMenuEntry;
+ BM_LOAD_CONTEXT *NewLoadContext;
+ UINT16 Index;
+
+ CallbackData->BmmAskSaveOrNot = TRUE;
+
+ UpdatePageStart (CallbackData);
+
+ CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, &DriverOptionMenu);
+
+ for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
+
+ NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
+ NewLoadContext->Deleted = FALSE;
+ CallbackData->BmmFakeNvData.DriverOptionDel[Index] = 0x00;
+
+ CreateCheckBoxOpCode (
+ (EFI_QUESTION_ID) (DRIVER_OPTION_DEL_QUESTION_ID + Index),
+ VARSTORE_ID_BOOT_MAINT,
+ (UINT16) (DRIVER_OPTION_DEL_VAR_OFFSET + Index),
+ NewMenuEntry->DisplayStringToken,
+ NewMenuEntry->HelpStringToken,
+ 0,
+ 0,
+ &gUpdateData
+ );
+ }
+
+ UpdatePageEnd (CallbackData);
+}
+
+VOID
+UpdateDriverAddHandleDescPage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+{
+ BM_MENU_ENTRY *NewMenuEntry;
+
+ CallbackData->BmmFakeNvData.DriverAddActive = 0x01;
+ CallbackData->BmmFakeNvData.DriverAddForceReconnect = 0x00;
+ CallbackData->BmmAskSaveOrNot = TRUE;
+ NewMenuEntry = CallbackData->MenuEntry;
+
+ UpdatePageStart (CallbackData);
+
+ CreateSubTitleOpCode (
+ NewMenuEntry->DisplayStringToken,
+ 0,
+ 0,
+ 0,
+ &gUpdateData
+ );
+
+ CreateStringOpCode (
+ (EFI_QUESTION_ID) DRV_ADD_HANDLE_DESC_QUESTION_ID,
+ VARSTORE_ID_BOOT_MAINT,
+ DRV_ADD_HANDLE_DESC_VAR_OFFSET,
+ STRING_TOKEN (STR_LOAD_OPTION_DESC),
+ STRING_TOKEN (STR_NULL_STRING),
+ 0,
+ 0,
+ 6,
+ 75,
+ &gUpdateData
+ );
+
+ CreateCheckBoxOpCode (
+ (EFI_QUESTION_ID) DRV_ADD_RECON_QUESTION_ID,
+ VARSTORE_ID_BOOT_MAINT,
+ DRV_ADD_RECON_VAR_OFFSET,
+ STRING_TOKEN (STR_LOAD_OPTION_FORCE_RECON),
+ STRING_TOKEN (STR_LOAD_OPTION_FORCE_RECON),
+ 0,
+ 0,
+ &gUpdateData
+ );
+
+ CreateStringOpCode (
+ (EFI_QUESTION_ID) DRIVER_ADD_OPTION_QUESTION_ID,
+ VARSTORE_ID_BOOT_MAINT,
+ DRIVER_ADD_OPTION_VAR_OFFSET,
+ STRING_TOKEN (STR_OPTIONAL_DATA),
+ STRING_TOKEN (STR_NULL_STRING),
+ 0,
+ 0,
+ 6,
+ 75,
+ &gUpdateData
+ );
+
+ UpdatePageEnd (CallbackData);
+}
+
+VOID
+UpdateConsolePage (
+ IN UINT16 UpdatePageId,
+ IN BM_MENU_OPTION *ConsoleMenu,
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+{
+ BM_MENU_ENTRY *NewMenuEntry;
+ BM_CONSOLE_CONTEXT *NewConsoleContext;
+ BM_TERMINAL_CONTEXT *NewTerminalContext;
+ UINT16 Index;
+ UINT16 Index2;
+ UINT8 CheckFlags;
+ EFI_STATUS Status;
+ VOID *Interface;
+
+ CallbackData->BmmAskSaveOrNot = TRUE;
+
+ UpdatePageStart (CallbackData);
+
+ for (Index = 0; Index < ConsoleMenu->MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (ConsoleMenu, Index);
+ NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
+ CheckFlags = 0;
+ if (NewConsoleContext->IsActive) {
+ CheckFlags |= EFI_IFR_CHECKBOX_DEFAULT;
+ CallbackData->BmmFakeNvData.ConsoleCheck[Index] = TRUE;
+ } else {
+ CallbackData->BmmFakeNvData.ConsoleCheck[Index] = FALSE;
+ }
+
+ CreateCheckBoxOpCode (
+ (EFI_QUESTION_ID) (CON_DEVICE_QUESTION_ID + Index),
+ VARSTORE_ID_BOOT_MAINT,
+ (UINT16) (CON_DEVICE_VAR_OFFSET + Index),
+ NewMenuEntry->DisplayStringToken,
+ NewMenuEntry->HelpStringToken,
+ 0,
+ CheckFlags,
+ &gUpdateData
+ );
+ }
+
+ Status = EfiLibLocateProtocol (&gTerminalDriverGuid, (VOID **) &Interface);
+ if (!EFI_ERROR (Status)) {
+ for (Index2 = 0; Index2 < TerminalMenu.MenuNumber; Index2++) {
+ CheckFlags = 0;
+ NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index2);
+ NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
+
+ if ((NewTerminalContext->IsConIn && (UpdatePageId == FORM_CON_IN_ID)) ||
+ (NewTerminalContext->IsConOut && (UpdatePageId == FORM_CON_OUT_ID)) ||
+ (NewTerminalContext->IsStdErr && (UpdatePageId == FORM_CON_ERR_ID))
+ ) {
+ CheckFlags |= EFI_IFR_CHECKBOX_DEFAULT;
+ CallbackData->BmmFakeNvData.ConsoleCheck[Index] = TRUE;
+ } else {
+ CallbackData->BmmFakeNvData.ConsoleCheck[Index] = FALSE;
+ }
+
+ CreateCheckBoxOpCode (
+ (EFI_QUESTION_ID) (CON_DEVICE_QUESTION_ID + Index),
+ VARSTORE_ID_BOOT_MAINT,
+ (UINT16) (CON_DEVICE_VAR_OFFSET + Index),
+ NewMenuEntry->DisplayStringToken,
+ NewMenuEntry->HelpStringToken,
+ 0,
+ CheckFlags,
+ &gUpdateData
+ );
+
+ Index++;
+ }
+ }
+
+ UpdatePageEnd (CallbackData);
+}
+
+VOID
+UpdateOrderPage (
+ IN UINT16 UpdatePageId,
+ IN BM_MENU_OPTION *OptionMenu,
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+{
+ BM_MENU_ENTRY *NewMenuEntry;
+ UINT16 Index;
+ IFR_OPTION *IfrOptionList;
+
+ CallbackData->BmmAskSaveOrNot = TRUE;
+
+ UpdatePageStart (CallbackData);
+
+ CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, OptionMenu);
+
+ ZeroMem (CallbackData->BmmFakeNvData.OptionOrder, 100);
+
+ IfrOptionList = EfiAllocateZeroPool (sizeof (IFR_OPTION) * OptionMenu->MenuNumber);
+ if (NULL == IfrOptionList) {
+ return ;
+ }
+
+ for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (OptionMenu, Index);
+ IfrOptionList[Index].StringToken = NewMenuEntry->DisplayStringToken;
+ IfrOptionList[Index].Value.u8 = (UINT8) (NewMenuEntry->OptionNumber + 1);
+ IfrOptionList[Index].Flags = 0;
+ CallbackData->BmmFakeNvData.OptionOrder[Index] = IfrOptionList[Index].Value.u8;
+ }
+
+ if (OptionMenu->MenuNumber > 0) {
+ CreateOrderedListOpCode (
+ (EFI_QUESTION_ID) OPTION_ORDER_QUESTION_ID,
+ VARSTORE_ID_BOOT_MAINT,
+ OPTION_ORDER_VAR_OFFSET,
+ STRING_TOKEN (STR_CHANGE_ORDER),
+ STRING_TOKEN (STR_CHANGE_ORDER),
+ 0,
+ 0,
+ EFI_IFR_NUMERIC_SIZE_1,
+ 100,
+ IfrOptionList,
+ OptionMenu->MenuNumber,
+ &gUpdateData
+ );
+ }
+
+ SafeFreePool (IfrOptionList);
+
+ UpdatePageEnd (CallbackData);
+
+ CopyMem (
+ CallbackData->BmmOldFakeNVData.OptionOrder,
+ CallbackData->BmmFakeNvData.OptionOrder,
+ 100
+ );
+}
+
+VOID
+UpdateBootNextPage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+{
+ BM_MENU_ENTRY *NewMenuEntry;
+ BM_LOAD_CONTEXT *NewLoadContext;
+ IFR_OPTION *IfrOptionList;
+ UINTN NumberOfOptions;
+ UINT16 Index;
+
+ IfrOptionList = NULL;
+ NumberOfOptions = BootOptionMenu.MenuNumber;
+ CallbackData->BmmAskSaveOrNot = TRUE;
+
+ UpdatePageStart (CallbackData);
+ CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, &BootOptionMenu);
+
+ if (NumberOfOptions > 0) {
+ IfrOptionList = EfiAllocateZeroPool ((NumberOfOptions + 1) * sizeof (IFR_OPTION));
+
+ ASSERT (IfrOptionList);
+
+ CallbackData->BmmFakeNvData.BootNext = (UINT16) (BootOptionMenu.MenuNumber);
+
+ for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
+ NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
+ if (NewLoadContext->IsBootNext) {
+ IfrOptionList[Index].Flags = EFI_IFR_OPTION_DEFAULT;
+ CallbackData->BmmFakeNvData.BootNext = Index;
+ } else {
+ IfrOptionList[Index].Flags = 0;
+ }
+
+ IfrOptionList[Index].Value.u16 = Index;
+ IfrOptionList[Index].StringToken = NewMenuEntry->DisplayStringToken;
+ }
+
+ IfrOptionList[Index].Value.u16 = Index;
+ IfrOptionList[Index].StringToken = STRING_TOKEN (STR_NONE);
+ IfrOptionList[Index].Flags = 0;
+ if (CallbackData->BmmFakeNvData.BootNext == Index) {
+ IfrOptionList[Index].Flags |= EFI_IFR_OPTION_DEFAULT;
+ }
+
+ CreateOneOfOpCode (
+ (EFI_QUESTION_ID) BOOT_NEXT_QUESTION_ID,
+ VARSTORE_ID_BOOT_MAINT,
+ BOOT_NEXT_VAR_OFFSET,
+ STRING_TOKEN (STR_BOOT_NEXT),
+ STRING_TOKEN (STR_BOOT_NEXT_HELP),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_2,
+ IfrOptionList,
+ (UINTN) (NumberOfOptions + 1),
+ &gUpdateData
+ );
+
+ SafeFreePool (IfrOptionList);
+ }
+
+ UpdatePageEnd (CallbackData);
+}
+
+VOID
+UpdateTimeOutPage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+{
+ UINT16 BootTimeOut;
+
+ CallbackData->BmmAskSaveOrNot = TRUE;
+
+ UpdatePageStart (CallbackData);
+
+ BootTimeOut = BdsLibGetTimeout ();
+
+ CreateNumericOpCode (
+ (EFI_QUESTION_ID) BOOT_TIME_OUT_QUESTION_ID,
+ VARSTORE_ID_BOOT_MAINT,
+ BOOT_TIME_OUT_VAR_OFFSET,
+ STRING_TOKEN (STR_NUM_AUTO_BOOT),
+ STRING_TOKEN (STR_HLP_AUTO_BOOT),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_2 | EFI_IFR_DISPLAY_UINT_DEC,
+ 0,
+ 65535,
+ 0,
+ BootTimeOut,
+ &gUpdateData
+ );
+
+ CallbackData->BmmFakeNvData.BootTimeOut = BootTimeOut;
+
+ UpdatePageEnd (CallbackData);
+}
+
+VOID
+UpdateConModePage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+/*++
+
+Routine Description:
+ Refresh the text mode page
+
+Arguments:
+ CallbackData - BMM_CALLBACK_DATA
+
+Returns:
+ None.
+
+--*/
+{
+ UINTN Mode;
+ UINTN Index;
+ UINTN Col;
+ UINTN Row;
+ CHAR16 RowString[50];
+ CHAR16 ModeString[50];
+ UINTN MaxMode;
+ UINTN ValidMode;
+ EFI_STRING_ID *ModeToken;
+ IFR_OPTION *IfrOptionList;
+ EFI_STATUS Status;
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;
+
+ ConOut = gST->ConOut;
+ Index = 0;
+ ValidMode = 0;
+ MaxMode = (UINTN) (ConOut->Mode->MaxMode);
+
+ CallbackData->BmmAskSaveOrNot = TRUE;
+
+ UpdatePageStart (CallbackData);
+
+ //
+ // Check valid mode
+ //
+ for (Mode = 0; Mode < MaxMode; Mode++) {
+ Status = ConOut->QueryMode (ConOut, Mode, &Col, &Row);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+ ValidMode++;
+ }
+
+ if (ValidMode == 0) {
+ return;
+ }
+
+ IfrOptionList = EfiAllocateZeroPool (sizeof (IFR_OPTION) * ValidMode);
+ ASSERT(IfrOptionList != NULL);
+
+ ModeToken = EfiAllocateZeroPool (sizeof (EFI_STRING_ID) * ValidMode);
+ ASSERT(ModeToken != NULL);
+
+ //
+ // Determin which mode should be the first entry in menu
+ //
+ GetConsoleOutMode (CallbackData);
+
+ //
+ // Build text mode options
+ //
+ for (Mode = 0; Mode < MaxMode; Mode++) {
+ Status = ConOut->QueryMode (ConOut, Mode, &Col, &Row);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+ //
+ // Build mode string Column x Row
+ //
+ UnicodeValueToString (ModeString, 0, Col, 0);
+ StrCat (ModeString, L" x ");
+ UnicodeValueToString (RowString, 0, Row, 0);
+ StrCat (ModeString, RowString);
+
+ IfrLibNewString (CallbackData->BmmHiiHandle, &ModeToken[Index], ModeString);
+
+ IfrOptionList[Index].StringToken = ModeToken[Index];
+ IfrOptionList[Index].Value.u16 = (UINT16) Mode;
+ if (Mode == CallbackData->BmmFakeNvData.ConsoleOutMode) {
+ IfrOptionList[Index].Flags = EFI_IFR_OPTION_DEFAULT;
+ } else {
+ IfrOptionList[Index].Flags = 0;
+ }
+ Index++;
+ }
+
+ CreateOneOfOpCode (
+ (EFI_QUESTION_ID) CON_MODE_QUESTION_ID,
+ VARSTORE_ID_BOOT_MAINT,
+ CON_MODE_VAR_OFFSET,
+ STRING_TOKEN (STR_CON_MODE_SETUP),
+ STRING_TOKEN (STR_CON_MODE_SETUP),
+ EFI_IFR_FLAG_RESET_REQUIRED,
+ EFI_IFR_NUMERIC_SIZE_2,
+ IfrOptionList,
+ ValidMode,
+ &gUpdateData
+ );
+ SafeFreePool (IfrOptionList);
+ SafeFreePool (ModeToken);
+
+ UpdatePageEnd (CallbackData);
+}
+
+VOID
+UpdateTerminalPage (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+{
+ UINT8 Index;
+ UINT8 CheckFlags;
+ IFR_OPTION *IfrOptionList;
+ BM_MENU_ENTRY *NewMenuEntry;
+ BM_TERMINAL_CONTEXT *NewTerminalContext;
+
+ CallbackData->BmmAskSaveOrNot = TRUE;
+
+ UpdatePageStart (CallbackData);
+
+ NewMenuEntry = BOpt_GetMenuEntry (
+ &TerminalMenu,
+ CallbackData->CurrentTerminal
+ );
+
+ if (NewMenuEntry == NULL) {
+ return ;
+ }
+
+ NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
+
+ IfrOptionList = EfiAllocateZeroPool (sizeof (IFR_OPTION) * 19);
+ if (IfrOptionList == NULL) {
+ return ;
+ }
+
+ for (Index = 0; Index < 19; Index++) {
+ CheckFlags = 0;
+ if (NewTerminalContext->BaudRate == (UINT64) (BaudRateList[Index].Value)) {
+ CheckFlags |= EFI_IFR_OPTION_DEFAULT;
+ NewTerminalContext->BaudRateIndex = Index;
+ CallbackData->BmmFakeNvData.COMBaudRate = NewTerminalContext->BaudRateIndex;
+ }
+
+ IfrOptionList[Index].Flags = CheckFlags;
+ IfrOptionList[Index].StringToken = BaudRateList[Index].StringToken;
+ IfrOptionList[Index].Value.u8 = Index;
+ }
+
+ CreateOneOfOpCode (
+ (EFI_QUESTION_ID) COM_BAUD_RATE_QUESTION_ID,
+ VARSTORE_ID_BOOT_MAINT,
+ COM_BAUD_RATE_VAR_OFFSET,
+ STRING_TOKEN (STR_COM_BAUD_RATE),
+ STRING_TOKEN (STR_COM_BAUD_RATE),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_1,
+ IfrOptionList,
+ 19,
+ &gUpdateData
+ );
+
+ for (Index = 0; Index < 4; Index++) {
+ CheckFlags = 0;
+
+ if (NewTerminalContext->DataBits == DataBitsList[Index].Value) {
+ NewTerminalContext->DataBitsIndex = Index;
+ CallbackData->BmmFakeNvData.COMDataRate = NewTerminalContext->DataBitsIndex;
+ CheckFlags |= EFI_IFR_OPTION_DEFAULT;
+ }
+
+ IfrOptionList[Index].Flags = CheckFlags;
+ IfrOptionList[Index].StringToken = DataBitsList[Index].StringToken;
+ IfrOptionList[Index].Value.u8 = Index;
+ }
+
+ CreateOneOfOpCode (
+ (EFI_QUESTION_ID) COM_DATA_RATE_QUESTION_ID,
+ VARSTORE_ID_BOOT_MAINT,
+ COM_DATA_RATE_VAR_OFFSET,
+ STRING_TOKEN (STR_COM_DATA_BITS),
+ STRING_TOKEN (STR_COM_DATA_BITS),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_1,
+ IfrOptionList,
+ 4,
+ &gUpdateData
+ );
+
+ for (Index = 0; Index < 5; Index++) {
+ CheckFlags = 0;
+ if (NewTerminalContext->Parity == ParityList[Index].Value) {
+ CheckFlags |= EFI_IFR_OPTION_DEFAULT;
+ NewTerminalContext->ParityIndex = (UINT8) Index;
+ CallbackData->BmmFakeNvData.COMParity = NewTerminalContext->ParityIndex;
+ }
+
+ IfrOptionList[Index].Flags = CheckFlags;
+ IfrOptionList[Index].StringToken = ParityList[Index].StringToken;
+ IfrOptionList[Index].Value.u8 = Index;
+ }
+
+ CreateOneOfOpCode (
+ (EFI_QUESTION_ID) COM_PARITY_QUESTION_ID,
+ VARSTORE_ID_BOOT_MAINT,
+ COM_PARITY_VAR_OFFSET,
+ STRING_TOKEN (STR_COM_PARITY),
+ STRING_TOKEN (STR_COM_PARITY),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_1,
+ IfrOptionList,
+ 5,
+ &gUpdateData
+ );
+
+ for (Index = 0; Index < 3; Index++) {
+ CheckFlags = 0;
+ if (NewTerminalContext->StopBits == StopBitsList[Index].Value) {
+ CheckFlags |= EFI_IFR_OPTION_DEFAULT;
+ NewTerminalContext->StopBitsIndex = (UINT8) Index;
+ CallbackData->BmmFakeNvData.COMStopBits = NewTerminalContext->StopBitsIndex;
+ }
+
+ IfrOptionList[Index].Flags = CheckFlags;
+ IfrOptionList[Index].StringToken = StopBitsList[Index].StringToken;
+ IfrOptionList[Index].Value.u8 = Index;
+ }
+
+ CreateOneOfOpCode (
+ (EFI_QUESTION_ID) COM_STOP_BITS_QUESTION_ID,
+ VARSTORE_ID_BOOT_MAINT,
+ COM_STOP_BITS_VAR_OFFSET,
+ STRING_TOKEN (STR_COM_STOP_BITS),
+ STRING_TOKEN (STR_COM_STOP_BITS),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_1,
+ IfrOptionList,
+ 3,
+ &gUpdateData
+ );
+
+ for (Index = 0; Index < 4; Index++) {
+ CheckFlags = 0;
+ if (NewTerminalContext->TerminalType == Index) {
+ CheckFlags |= EFI_IFR_OPTION_DEFAULT;
+ CallbackData->BmmFakeNvData.COMTerminalType = NewTerminalContext->TerminalType;
+ }
+
+ IfrOptionList[Index].Flags = CheckFlags;
+ IfrOptionList[Index].StringToken = (EFI_STRING_ID) TerminalType[Index];
+ IfrOptionList[Index].Value.u8 = Index;
+ }
+
+ CreateOneOfOpCode (
+ (EFI_QUESTION_ID) COM_TERMINAL_QUESTION_ID,
+ VARSTORE_ID_BOOT_MAINT,
+ COM_TERMINAL_VAR_OFFSET,
+ STRING_TOKEN (STR_COM_TERMI_TYPE),
+ STRING_TOKEN (STR_COM_TERMI_TYPE),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_1,
+ IfrOptionList,
+ 4,
+ &gUpdateData
+ );
+
+ SafeFreePool (IfrOptionList);
+
+ UpdatePageEnd (CallbackData);
+}
+
+VOID
+UpdatePageBody (
+ IN UINT16 UpdatePageId,
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+{
+ CleanUpPage (UpdatePageId, CallbackData);
+ switch (UpdatePageId) {
+ case FORM_CON_IN_ID:
+ UpdateConsolePage (UpdatePageId, &ConsoleInpMenu, CallbackData);
+ break;
+
+ case FORM_CON_OUT_ID:
+ UpdateConsolePage (UpdatePageId, &ConsoleOutMenu, CallbackData);
+ break;
+
+ case FORM_CON_ERR_ID:
+ UpdateConsolePage (UpdatePageId, &ConsoleErrMenu, CallbackData);
+ break;
+
+ case FORM_BOOT_CHG_ID:
+ UpdateOrderPage (UpdatePageId, &BootOptionMenu, CallbackData);
+ break;
+
+ case FORM_DRV_CHG_ID:
+ UpdateOrderPage (UpdatePageId, &DriverOptionMenu, CallbackData);
+ break;
+
+ default:
+ break;
+ }
+}
+
+VOID *
+GetLegacyBootOptionVar (
+ IN UINTN DeviceType,
+ OUT UINTN *OptionIndex,
+ OUT UINTN *OptionSize
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ VOID *OptionBuffer;
+ UINTN OrderSize;
+ UINTN Index;
+ UINT16 *OrderBuffer;
+ CHAR16 StrTemp[100];
+ UINT16 FilePathSize;
+ UINT8 *Ptr;
+ UINT8 *OptionalData;
+
+ //
+ // Get Boot Option number from the size of BootOrder
+ //
+ OrderBuffer = BdsLibGetVariableAndSize (
+ L"BootOrder",
+ &gEfiGlobalVariableGuid,
+ &OrderSize
+ );
+
+ for (Index = 0; Index < OrderSize / sizeof (UINT16); Index++) {
+ UnicodeSPrint (StrTemp, 100, L"Boot%04x", OrderBuffer[Index]);
+ OptionBuffer = BdsLibGetVariableAndSize (
+ StrTemp,
+ &gEfiGlobalVariableGuid,
+ OptionSize
+ );
+ if (NULL == OptionBuffer) {
+ continue;
+ }
+
+ Ptr = (UINT8 *) OptionBuffer;
+ Ptr += sizeof (UINT32);
+
+ FilePathSize = *(UINT16 *) Ptr;
+ Ptr += sizeof (UINT16);
+
+ Ptr += StrSize ((CHAR16 *) Ptr);
+
+ //
+ // Now Ptr point to Device Path
+ //
+ DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
+ Ptr += FilePathSize;
+
+ //
+ // Now Ptr point to Optional Data
+ //
+ OptionalData = Ptr;
+
+ if ((DeviceType == ((BBS_TABLE *) OptionalData)->DeviceType) &&
+ (BBS_DEVICE_PATH == DevicePath->Type) &&
+ (BBS_BBS_DP == DevicePath->SubType)
+ ) {
+ *OptionIndex = OrderBuffer[Index];
+ SafeFreePool (OrderBuffer);
+ return OptionBuffer;
+ } else {
+ SafeFreePool (OptionBuffer);
+ }
+ }
+
+ SafeFreePool (OrderBuffer);
+ return NULL;
+}
+
+VOID
+UpdateSetLegacyDeviceOrderPage (
+ IN UINT16 UpdatePageId,
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+{
+ BM_LEGACY_DEV_ORDER_CONTEXT *DevOrder;
+ BM_MENU_OPTION *OptionMenu;
+ BM_MENU_ENTRY *NewMenuEntry;
+ IFR_OPTION *IfrOptionList;
+ EFI_STRING_ID StrRef;
+ EFI_STRING_ID StrRefHelp;
+ BBS_TYPE BbsType;
+ UINTN VarSize;
+ UINTN Pos;
+ UINTN Bit;
+ UINT16 Index;
+ UINT16 Key;
+ CHAR16 String[100];
+ CHAR16 *TypeStr;
+ CHAR16 *TypeStrHelp;
+ UINT16 VarDevOrder;
+ UINT8 *VarData;
+ UINT8 *LegacyOrder;
+ UINT8 *OldData;
+ UINT8 *DisMap;
+
+ OptionMenu = NULL;
+ Key = 0;
+ StrRef = 0;
+ StrRefHelp = 0;
+ TypeStr = NULL;
+ TypeStrHelp = NULL;
+ BbsType = BBS_FLOPPY;
+ LegacyOrder = NULL;
+ OldData = NULL;
+ DisMap = NULL;
+
+ CallbackData->BmmAskSaveOrNot = TRUE;
+ UpdatePageStart (CallbackData);
+
+ DisMap = CallbackData->BmmOldFakeNVData.DisableMap;
+
+ SetMem (DisMap, 32, 0);
+ //
+ // Create oneof option list
+ //
+ switch (UpdatePageId) {
+ case FORM_SET_FD_ORDER_ID:
+ OptionMenu = (BM_MENU_OPTION *) &LegacyFDMenu;
+ Key = (UINT16) LEGACY_FD_QUESTION_ID;
+ TypeStr = StrFloppy;
+ TypeStrHelp = StrFloppyHelp;
+ BbsType = BBS_FLOPPY;
+ LegacyOrder = CallbackData->BmmFakeNvData.LegacyFD;
+ OldData = CallbackData->BmmOldFakeNVData.LegacyFD;
+ break;
+
+ case FORM_SET_HD_ORDER_ID:
+ OptionMenu = (BM_MENU_OPTION *) &LegacyHDMenu;
+ Key = (UINT16) LEGACY_HD_QUESTION_ID;
+ TypeStr = StrHardDisk;
+ TypeStrHelp = StrHardDiskHelp;
+ BbsType = BBS_HARDDISK;
+ LegacyOrder = CallbackData->BmmFakeNvData.LegacyHD;
+ OldData = CallbackData->BmmOldFakeNVData.LegacyHD;
+ break;
+
+ case FORM_SET_CD_ORDER_ID:
+ OptionMenu = (BM_MENU_OPTION *) &LegacyCDMenu;
+ Key = (UINT16) LEGACY_CD_QUESTION_ID;
+ TypeStr = StrCDROM;
+ TypeStrHelp = StrCDROMHelp;
+ BbsType = BBS_CDROM;
+ LegacyOrder = CallbackData->BmmFakeNvData.LegacyCD;
+ OldData = CallbackData->BmmOldFakeNVData.LegacyCD;
+ break;
+
+ case FORM_SET_NET_ORDER_ID:
+ OptionMenu = (BM_MENU_OPTION *) &LegacyNETMenu;
+ Key = (UINT16) LEGACY_NET_QUESTION_ID;
+ TypeStr = StrNET;
+ TypeStrHelp = StrNETHelp;
+ BbsType = BBS_EMBED_NETWORK;
+ LegacyOrder = CallbackData->BmmFakeNvData.LegacyNET;
+ OldData = CallbackData->BmmOldFakeNVData.LegacyNET;
+ break;
+
+ case FORM_SET_BEV_ORDER_ID:
+ OptionMenu = (BM_MENU_OPTION *) &LegacyBEVMenu;
+ Key = (UINT16) LEGACY_BEV_QUESTION_ID;
+ TypeStr = StrBEV;
+ TypeStrHelp = StrBEVHelp;
+ BbsType = BBS_BEV_DEVICE;
+ LegacyOrder = CallbackData->BmmFakeNvData.LegacyBEV;
+ OldData = CallbackData->BmmOldFakeNVData.LegacyBEV;
+ break;
+
+ }
+
+ CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, OptionMenu);
+
+ IfrOptionList = EfiAllocateZeroPool (sizeof (IFR_OPTION) * (OptionMenu->MenuNumber + 1));
+ if (NULL == IfrOptionList) {
+ return ;
+ }
+
+ for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (OptionMenu, Index);
+ IfrOptionList[Index].Flags = 0;
+ if (0 == Index) {
+ IfrOptionList[Index].Flags |= EFI_IFR_OPTION_DEFAULT;
+ }
+
+ IfrOptionList[Index].StringToken = NewMenuEntry->DisplayStringToken;
+ IfrOptionList[Index].Value.u8 = (UINT8) ((BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext)->Index;
+ }
+ //
+ // for item "Disabled"
+ //
+ IfrOptionList[Index].Flags = 0;
+ IfrOptionList[Index].StringToken = STRING_TOKEN (STR_DISABLE_LEGACY_DEVICE);
+ IfrOptionList[Index].Value.u8 = 0xFF;
+
+ //
+ // Get Device Order from variable
+ //
+ VarData = BdsLibGetVariableAndSize (
+ VarLegacyDevOrder,
+ &EfiLegacyDevOrderGuid,
+ &VarSize
+ );
+
+ if (NULL != VarData) {
+ DevOrder = (BM_LEGACY_DEV_ORDER_CONTEXT *) VarData;
+ while (VarData < VarData + VarSize) {
+ if (DevOrder->BbsType == BbsType) {
+ break;
+ }
+
+ VarData += sizeof (BBS_TYPE);
+ VarData += *(UINT16 *) VarData;
+ DevOrder = (BM_LEGACY_DEV_ORDER_CONTEXT *) VarData;
+ }
+ //
+ // Create oneof tag here for FD/HD/CD #1 #2
+ //
+ for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
+ //
+ // Create the string for oneof tag
+ //
+ UnicodeSPrint (String, sizeof (String), TypeStr, Index);
+ StrRef = 0;
+ IfrLibNewString (CallbackData->BmmHiiHandle, &StrRef, String);
+
+ UnicodeSPrint (String, sizeof (String), TypeStrHelp, Index);
+ StrRefHelp = 0;
+ IfrLibNewString (CallbackData->BmmHiiHandle, &StrRefHelp, String);
+
+ CreateOneOfOpCode (
+ (EFI_QUESTION_ID) (Key + Index),
+ VARSTORE_ID_BOOT_MAINT,
+ (UINT16) (Key + Index - CONFIG_OPTION_OFFSET),
+ StrRef,
+ StrRefHelp,
+ EFI_IFR_FLAG_CALLBACK,
+ EFI_IFR_NUMERIC_SIZE_1,
+ IfrOptionList,
+ OptionMenu->MenuNumber + 1,
+ &gUpdateData
+ );
+
+ VarDevOrder = *(UINT16 *) ((UINT8 *) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16) + Index * sizeof (UINT16));
+
+ if (0xFF00 == (VarDevOrder & 0xFF00)) {
+ LegacyOrder[Index] = 0xFF;
+ Pos = (VarDevOrder & 0xFF) / 8;
+ Bit = 7 - ((VarDevOrder & 0xFF) % 8);
+ DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));
+ } else {
+ LegacyOrder[Index] = (UINT8) (VarDevOrder & 0xFF);
+ }
+ }
+ }
+
+ CopyMem (OldData, LegacyOrder, 100);
+
+ if (IfrOptionList != NULL) {
+ SafeFreePool (IfrOptionList);
+ IfrOptionList = NULL;
+ }
+
+ UpdatePageEnd (CallbackData);
+}
+
+VOID
+UpdatePageId (
+ BMM_CALLBACK_DATA *Private,
+ UINT16 NewPageId
+ )
+{
+ if ((NewPageId < FILE_OPTION_OFFSET) && (NewPageId >= HANDLE_OPTION_OFFSET)) {
+ //
+ // If we select a handle to add driver option, advance to the add handle description page.
+ //
+ NewPageId = FORM_DRV_ADD_HANDLE_DESC_ID;
+ } else if ((NewPageId == KEY_VALUE_SAVE_AND_EXIT) || (NewPageId == KEY_VALUE_NO_SAVE_AND_EXIT)) {
+ //
+ // Return to main page after "Save Changes" or "Discard Changes".
+ //
+ NewPageId = FORM_MAIN_ID;
+ } else if ((NewPageId >= TERMINAL_OPTION_OFFSET) && (NewPageId < CONSOLE_OPTION_OFFSET)) {
+ NewPageId = FORM_CON_COM_SETUP_ID;
+ }
+
+ if ((NewPageId > 0) && (NewPageId < MAXIMUM_FORM_ID)) {
+ Private->BmmPreviousPageId = Private->BmmCurrentPageId;
+ Private->BmmCurrentPageId = NewPageId;
+ }
+}
diff --git a/MdeModulePkg/Universal/BdsDxe/BootMaint/Variable.c b/MdeModulePkg/Universal/BdsDxe/BootMaint/Variable.c new file mode 100644 index 0000000000..f5a1038b46 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/BootMaint/Variable.c @@ -0,0 +1,1314 @@ +/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ Variable.c
+
+Abstract:
+
+ Variable operation that will be used by bootmaint
+
+--*/
+
+#include "BootMaint.h"
+
+EFI_STATUS
+Var_DelBootOption (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Delete Boot Option that represent a Deleted state in BootOptionMenu.
+ After deleting this boot option, call Var_ChangeBootOrder to
+ make sure BootOrder is in valid state.
+
+Arguments:
+ LoadOption -- Pointer to the boot option that to be deleted
+
+Returns:
+ EFI_SUCCESS
+ Others
+
+--*/
+{
+ BM_MENU_ENTRY *NewMenuEntry;
+ BM_LOAD_CONTEXT *NewLoadContext;
+ UINT16 BootString[10];
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN Index2;
+
+ Status = EFI_SUCCESS;
+ Index2 = 0;
+ for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, (Index - Index2));
+ if (NULL == NewMenuEntry) {
+ return EFI_NOT_FOUND;
+ }
+
+ NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
+ if (!NewLoadContext->Deleted) {
+ continue;
+ }
+
+ UnicodeSPrint (
+ BootString,
+ sizeof (BootString),
+ L"Boot%04x",
+ NewMenuEntry->OptionNumber
+ );
+
+ EfiLibDeleteVariable (BootString, &gEfiGlobalVariableGuid);
+ Index2++;
+ //
+ // If current Load Option is the same as BootNext,
+ // must delete BootNext in order to make sure
+ // there will be no panic on next boot
+ //
+ if (NewLoadContext->IsBootNext) {
+ EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);
+ }
+
+ RemoveEntryList (&NewMenuEntry->Link);
+ BOpt_DestroyMenuEntry (NewMenuEntry);
+ NewMenuEntry = NULL;
+ }
+
+ BootOptionMenu.MenuNumber -= Index2;
+
+ Status = Var_ChangeBootOrder ();
+ return Status;
+}
+
+EFI_STATUS
+Var_ChangeBootOrder (
+ VOID
+ )
+/*++
+
+Routine Description:
+ After any operation on Boot####, there will be a discrepancy in BootOrder.
+ Since some are missing but in BootOrder, while some are present but are
+ not reflected by BootOrder. Then a function rebuild BootOrder from
+ scratch by content from BootOptionMenu is needed.
+
+Arguments:
+
+Returns:
+ EFI_SUCCESS
+ Others
+
+--*/
+{
+
+ EFI_STATUS Status;
+ BM_MENU_ENTRY *NewMenuEntry;
+ UINT16 *BootOrderList;
+ UINT16 *BootOrderListPtr;
+ UINTN BootOrderListSize;
+ UINTN Index;
+
+ BootOrderList = NULL;
+ BootOrderListSize = 0;
+
+ //
+ // First check whether BootOrder is present in current configuration
+ //
+ BootOrderList = BdsLibGetVariableAndSize (
+ L"BootOrder",
+ &gEfiGlobalVariableGuid,
+ &BootOrderListSize
+ );
+
+ //
+ // If exists, delete it to hold new BootOrder
+ //
+ if (BootOrderList) {
+ EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);
+ SafeFreePool (BootOrderList);
+ BootOrderList = NULL;
+ }
+ //
+ // Maybe here should be some check method to ensure that
+ // no new added boot options will be added
+ // but the setup engine now will give only one callback
+ // that is to say, user are granted only one chance to
+ // decide whether the boot option will be added or not
+ // there should be no indictor to show whether this
+ // is a "new" boot option
+ //
+ BootOrderListSize = BootOptionMenu.MenuNumber;
+
+ if (BootOrderListSize > 0) {
+ BootOrderList = EfiAllocateZeroPool (BootOrderListSize * sizeof (UINT16));
+ ASSERT (BootOrderList != NULL);
+ BootOrderListPtr = BootOrderList;
+
+ //
+ // Get all current used Boot#### from BootOptionMenu.
+ // OptionNumber in each BM_LOAD_OPTION is really its
+ // #### value.
+ //
+ for (Index = 0; Index < BootOrderListSize; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
+ *BootOrderList = (UINT16) NewMenuEntry->OptionNumber;
+ BootOrderList++;
+ }
+
+ BootOrderList = BootOrderListPtr;
+
+ //
+ // After building the BootOrderList, write it back
+ //
+ Status = gRT->SetVariable (
+ L"BootOrder",
+ &gEfiGlobalVariableGuid,
+ VAR_FLAG,
+ BootOrderListSize * sizeof (UINT16),
+ BootOrderList
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+Var_DelDriverOption (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Delete Load Option that represent a Deleted state in BootOptionMenu.
+ After deleting this Driver option, call Var_ChangeDriverOrder to
+ make sure DriverOrder is in valid state.
+
+Arguments:
+ LoadOption -- Pointer to the Driver option that to be deleted
+
+Returns:
+ EFI_SUCCESS
+ Others
+
+--*/
+{
+ BM_MENU_ENTRY *NewMenuEntry;
+ BM_LOAD_CONTEXT *NewLoadContext;
+ UINT16 DriverString[12];
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN Index2;
+
+ Status = EFI_SUCCESS;
+ Index2 = 0;
+ for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, (Index - Index2));
+ if (NULL == NewMenuEntry) {
+ return EFI_NOT_FOUND;
+ }
+
+ NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
+ if (!NewLoadContext->Deleted) {
+ continue;
+ }
+
+ UnicodeSPrint (
+ DriverString,
+ sizeof (DriverString),
+ L"Driver%04x",
+ NewMenuEntry->OptionNumber
+ );
+
+ EfiLibDeleteVariable (DriverString, &gEfiGlobalVariableGuid);
+ Index2++;
+
+ RemoveEntryList (&NewMenuEntry->Link);
+ BOpt_DestroyMenuEntry (NewMenuEntry);
+ NewMenuEntry = NULL;
+ }
+
+ DriverOptionMenu.MenuNumber -= Index2;
+
+ Status = Var_ChangeDriverOrder ();
+ return Status;
+}
+
+EFI_STATUS
+Var_ChangeDriverOrder (
+ VOID
+ )
+/*++
+
+Routine Description:
+ After any operation on Driver####, there will be a discrepancy in
+ DriverOrder. Since some are missing but in DriverOrder, while some
+ are present but are not reflected by DriverOrder. Then a function
+ rebuild DriverOrder from scratch by content from DriverOptionMenu is
+ needed.
+
+Arguments:
+
+Returns:
+ EFI_SUCCESS
+ Others
+
+--*/
+{
+ EFI_STATUS Status;
+ BM_MENU_ENTRY *NewMenuEntry;
+ UINT16 *DriverOrderList;
+ UINT16 *DriverOrderListPtr;
+ UINTN DriverOrderListSize;
+ UINTN Index;
+
+ DriverOrderList = NULL;
+ DriverOrderListSize = 0;
+
+ //
+ // First check whether DriverOrder is present in current configuration
+ //
+ DriverOrderList = BdsLibGetVariableAndSize (
+ L"DriverOrder",
+ &gEfiGlobalVariableGuid,
+ &DriverOrderListSize
+ );
+
+ //
+ // If exists, delete it to hold new DriverOrder
+ //
+ if (DriverOrderList) {
+ EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);
+ SafeFreePool (DriverOrderList);
+ DriverOrderList = NULL;
+ }
+
+ DriverOrderListSize = DriverOptionMenu.MenuNumber;
+
+ if (DriverOrderListSize > 0) {
+ DriverOrderList = EfiAllocateZeroPool (DriverOrderListSize * sizeof (UINT16));
+ ASSERT (DriverOrderList != NULL);
+ DriverOrderListPtr = DriverOrderList;
+
+ //
+ // Get all current used Driver#### from DriverOptionMenu.
+ // OptionNumber in each BM_LOAD_OPTION is really its
+ // #### value.
+ //
+ for (Index = 0; Index < DriverOrderListSize; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
+ *DriverOrderList = (UINT16) NewMenuEntry->OptionNumber;
+ DriverOrderList++;
+ }
+
+ DriverOrderList = DriverOrderListPtr;
+
+ //
+ // After building the DriverOrderList, write it back
+ //
+ Status = gRT->SetVariable (
+ L"DriverOrder",
+ &gEfiGlobalVariableGuid,
+ VAR_FLAG,
+ DriverOrderListSize * sizeof (UINT16),
+ DriverOrderList
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+VOID
+Var_UpdateAllConsoleOption (
+ VOID
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *OutDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *InpDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *ErrDevicePath;
+ EFI_STATUS Status;
+
+ OutDevicePath = EfiLibGetVariable (L"ConOut", &gEfiGlobalVariableGuid);
+ InpDevicePath = EfiLibGetVariable (L"ConIn", &gEfiGlobalVariableGuid);
+ ErrDevicePath = EfiLibGetVariable (L"ErrOut", &gEfiGlobalVariableGuid);
+ if (OutDevicePath) {
+ ChangeVariableDevicePath (OutDevicePath);
+ Status = gRT->SetVariable (
+ L"ConOut",
+ &gEfiGlobalVariableGuid,
+ VAR_FLAG,
+ GetDevicePathSize (OutDevicePath),
+ OutDevicePath
+ );
+ ASSERT (!EFI_ERROR (Status));
+ }
+
+ if (InpDevicePath) {
+ ChangeVariableDevicePath (InpDevicePath);
+ Status = gRT->SetVariable (
+ L"ConIn",
+ &gEfiGlobalVariableGuid,
+ VAR_FLAG,
+ GetDevicePathSize (InpDevicePath),
+ InpDevicePath
+ );
+ ASSERT (!EFI_ERROR (Status));
+ }
+
+ if (ErrDevicePath) {
+ ChangeVariableDevicePath (ErrDevicePath);
+ Status = gRT->SetVariable (
+ L"ErrOut",
+ &gEfiGlobalVariableGuid,
+ VAR_FLAG,
+ GetDevicePathSize (ErrDevicePath),
+ ErrDevicePath
+ );
+ ASSERT (!EFI_ERROR (Status));
+ }
+}
+
+EFI_STATUS
+Var_UpdateConsoleOption (
+ IN UINT16 *ConsoleName,
+ IN BM_MENU_OPTION *ConsoleMenu,
+ IN UINT16 UpdatePageId
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *ConDevicePath;
+ BM_MENU_ENTRY *NewMenuEntry;
+ BM_CONSOLE_CONTEXT *NewConsoleContext;
+ BM_TERMINAL_CONTEXT *NewTerminalContext;
+ EFI_STATUS Status;
+ VENDOR_DEVICE_PATH Vendor;
+ EFI_DEVICE_PATH_PROTOCOL *TerminalDevicePath;
+ UINTN Index;
+
+ ConDevicePath = EfiLibGetVariable (ConsoleName, &gEfiGlobalVariableGuid);
+ if (ConDevicePath != NULL) {
+ EfiLibDeleteVariable (ConsoleName, &gEfiGlobalVariableGuid);
+ SafeFreePool (ConDevicePath);
+ ConDevicePath = NULL;
+ };
+
+ //
+ // First add all console input device to it from console input menu
+ //
+ for (Index = 0; Index < ConsoleMenu->MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (ConsoleMenu, Index);
+ if (NULL == NewMenuEntry) {
+ return EFI_NOT_FOUND;
+ }
+
+ NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
+ if (NewConsoleContext->IsActive) {
+ ConDevicePath = AppendDevicePathInstance (
+ ConDevicePath,
+ NewConsoleContext->DevicePath
+ );
+ }
+ }
+
+ 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;
+ if ((NewTerminalContext->IsConIn && (UpdatePageId == FORM_CON_IN_ID)) ||
+ (NewTerminalContext->IsConOut && (UpdatePageId == FORM_CON_OUT_ID)) ||
+ (NewTerminalContext->IsStdErr && (UpdatePageId == FORM_CON_ERR_ID))
+ ) {
+ Vendor.Header.Type = MESSAGING_DEVICE_PATH;
+ Vendor.Header.SubType = MSG_VENDOR_DP;
+ CopyMem (
+ &Vendor.Guid,
+ &Guid[NewTerminalContext->TerminalType],
+ sizeof (EFI_GUID)
+ );
+ SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH));
+ TerminalDevicePath = AppendDevicePathNode (
+ NewTerminalContext->DevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *) &Vendor
+ );
+ ASSERT (TerminalDevicePath != NULL);
+ ChangeTerminalDevicePath (TerminalDevicePath, TRUE);
+ ConDevicePath = AppendDevicePathInstance (
+ ConDevicePath,
+ TerminalDevicePath
+ );
+ }
+ }
+
+ if (ConDevicePath) {
+ Status = gRT->SetVariable (
+ ConsoleName,
+ &gEfiGlobalVariableGuid,
+ VAR_FLAG,
+ GetDevicePathSize (ConDevicePath),
+ ConDevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+EFI_STATUS
+Var_UpdateConsoleInpOption (
+ VOID
+ )
+{
+ return Var_UpdateConsoleOption (L"ConIn", &ConsoleInpMenu, FORM_CON_IN_ID);
+}
+
+EFI_STATUS
+Var_UpdateConsoleOutOption (
+ VOID
+ )
+{
+ return Var_UpdateConsoleOption (L"ConOut", &ConsoleOutMenu, FORM_CON_OUT_ID);
+}
+
+EFI_STATUS
+Var_UpdateErrorOutOption (
+ VOID
+ )
+{
+ return Var_UpdateConsoleOption (L"ErrOut", &ConsoleErrMenu, FORM_CON_ERR_ID);
+}
+
+EFI_STATUS
+Var_UpdateDriverOption (
+ IN BMM_CALLBACK_DATA *CallbackData,
+ IN EFI_HII_HANDLE HiiHandle,
+ IN UINT16 *DescriptionData,
+ IN UINT16 *OptionalData,
+ IN UINT8 ForceReconnect
+ )
+{
+ UINT16 Index;
+ UINT16 *DriverOrderList;
+ UINT16 *NewDriverOrderList;
+ UINT16 DriverString[12];
+ UINTN DriverOrderListSize;
+ VOID *Buffer;
+ UINTN BufferSize;
+ UINT8 *Ptr;
+ BM_MENU_ENTRY *NewMenuEntry;
+ BM_LOAD_CONTEXT *NewLoadContext;
+ BOOLEAN OptionalDataExist;
+ EFI_STATUS Status;
+
+ OptionalDataExist = FALSE;
+
+ Index = BOpt_GetDriverOptionNumber ();
+ UnicodeSPrint (
+ DriverString,
+ sizeof (DriverString),
+ L"Driver%04x",
+ Index
+ );
+
+ if (*DescriptionData == 0x0000) {
+ StrCpy (DescriptionData, DriverString);
+ }
+
+ BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (DescriptionData);
+ BufferSize += GetDevicePathSize (CallbackData->LoadContext->FilePathList);
+
+ if (*OptionalData != 0x0000) {
+ OptionalDataExist = TRUE;
+ BufferSize += StrSize (OptionalData);
+ }
+
+ Buffer = EfiAllocateZeroPool (BufferSize);
+ if (NULL == Buffer) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);
+ if (NULL == NewMenuEntry) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
+ NewLoadContext->Deleted = FALSE;
+ NewLoadContext->LoadOptionSize = BufferSize;
+ Ptr = (UINT8 *) Buffer;
+ NewLoadContext->LoadOption = Ptr;
+ *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE | (ForceReconnect << 1);
+ NewLoadContext->Attributes = *((UINT32 *) Ptr);
+ NewLoadContext->IsActive = TRUE;
+ NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT);
+
+ Ptr += sizeof (UINT32);
+ *((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
+ NewLoadContext->FilePathListLength = *((UINT16 *) Ptr);
+
+ Ptr += sizeof (UINT16);
+ CopyMem (
+ Ptr,
+ DescriptionData,
+ StrSize (DescriptionData)
+ );
+
+ NewLoadContext->Description = EfiAllocateZeroPool (StrSize (DescriptionData));
+ ASSERT (NewLoadContext->Description != NULL);
+ NewMenuEntry->DisplayString = NewLoadContext->Description;
+ CopyMem (
+ NewLoadContext->Description,
+ (VOID *) Ptr,
+ StrSize (DescriptionData)
+ );
+
+ Ptr += StrSize (DescriptionData);
+ CopyMem (
+ Ptr,
+ CallbackData->LoadContext->FilePathList,
+ GetDevicePathSize (CallbackData->LoadContext->FilePathList)
+ );
+
+ NewLoadContext->FilePathList = EfiAllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));
+ ASSERT (NewLoadContext->FilePathList != NULL);
+
+ CopyMem (
+ NewLoadContext->FilePathList,
+ (VOID *) Ptr,
+ GetDevicePathSize (CallbackData->LoadContext->FilePathList)
+ );
+
+ NewMenuEntry->HelpString = DevicePathToStr (NewLoadContext->FilePathList);
+ NewMenuEntry->OptionNumber = Index;
+ NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository (
+ CallbackData,
+ DriverOptionStrDepository
+ );
+ IfrLibNewString (HiiHandle, &NewMenuEntry->DisplayStringToken, NewMenuEntry->DisplayString);
+
+ NewMenuEntry->HelpStringToken = GetStringTokenFromDepository (
+ CallbackData,
+ DriverOptionHelpStrDepository
+ );
+ IfrLibNewString (HiiHandle, &NewMenuEntry->HelpStringToken, NewMenuEntry->HelpString);
+
+ if (OptionalDataExist) {
+ Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
+
+ CopyMem (
+ Ptr,
+ OptionalData,
+ StrSize (OptionalData)
+ );
+ }
+
+ Status = gRT->SetVariable (
+ DriverString,
+ &gEfiGlobalVariableGuid,
+ VAR_FLAG,
+ BufferSize,
+ Buffer
+ );
+ ASSERT_EFI_ERROR (Status);
+ DriverOrderList = BdsLibGetVariableAndSize (
+ L"DriverOrder",
+ &gEfiGlobalVariableGuid,
+ &DriverOrderListSize
+ );
+ NewDriverOrderList = EfiAllocateZeroPool (DriverOrderListSize + sizeof (UINT16));
+ ASSERT (NewDriverOrderList != NULL);
+ CopyMem (NewDriverOrderList, DriverOrderList, DriverOrderListSize);
+ NewDriverOrderList[DriverOrderListSize / sizeof (UINT16)] = Index;
+ if (DriverOrderList != NULL) {
+ EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);
+ }
+
+ Status = gRT->SetVariable (
+ L"DriverOrder",
+ &gEfiGlobalVariableGuid,
+ VAR_FLAG,
+ DriverOrderListSize + sizeof (UINT16),
+ NewDriverOrderList
+ );
+ ASSERT_EFI_ERROR (Status);
+ SafeFreePool (DriverOrderList);
+ DriverOrderList = NULL;
+ SafeFreePool (NewDriverOrderList);
+ NewDriverOrderList = NULL;
+ InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link);
+ DriverOptionMenu.MenuNumber++;
+
+ *DescriptionData = 0x0000;
+ *OptionalData = 0x0000;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+Var_UpdateBootOption (
+ IN BMM_CALLBACK_DATA *CallbackData,
+ IN FILE_EXPLORER_NV_DATA *NvRamMap
+ )
+{
+ UINT16 *BootOrderList;
+ UINT16 *NewBootOrderList;
+ UINTN BootOrderListSize;
+ UINT16 BootString[10];
+ VOID *Buffer;
+ UINTN BufferSize;
+ UINT8 *Ptr;
+ UINT16 Index;
+ BM_MENU_ENTRY *NewMenuEntry;
+ BM_LOAD_CONTEXT *NewLoadContext;
+ BOOLEAN OptionalDataExist;
+ EFI_STATUS Status;
+
+ OptionalDataExist = FALSE;
+
+ Index = BOpt_GetBootOptionNumber () ;
+ UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", Index);
+
+ if (NvRamMap->DescriptionData[0] == 0x0000) {
+ StrCpy (NvRamMap->DescriptionData, BootString);
+ }
+
+ BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (NvRamMap->DescriptionData);
+ BufferSize += GetDevicePathSize (CallbackData->LoadContext->FilePathList);
+
+ if (NvRamMap->OptionalData[0] != 0x0000) {
+ OptionalDataExist = TRUE;
+ BufferSize += StrSize (NvRamMap->OptionalData);
+ }
+
+ Buffer = EfiAllocateZeroPool (BufferSize);
+ if (NULL == Buffer) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);
+ if (NULL == NewMenuEntry) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
+ NewLoadContext->Deleted = FALSE;
+ NewLoadContext->LoadOptionSize = BufferSize;
+ Ptr = (UINT8 *) Buffer;
+ NewLoadContext->LoadOption = Ptr;
+ *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE;
+ NewLoadContext->Attributes = *((UINT32 *) Ptr);
+ NewLoadContext->IsActive = TRUE;
+ NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT);
+
+ Ptr += sizeof (UINT32);
+ *((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
+ NewLoadContext->FilePathListLength = *((UINT16 *) Ptr);
+ Ptr += sizeof (UINT16);
+
+ CopyMem (
+ Ptr,
+ NvRamMap->DescriptionData,
+ StrSize (NvRamMap->DescriptionData)
+ );
+
+ NewLoadContext->Description = EfiAllocateZeroPool (StrSize (NvRamMap->DescriptionData));
+ ASSERT (NewLoadContext->Description != NULL);
+
+ NewMenuEntry->DisplayString = NewLoadContext->Description;
+ CopyMem (
+ NewLoadContext->Description,
+ (VOID *) Ptr,
+ StrSize (NvRamMap->DescriptionData)
+ );
+
+ Ptr += StrSize (NvRamMap->DescriptionData);
+ CopyMem (
+ Ptr,
+ CallbackData->LoadContext->FilePathList,
+ GetDevicePathSize (CallbackData->LoadContext->FilePathList)
+ );
+
+ NewLoadContext->FilePathList = EfiAllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));
+ ASSERT (NewLoadContext->FilePathList != NULL);
+
+ CopyMem (
+ NewLoadContext->FilePathList,
+ (VOID *) Ptr,
+ GetDevicePathSize (CallbackData->LoadContext->FilePathList)
+ );
+
+ NewMenuEntry->HelpString = DevicePathToStr (NewLoadContext->FilePathList);
+ NewMenuEntry->OptionNumber = Index;
+ NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository (
+ CallbackData,
+ BootOptionStrDepository
+ );
+ IfrLibNewString (CallbackData->FeHiiHandle, &NewMenuEntry->DisplayStringToken, NewMenuEntry->DisplayString);
+
+ NewMenuEntry->HelpStringToken = GetStringTokenFromDepository (
+ CallbackData,
+ BootOptionHelpStrDepository
+ );
+ IfrLibNewString (CallbackData->FeHiiHandle, &NewMenuEntry->HelpStringToken, NewMenuEntry->HelpString);
+
+ if (OptionalDataExist) {
+ Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
+
+ CopyMem (Ptr, NvRamMap->OptionalData, StrSize (NvRamMap->OptionalData));
+ }
+
+ Status = gRT->SetVariable (
+ BootString,
+ &gEfiGlobalVariableGuid,
+ VAR_FLAG,
+ BufferSize,
+ Buffer
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ BootOrderList = BdsLibGetVariableAndSize (
+ L"BootOrder",
+ &gEfiGlobalVariableGuid,
+ &BootOrderListSize
+ );
+
+ NewBootOrderList = EfiAllocateZeroPool (BootOrderListSize + sizeof (UINT16));
+ ASSERT (NewBootOrderList != NULL);
+ CopyMem (NewBootOrderList, BootOrderList, BootOrderListSize);
+ NewBootOrderList[BootOrderListSize / sizeof (UINT16)] = Index;
+
+ if (BootOrderList != NULL) {
+ EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);
+ }
+
+ Status = gRT->SetVariable (
+ L"BootOrder",
+ &gEfiGlobalVariableGuid,
+ VAR_FLAG,
+ BootOrderListSize + sizeof (UINT16),
+ NewBootOrderList
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ SafeFreePool (BootOrderList);
+ BootOrderList = NULL;
+ SafeFreePool (NewBootOrderList);
+ NewBootOrderList = NULL;
+ InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link);
+ BootOptionMenu.MenuNumber++;
+
+ NvRamMap->DescriptionData[0] = 0x0000;
+ NvRamMap->OptionalData[0] = 0x0000;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+Var_UpdateBootNext (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+{
+ BM_MENU_ENTRY *NewMenuEntry;
+ BM_LOAD_CONTEXT *NewLoadContext;
+ BMM_FAKE_NV_DATA *CurrentFakeNVMap;
+ UINT16 Index;
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+ CurrentFakeNVMap = &CallbackData->BmmFakeNvData;
+ for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
+ if (NULL == NewMenuEntry) {
+ return EFI_NOT_FOUND;
+ }
+
+ NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
+ NewLoadContext->IsBootNext = FALSE;
+ }
+
+ if (CurrentFakeNVMap->BootNext == BootOptionMenu.MenuNumber) {
+ EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);
+ return EFI_SUCCESS;
+ }
+
+ NewMenuEntry = BOpt_GetMenuEntry (
+ &BootOptionMenu,
+ CurrentFakeNVMap->BootNext
+ );
+ if (NULL == NewMenuEntry) {
+ return EFI_NOT_FOUND;
+ }
+
+ NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
+ Status = gRT->SetVariable (
+ L"BootNext",
+ &gEfiGlobalVariableGuid,
+ VAR_FLAG,
+ sizeof (UINT16),
+ &NewMenuEntry->OptionNumber
+ );
+ NewLoadContext->IsBootNext = TRUE;
+ CallbackData->BmmOldFakeNVData.BootNext = CurrentFakeNVMap->BootNext;
+ return Status;
+}
+
+EFI_STATUS
+Var_UpdateBootOrder (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+{
+ EFI_STATUS Status;
+ UINT16 Index;
+ UINT16 *BootOrderList;
+ UINT16 *NewBootOrderList;
+ UINTN BootOrderListSize;
+ UINT8 *Map;
+
+ BootOrderList = NULL;
+ BootOrderListSize = 0;
+
+ //
+ // First check whether BootOrder is present in current configuration
+ //
+ BootOrderList = BdsLibGetVariableAndSize (
+ L"BootOrder",
+ &gEfiGlobalVariableGuid,
+ &BootOrderListSize
+ );
+
+ NewBootOrderList = EfiAllocateZeroPool (BootOrderListSize);
+ if (!NewBootOrderList) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Map = EfiAllocateZeroPool (BootOrderListSize / sizeof (UINT16));
+ if (!Map) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // If exists, delete it to hold new BootOrder
+ //
+ if (BootOrderList) {
+ EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);
+ }
+
+ for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
+ NewBootOrderList[Index] = (UINT16) (CallbackData->BmmFakeNvData.OptionOrder[Index] - 1);
+ }
+
+ Status = gRT->SetVariable (
+ L"BootOrder",
+ &gEfiGlobalVariableGuid,
+ VAR_FLAG,
+ BootOrderListSize,
+ NewBootOrderList
+ );
+ SafeFreePool (BootOrderList);
+ SafeFreePool (NewBootOrderList);
+ SafeFreePool (Map);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ BOpt_FreeMenu (&BootOptionMenu);
+ BOpt_GetBootOptions (CallbackData);
+
+ return EFI_SUCCESS;
+
+}
+
+EFI_STATUS
+Var_UpdateDriverOrder (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+{
+ EFI_STATUS Status;
+ UINT16 Index;
+ UINT16 *DriverOrderList;
+ UINT16 *NewDriverOrderList;
+ UINTN DriverOrderListSize;
+
+ DriverOrderList = NULL;
+ DriverOrderListSize = 0;
+
+ //
+ // First check whether DriverOrder is present in current configuration
+ //
+ DriverOrderList = BdsLibGetVariableAndSize (
+ L"DriverOrder",
+ &gEfiGlobalVariableGuid,
+ &DriverOrderListSize
+ );
+
+ NewDriverOrderList = EfiAllocateZeroPool (DriverOrderListSize);
+
+ if (!NewDriverOrderList) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // If exists, delete it to hold new DriverOrder
+ //
+ if (DriverOrderList) {
+ EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);
+ }
+
+ for (Index = 0; Index < DriverOrderListSize; Index++) {
+ NewDriverOrderList[Index] = (UINT16) (CallbackData->BmmFakeNvData.OptionOrder[Index] - 1);
+ }
+
+ Status = gRT->SetVariable (
+ L"DriverOrder",
+ &gEfiGlobalVariableGuid,
+ VAR_FLAG,
+ DriverOrderListSize,
+ NewDriverOrderList
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ SafeFreePool (DriverOrderList);
+
+ BOpt_FreeMenu (&DriverOptionMenu);
+ BOpt_GetDriverOptions (CallbackData);
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+Var_UpdateBBSOption (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+{
+ UINTN Index;
+ UINTN Index2;
+ VOID *BootOptionVar;
+ CHAR16 VarName[100];
+ UINTN OptionSize;
+ UINT8 *Ptr;
+ EFI_STATUS Status;
+ CHAR16 DescString[100];
+ CHAR8 DescAsciiString[100];
+ UINTN NewOptionSize;
+ UINT8 *NewOptionPtr;
+ UINT8 *TempPtr;
+ UINT32 *Attribute;
+ BM_MENU_OPTION *OptionMenu;
+ BM_LEGACY_DEVICE_CONTEXT *LegacyDeviceContext;
+ UINT8 *LegacyDev;
+ UINT8 *VarData;
+ UINTN VarSize;
+ BM_MENU_ENTRY *NewMenuEntry;
+ BM_LEGACY_DEV_ORDER_CONTEXT *DevOrder;
+ UINT8 *OriginalPtr;
+ UINT8 *DisMap;
+ UINTN Pos;
+ UINTN Bit;
+ UINT16 *NewOrder;
+ UINT16 Tmp;
+
+ LegacyDeviceContext = NULL;
+ DisMap = NULL;
+ NewOrder = NULL;
+
+ if (FORM_SET_FD_ORDER_ID == CallbackData->BmmPreviousPageId) {
+ OptionMenu = (BM_MENU_OPTION *) &LegacyFDMenu;
+ LegacyDev = CallbackData->BmmFakeNvData.LegacyFD;
+ CallbackData->BbsType = BBS_FLOPPY;
+ } else {
+ if (FORM_SET_HD_ORDER_ID == CallbackData->BmmPreviousPageId) {
+ OptionMenu = (BM_MENU_OPTION *) &LegacyHDMenu;
+ LegacyDev = CallbackData->BmmFakeNvData.LegacyHD;
+ CallbackData->BbsType = BBS_HARDDISK;
+ } else {
+ if (FORM_SET_CD_ORDER_ID == CallbackData->BmmPreviousPageId) {
+ OptionMenu = (BM_MENU_OPTION *) &LegacyCDMenu;
+ LegacyDev = CallbackData->BmmFakeNvData.LegacyCD;
+ CallbackData->BbsType = BBS_CDROM;
+ } else {
+ if (FORM_SET_NET_ORDER_ID == CallbackData->BmmPreviousPageId) {
+ OptionMenu = (BM_MENU_OPTION *) &LegacyNETMenu;
+ LegacyDev = CallbackData->BmmFakeNvData.LegacyNET;
+ CallbackData->BbsType = BBS_EMBED_NETWORK;
+ } else {
+ OptionMenu = (BM_MENU_OPTION *) &LegacyBEVMenu;
+ LegacyDev = CallbackData->BmmFakeNvData.LegacyBEV;
+ CallbackData->BbsType = BBS_BEV_DEVICE;
+ }
+ }
+ }
+ }
+
+ DisMap = CallbackData->BmmOldFakeNVData.DisableMap;
+ Status = EFI_SUCCESS;
+
+ //
+ // Find the first device's context
+ // If all devices are disabled( 0xFF == LegacyDev[0]), LegacyDeviceContext can be set to any VariableContext
+ // because we just use it to fill the desc string, and user can not see the string in UI
+ //
+ for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
+ NewMenuEntry = BOpt_GetMenuEntry (OptionMenu, Index);
+ LegacyDeviceContext = (BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext;
+ if (0xFF != LegacyDev[0] && LegacyDev[0] == LegacyDeviceContext->Index) {
+ DEBUG ((DEBUG_ERROR, "DescStr: %s\n", LegacyDeviceContext->Description));
+ break;
+ }
+ }
+ //
+ // Update the Variable "LegacyDevOrder"
+ //
+ VarData = (UINT8 *) BdsLibGetVariableAndSize (
+ VarLegacyDevOrder,
+ &EfiLegacyDevOrderGuid,
+ &VarSize
+ );
+
+ if (NULL == VarData) {
+ return EFI_NOT_FOUND;
+ }
+
+ OriginalPtr = VarData;
+ DevOrder = (BM_LEGACY_DEV_ORDER_CONTEXT *) VarData;
+
+ while (VarData < VarData + VarSize) {
+ if (DevOrder->BbsType == CallbackData->BbsType) {
+ break;
+ }
+
+ VarData += sizeof (BBS_TYPE);
+ VarData += *(UINT16 *) VarData;
+ DevOrder = (BM_LEGACY_DEV_ORDER_CONTEXT *) VarData;
+ }
+
+ if (VarData >= VarData + VarSize) {
+ SafeFreePool (OriginalPtr);
+ return EFI_NOT_FOUND;
+ }
+
+ NewOrder = (UINT16 *) EfiAllocateZeroPool (DevOrder->Length - sizeof (UINT16));
+ if (NULL == NewOrder) {
+ SafeFreePool (VarData);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
+ if (0xFF == LegacyDev[Index]) {
+ break;
+ }
+
+ NewOrder[Index] = LegacyDev[Index];
+ }
+ //
+ // Only the enable/disable state of each boot device with same device type can be changed,
+ // so we can count on the index information in DevOrder.
+ // DisMap bit array is the only reliable source to check a device's en/dis state,
+ // so we use DisMap to set en/dis state of each item in NewOrder array
+ //
+ for (Index2 = 0; Index2 < OptionMenu->MenuNumber; Index2++) {
+ Tmp = *(UINT16 *) ((UINT8 *) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16) + Index2 * sizeof (UINT16));
+ Tmp &= 0xFF;
+ Pos = Tmp / 8;
+ Bit = 7 - (Tmp % 8);
+ if (DisMap[Pos] & (1 << Bit)) {
+ NewOrder[Index] = (UINT16) (0xFF00 | Tmp);
+ Index++;
+ }
+ }
+
+ CopyMem (
+ (UINT8 *) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16),
+ NewOrder,
+ DevOrder->Length - sizeof (UINT16)
+ );
+ SafeFreePool (NewOrder);
+
+ Status = gRT->SetVariable (
+ VarLegacyDevOrder,
+ &EfiLegacyDevOrderGuid,
+ VAR_FLAG,
+ VarSize,
+ OriginalPtr
+ );
+
+ SafeFreePool (OriginalPtr);
+
+ //
+ // Update Optional Data of Boot####
+ //
+ BootOptionVar = GetLegacyBootOptionVar (CallbackData->BbsType, &Index, &OptionSize);
+
+ if (NULL != BootOptionVar) {
+ CopyMem (
+ DescString,
+ LegacyDeviceContext->Description,
+ StrSize (LegacyDeviceContext->Description)
+ );
+
+ UnicodeToAscii (DescString, StrSize (DescString), DescAsciiString);
+
+ NewOptionSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (DescString) +
+ sizeof (BBS_BBS_DEVICE_PATH);
+ NewOptionSize += AsciiStrLen (DescAsciiString) +
+ EFI_END_DEVICE_PATH_LENGTH + sizeof (BBS_TABLE) + sizeof (UINT16);
+
+ UnicodeSPrint (VarName, 100, L"Boot%04x", Index);
+
+ Ptr = BootOptionVar;
+
+ Attribute = (UINT32 *) Ptr;
+ *Attribute |= LOAD_OPTION_ACTIVE;
+ if (0xFF == LegacyDev[0]) {
+ //
+ // Disable this legacy boot option
+ //
+ *Attribute &= ~LOAD_OPTION_ACTIVE;
+ }
+
+ Ptr += sizeof (UINT32);
+
+ Ptr += sizeof (UINT16);
+ Ptr += StrSize ((CHAR16 *) Ptr);
+
+ NewOptionPtr = EfiAllocateZeroPool (NewOptionSize);
+ if (NULL == NewOptionPtr) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ TempPtr = NewOptionPtr;
+
+ //
+ // Attribute
+ //
+ CopyMem (
+ TempPtr,
+ BootOptionVar,
+ sizeof (UINT32)
+ );
+
+ TempPtr += sizeof (UINT32);
+
+ //
+ // BBS device path Length
+ //
+ *((UINT16 *) TempPtr) = (UINT16) (sizeof (BBS_BBS_DEVICE_PATH) +
+ AsciiStrLen (DescAsciiString) +
+ EFI_END_DEVICE_PATH_LENGTH);
+
+ TempPtr += sizeof (UINT16);
+
+ //
+ // Description string
+ //
+ CopyMem (
+ TempPtr,
+ DescString,
+ StrSize (DescString)
+ );
+
+ TempPtr += StrSize (DescString);
+
+ //
+ // BBS device path
+ //
+ CopyMem (
+ TempPtr,
+ Ptr,
+ sizeof (BBS_BBS_DEVICE_PATH)
+ );
+
+ CopyMem (
+ ((BBS_BBS_DEVICE_PATH*) TempPtr)->String,
+ DescAsciiString,
+ AsciiStrSize (DescAsciiString)
+ );
+
+ SetDevicePathNodeLength (
+ (EFI_DEVICE_PATH_PROTOCOL *) TempPtr,
+ sizeof (BBS_BBS_DEVICE_PATH) + AsciiStrLen (DescAsciiString)
+ );
+
+ TempPtr += sizeof (BBS_BBS_DEVICE_PATH) + AsciiStrLen (DescAsciiString);
+
+ //
+ // End node
+ //
+ CopyMem (
+ TempPtr,
+ EndDevicePath,
+ EFI_END_DEVICE_PATH_LENGTH
+ );
+ TempPtr += EFI_END_DEVICE_PATH_LENGTH;
+
+ //
+ // Now TempPtr point to optional data, i.e. Bbs Table
+ //
+ CopyMem (
+ TempPtr,
+ LegacyDeviceContext->BbsTable,
+ sizeof (BBS_TABLE)
+ );
+
+ //
+ // Now TempPtr point to BBS index
+ //
+ TempPtr += sizeof (BBS_TABLE);
+ *((UINT16 *) TempPtr) = (UINT16) LegacyDeviceContext->Index;
+
+ Status = gRT->SetVariable (
+ VarName,
+ &gEfiGlobalVariableGuid,
+ VAR_FLAG,
+ NewOptionSize,
+ NewOptionPtr
+ );
+
+ SafeFreePool (NewOptionPtr);
+ SafeFreePool (BootOptionVar);
+ }
+
+ BOpt_GetBootOptions (CallbackData);
+ return Status;
+}
+
+EFI_STATUS
+Var_UpdateConMode (
+ IN BMM_CALLBACK_DATA *CallbackData
+ )
+{
+ EFI_STATUS Status;
+ UINTN Mode;
+ CONSOLE_OUT_MODE ModeInfo;
+
+ Mode = CallbackData->BmmFakeNvData.ConsoleOutMode;
+
+ Status = gST->ConOut->QueryMode (gST->ConOut, Mode, &(ModeInfo.Column), &(ModeInfo.Row));
+ if (EFI_ERROR(Status)) {
+ ModeInfo.Column = 80;
+ ModeInfo.Row = 25;
+ }
+
+ Status = gRT->SetVariable (
+ VarConOutMode,
+ &gEfiGenericPlatformVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ sizeof (CONSOLE_OUT_MODE),
+ &ModeInfo
+ );
+
+ return Status;
+}
diff --git a/MdeModulePkg/Universal/BdsDxe/BootMngr/BootManager.c b/MdeModulePkg/Universal/BdsDxe/BootMngr/BootManager.c new file mode 100644 index 0000000000..fdf39cac98 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/BootMngr/BootManager.c @@ -0,0 +1,335 @@ +/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ BootManager.c
+
+Abstract:
+
+ The platform boot manager reference implement
+
+--*/
+
+#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
+ }
+};
+
+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
+ )
+/*++
+
+ Routine Description:
+ This function processes the results of changes in configuration.
+
+ Arguments:
+ This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ Action - Specifies the type of action taken by the browser.
+ QuestionId - A unique value which is sent to the original exporting driver
+ so that it can identify the type of data to expect.
+ Type - The type of value for the question.
+ Value - A pointer to the data being sent to the original exporting driver.
+ ActionRequest - On return, points to the action requested by the callback function.
+
+ Returns:
+ EFI_SUCCESS - The callback successfully handled the action.
+ EFI_OUT_OF_RESOURCES - Not enough storage is available to hold the variable and its data.
+ EFI_DEVICE_ERROR - The variable could not be saved.
+ EFI_UNSUPPORTED - The specified Action is not supported by the callback.
+
+--*/
+{
+ 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;
+}
+
+EFI_STATUS
+InitializeBootManager (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Initialize HII information for the FrontPage
+
+Arguments:
+ None
+
+Returns:
+
+--*/
+{
+ 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 = PreparePackageList (2, &mBootManagerGuid, BootManagerVfrBin, BdsStrings);
+ ASSERT (PackageList != NULL);
+
+ Status = gHiiDatabase->NewPackageList (
+ gHiiDatabase,
+ PackageList,
+ gBootManagerPrivate.DriverHandle,
+ &gBootManagerPrivate.HiiHandle
+ );
+ FreePool (PackageList);
+
+ return Status;
+}
+
+VOID
+CallBootManager (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Hook to enable UI timeout override behavior.
+
+Arguments:
+ BdsDeviceList - Device List that BDS needs to connect.
+
+ Entry - Pointer to current Boot Entry.
+
+Returns:
+ NONE
+
+--*/
+{
+ 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;
+ }
+
+ IfrLibNewString (HiiHandle, &Token, Option->Description);
+
+ TempStr = DevicePathToStr (Option->DevicePath);
+ TempSize = StrSize (TempStr);
+ HelpString = AllocateZeroPool (TempSize + StrSize (L"Device Path : "));
+ StrCat (HelpString, L"Device Path : ");
+ StrCat (HelpString, TempStr);
+
+ IfrLibNewString (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);
+
+ //
+ // Drop the TPL level from TPL_APPLICATION to TPL_APPLICATION
+ //
+ gBS->RestoreTPL (TPL_APPLICATION);
+
+ 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) {
+ gBS->RaiseTPL (TPL_APPLICATION);
+ return ;
+ }
+
+ //
+ //Will leave browser, check any reset required change is applied? if yes, reset system
+ //
+ SetupResetReminder ();
+
+ //
+ // Raise the TPL level back to TPL_APPLICATION
+ //
+ gBS->RaiseTPL (TPL_APPLICATION);
+
+ //
+ // 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))
+ );
+ gBS->RestoreTPL (TPL_APPLICATION);
+ //
+ // BdsLibUiWaitForSingleEvent (gST->ConIn->WaitForKey, 0);
+ //
+ gBS->RaiseTPL (TPL_APPLICATION);
+ gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+ }
+}
diff --git a/MdeModulePkg/Universal/BdsDxe/BootMngr/BootManager.h b/MdeModulePkg/Universal/BdsDxe/BootMngr/BootManager.h new file mode 100644 index 0000000000..fab04d22a3 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/BootMngr/BootManager.h @@ -0,0 +1,88 @@ +/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ BootManager.h
+
+Abstract:
+
+ The platform boot manager reference implement
+
+Revision History
+
+--*/
+
+#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 EFI_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;
+
+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
+ )
+;
+
+EFI_STATUS
+InitializeBootManager (
+ VOID
+ )
+;
+
+VOID
+CallBootManager (
+ VOID
+ )
+;
+
+#endif
diff --git a/MdeModulePkg/Universal/BdsDxe/BootMngr/BootManagerStrings.uni b/MdeModulePkg/Universal/BdsDxe/BootMngr/BootManagerStrings.uni Binary files differnew file mode 100644 index 0000000000..99b0cdf551 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/BootMngr/BootManagerStrings.uni diff --git a/MdeModulePkg/Universal/BdsDxe/BootMngr/BootManagerVfr.Vfr b/MdeModulePkg/Universal/BdsDxe/BootMngr/BootManagerVfr.Vfr new file mode 100644 index 0000000000..e31d2292d4 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/BootMngr/BootManagerVfr.Vfr @@ -0,0 +1,59 @@ +// *++
+//
+// Copyright (c) 2004 - 2007, Intel Corporation
+// 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.
+//
+// Module Name:
+//
+// BootManager.vfr
+//
+// Abstract:
+//
+// Browser formset.
+//
+// Revision History:
+//
+// --*/
+
+#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;
diff --git a/MdeModulePkg/Universal/BdsDxe/Capsules.c b/MdeModulePkg/Universal/BdsDxe/Capsules.c new file mode 100644 index 0000000000..9969f486da --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/Capsules.c @@ -0,0 +1,264 @@ +/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ Capsules.c
+
+Abstract:
+
+ BDS routines to handle capsules.
+
+--*/
+#include "Bds.h"
+
+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++;
+ }
+}
+
+EFI_STATUS
+ProcessCapsules (
+ EFI_BOOT_MODE BootMode
+ )
+/*++
+
+Routine Description:
+
+ 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.
+
+Arguments:
+
+ BootMode - the current boot mode
+
+Returns:
+
+ EFI_INVALID_PARAMETER - boot mode is not correct for an update
+
+Note:
+
+ 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 awry 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.
+
+--*/
+{
+ 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;
+}
diff --git a/MdeModulePkg/Universal/BdsDxe/DeviceMngr/DeviceManager.c b/MdeModulePkg/Universal/BdsDxe/DeviceMngr/DeviceManager.c new file mode 100644 index 0000000000..0ec274d8ce --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/DeviceMngr/DeviceManager.c @@ -0,0 +1,434 @@ +/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ DeviceManager.c
+
+Abstract:
+
+ The platform device manager reference implement
+
+--*/
+
+#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))
+
+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
+ )
+/*++
+
+ Routine Description:
+ This function processes the results of changes in configuration.
+
+ Arguments:
+ This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ Action - Specifies the type of action taken by the browser.
+ QuestionId - A unique value which is sent to the original exporting driver
+ so that it can identify the type of data to expect.
+ Type - The type of value for the question.
+ Value - A pointer to the data being sent to the original exporting driver.
+ ActionRequest - On return, points to the action requested by the callback function.
+
+ Returns:
+ EFI_SUCCESS - The callback successfully handled the action.
+ EFI_OUT_OF_RESOURCES - Not enough storage is available to hold the variable and its data.
+ EFI_DEVICE_ERROR - The variable could not be saved.
+ EFI_UNSUPPORTED - The specified Action is not supported by the callback.
+
+--*/
+{
+ 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;
+}
+
+EFI_STATUS
+InitializeDeviceManager (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Initialize HII information for the FrontPage
+
+Arguments:
+ None
+
+Returns:
+
+--*/
+{
+ 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 = PreparePackageList (2, &mDeviceManagerGuid, DeviceManagerVfrBin, BdsStrings);
+ ASSERT (PackageList != NULL);
+
+ Status = gHiiDatabase->NewPackageList (
+ gHiiDatabase,
+ PackageList,
+ gDeviceManagerPrivate.DriverHandle,
+ &gDeviceManagerPrivate.HiiHandle
+ );
+ FreePool (PackageList);
+
+ return Status;
+}
+
+EFI_STATUS
+CallDeviceManager (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Call the browser and display the device manager
+
+Arguments:
+
+ None
+
+Returns:
+ EFI_SUCCESS - Operation is successful.
+ EFI_INVALID_PARAMETER - If the inputs to SendForm function is not valid.
+
+--*/
+{
+ 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 = GetHiiHandles (&HandleBufferLength, &HiiHandles);
+ ASSERT_EFI_ERROR (Status);
+
+ 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++) {
+ HiiLibExtractClassFromHiiHandle (HiiHandles[Index], &FormSetClass, &FormSetTitle, &FormSetHelp);
+
+ if (FormSetClass == EFI_NON_DEVICE_CLASS) {
+ continue;
+ }
+
+ Token = 0;
+ *String = 0;
+ StringLength = 0x1000;
+ IfrLibGetString (HiiHandles[Index], FormSetTitle, String, &StringLength);
+ IfrLibNewString (HiiHandle, &Token, String);
+
+ TokenHelp = 0;
+ *String = 0;
+ StringLength = 0x1000;
+ IfrLibGetString (HiiHandles[Index], FormSetHelp, String, &StringLength);
+ IfrLibNewString (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 (NULL == VideoOption) {
+ 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]
+ );
+
+ //
+ // Drop the TPL level from TPL_APPLICATION to TPL_APPLICATION
+ //
+ gBS->RestoreTPL (TPL_APPLICATION);
+
+ 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 = PreparePackageList (2, &mDeviceManagerGuid, DeviceManagerVfrBin, BdsStrings);
+ 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);
+
+ gBS->RaiseTPL (TPL_APPLICATION);
+
+ return Status;
+}
diff --git a/MdeModulePkg/Universal/BdsDxe/DeviceMngr/DeviceManager.h b/MdeModulePkg/Universal/BdsDxe/DeviceMngr/DeviceManager.h new file mode 100644 index 0000000000..046945612e --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/DeviceMngr/DeviceManager.h @@ -0,0 +1,108 @@ +/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ DeviceManager.c
+
+Abstract:
+
+ The platform device manager reference implement
+
+Revision History
+
+--*/
+
+#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 EFI_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;
+
+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
+ )
+;
+
+EFI_STATUS
+InitializeDeviceManager (
+ VOID
+ )
+;
+
+EFI_STATUS
+CallDeviceManager (
+ VOID
+ )
+;
+
+#endif
diff --git a/MdeModulePkg/Universal/BdsDxe/DeviceMngr/DeviceManagerStrings.uni b/MdeModulePkg/Universal/BdsDxe/DeviceMngr/DeviceManagerStrings.uni Binary files differnew file mode 100644 index 0000000000..99beee4c65 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/DeviceMngr/DeviceManagerStrings.uni diff --git a/MdeModulePkg/Universal/BdsDxe/DeviceMngr/DeviceManagerVfr.Vfr b/MdeModulePkg/Universal/BdsDxe/DeviceMngr/DeviceManagerVfr.Vfr new file mode 100644 index 0000000000..78fff23f5d --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/DeviceMngr/DeviceManagerVfr.Vfr @@ -0,0 +1,82 @@ +// *++
+//
+// Copyright (c) 2004 - 2007, Intel Corporation
+// 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.
+//
+// Module Name:
+//
+// DeviceManagerVfr.vfr
+//
+// Abstract:
+//
+// Device Manager formset.
+//
+// Revision History:
+//
+// --*/
+
+#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;
+
diff --git a/MdeModulePkg/Universal/BdsDxe/FrontPage.c b/MdeModulePkg/Universal/BdsDxe/FrontPage.c new file mode 100644 index 0000000000..b82b40fbb7 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/FrontPage.c @@ -0,0 +1,1035 @@ +/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ FrontPage.c
+
+Abstract:
+
+ FrontPage routines to handle the callbacks and browser calls
+
+--*/
+
+#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
+ }
+};
+
+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
+ )
+/*++
+
+ Routine Description:
+ This function allows a caller to extract the current configuration for one
+ or more named elements from the target driver.
+
+ Arguments:
+ This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ Request - A null-terminated Unicode string in <ConfigRequest> format.
+ 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.
+ 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.
+
+ Returns:
+ EFI_SUCCESS - The Results is filled with the requested values.
+ EFI_OUT_OF_RESOURCES - Not enough memory to store the results.
+ EFI_INVALID_PARAMETER - Request is NULL, illegal syntax, or unknown name.
+ EFI_NOT_FOUND - Routing data doesn't match any storage in this driver.
+
+--*/
+{
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+EFIAPI
+FakeRouteConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+ )
+/*++
+
+ Routine Description:
+ This function processes the results of changes in configuration.
+
+ Arguments:
+ This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ Configuration - A null-terminated Unicode string in <ConfigResp> format.
+ 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.
+
+ Returns:
+ EFI_SUCCESS - The Results is processed successfully.
+ EFI_INVALID_PARAMETER - Configuration is NULL.
+ EFI_NOT_FOUND - Routing data doesn't match any storage in this driver.
+
+--*/
+{
+ return EFI_SUCCESS;
+}
+
+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
+ )
+/*++
+
+ Routine Description:
+ This function processes the results of changes in configuration.
+
+ Arguments:
+ This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ Action - Specifies the type of action taken by the browser.
+ QuestionId - A unique value which is sent to the original exporting driver
+ so that it can identify the type of data to expect.
+ Type - The type of value for the question.
+ Value - A pointer to the data being sent to the original exporting driver.
+ ActionRequest - On return, points to the action requested by the callback function.
+
+ Returns:
+ EFI_SUCCESS - The callback successfully handled the action.
+ EFI_OUT_OF_RESOURCES - Not enough storage is available to hold the variable and its data.
+ EFI_DEVICE_ERROR - The variable could not be saved.
+ EFI_UNSUPPORTED - The specified Action is not supported by the callback.
+
+--*/
+{
+ CHAR8 *LanguageString;
+ CHAR8 *LangCode;
+ CHAR8 Lang[RFC_3066_ENTRY_SIZE];
+#ifdef LANG_SUPPORT
+ CHAR8 OldLang[ISO_639_2_ENTRY_SIZE];
+#endif
+ 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 = GetSupportedLanguages (gFrontPagePrivate.HiiHandle);
+ ASSERT (LanguageString != NULL);
+
+ Index = 0;
+ LangCode = LanguageString;
+ while (*LangCode != 0) {
+ GetNextLanguage (&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
+ );
+
+#ifdef LANG_SUPPORT
+ //
+ // 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
+ );
+ }
+#endif
+
+ 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;
+}
+
+EFI_STATUS
+InitializeFrontPage (
+ BOOLEAN ReInitializeStrings
+ )
+/*++
+
+Routine Description:
+ Initialize HII information for the FrontPage
+
+Arguments:
+ None
+
+Returns:
+ EFI_SUCCESS - The operation is successful.
+ EFI_DEVICE_ERROR - If the dynamic opcode creation failed.
+
+--*/
+{
+ 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 (!ReInitializeStrings) {
+ //
+ // 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 = PreparePackageList (2, &mFrontPageGuid, FrontPageVfrBin, BdsStrings);
+ 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 = GetSupportedLanguages (HiiHandle);
+ ASSERT (LanguageString != NULL);
+
+ OptionCount = 0;
+ LangCode = LanguageString;
+ while (*LangCode != 0) {
+ GetNextLanguage (&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 = IfrLibNewString (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;
+}
+
+EFI_STATUS
+CallFrontPage (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Call the browser and display the front page
+
+Arguments:
+ None
+
+Returns:
+
+--*/
+{
+ 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)
+ );
+
+
+ //
+ // Drop the TPL level from TPL_APPLICATION to TPL_APPLICATION
+ //
+ gBS->RestoreTPL (TPL_APPLICATION);
+
+ 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 ();
+ }
+
+ gBS->RaiseTPL (TPL_APPLICATION);
+ return Status;
+}
+
+EFI_STATUS
+GetProducerString (
+ IN EFI_GUID *ProducerGuid,
+ IN EFI_STRING_ID Token,
+ OUT CHAR16 **String
+ )
+/*++
+
+Routine Description:
+ Acquire the string associated with the ProducerGuid and return it.
+
+Arguments:
+ ProducerGuid - The Guid to search the HII database for
+ Token - The token value of the string to extract
+ String - The string that is extracted
+
+Returns:
+ EFI_SUCCESS - The function returns EFI_SUCCESS always.
+
+--*/
+{
+ EFI_STATUS Status;
+
+ Status = GetStringFromToken (ProducerGuid, Token, String);
+ if (EFI_ERROR (Status)) {
+ *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));
+ }
+
+ return EFI_SUCCESS;
+}
+
+VOID
+ConvertProcessorToString (
+ IN EFI_PROCESSOR_CORE_FREQUENCY_DATA *ProcessorFrequency,
+ OUT CHAR16 **String
+ )
+/*++
+
+Routine Description:
+ Convert Processor Frequency Data to a string
+
+Arguments:
+ ProcessorFrequency - The frequency data to process
+ String - The string that is created
+
+Returns:
+
+--*/
+{
+ 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 ;
+}
+
+VOID
+ConvertMemorySizeToString (
+ IN UINT32 MemorySize,
+ OUT CHAR16 **String
+ )
+/*++
+
+Routine Description:
+ Convert Memory Size to a string
+
+Arguments:
+ MemorySize - The size of the memory to process
+ String - The string that is created
+
+Returns:
+
+--*/
+{
+ CHAR16 *StringBuffer;
+
+ StringBuffer = AllocateZeroPool (0x20);
+ ASSERT (StringBuffer != NULL);
+ UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, MemorySize, 6);
+ StrCat (StringBuffer, L" MB RAM");
+
+ *String = (CHAR16 *) StringBuffer;
+
+ return ;
+}
+
+VOID
+UpdateFrontPageStrings (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Update the banner information for the Front Page based on DataHub information
+
+Arguments:
+ None
+
+Returns:
+
+--*/
+{
+ 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);
+ IfrLibSetString (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);
+ IfrLibSetString (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);
+ IfrLibSetString (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);
+ IfrLibSetString (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);
+ IfrLibSetString (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 ;
+}
+
+EFI_STATUS
+WaitForSingleEvent (
+ IN EFI_EVENT Event,
+ IN UINT64 Timeout OPTIONAL
+ )
+/*++
+
+Routine Description:
+ Function waits for a given event to fire, or for an optional timeout to expire.
+
+Arguments:
+ Event - The event to wait for
+ Timeout - An optional timeout value in 100 ns units.
+
+Returns:
+ EFI_SUCCESS - Event fired before Timeout expired.
+ EFI_TIME_OUT - Timout expired before Event fired..
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_EVENT TimerEvent;
+ EFI_EVENT WaitList[2];
+
+ if (Timeout) {
+ //
+ // 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;
+}
+
+EFI_STATUS
+ShowProgress (
+ IN UINT16 TimeoutDefault
+ )
+/*++
+
+Routine Description:
+ Function show progress bar to wait for user input.
+
+Arguments:
+ TimeoutDefault - The fault time out value before the system
+ continue to boot.
+
+Returns:
+ EFI_SUCCESS - User pressed some key except "Enter"
+ EFI_TIME_OUT - Timout expired or user press "Enter"
+
+--*/
+{
+ 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;
+ }
+
+ 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) {
+ 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;
+}
+
+VOID
+PlatformBdsEnterFrontPage (
+ IN UINT16 TimeoutDefault,
+ IN BOOLEAN ConnectAllHappened
+ )
+/*++
+
+Routine Description:
+ 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.
+
+Arguments:
+ TimeoutDefault - The fault time out value before the system
+ continue to boot.
+ ConnectAllHappened - The indicater to check if the connect all have
+ already happended.
+
+Returns:
+ None
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;
+
+ //
+ // Indicate if we need connect all in the platform setup
+ //
+ if (ConnectAllHappened) {
+ gConnectAllHappened = TRUE;
+ }
+
+ if (TimeoutDefault != 0xffff) {
+ gBS->RestoreTPL (TPL_APPLICATION);
+ Status = ShowProgress (TimeoutDefault);
+ gBS->RaiseTPL (TPL_APPLICATION);
+
+ if (EFI_ERROR (Status)) {
+ //
+ // Timeout or user press enter to continue
+ //
+ goto Exit;
+ }
+ }
+
+ do {
+
+ InitializeFrontPage (TRUE);
+
+ //
+ // Update Front Page strings
+ //
+ UpdateFrontPageStrings ();
+
+ gCallbackKey = 0;
+ PERF_START (0, "BdsTimeOut", "BDS", 0);
+ Status = CallFrontPage ();
+ PERF_END (0, "BdsTimeOut", "BDS", 0);
+
+ //
+ // 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
+ //
+ gBS->RestoreTPL (TPL_APPLICATION);
+ SetupResetReminder ();
+ gBS->RaiseTPL (TPL_APPLICATION);
+
+Exit:
+ //
+ // Automatically load current entry
+ // Note: The following lines of code only execute when Auto boot
+ // takes affect
+ //
+ Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);
+ ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);
+
+}
diff --git a/MdeModulePkg/Universal/BdsDxe/FrontPage.h b/MdeModulePkg/Universal/BdsDxe/FrontPage.h new file mode 100644 index 0000000000..fc01d16d54 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/FrontPage.h @@ -0,0 +1,149 @@ +/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ FrontPage.h
+
+Abstract:
+
+ FrontPage routines to handle the callbacks and browser calls
+
+Revision History
+
+--*/
+
+#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 EFI_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;
+
+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
+ );
+
+EFI_STATUS
+EFIAPI
+FakeRouteConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+ );
+
+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
+ );
+
+EFI_STATUS
+InitializeFrontPage (
+ IN BOOLEAN ReInitializeStrings
+ );
+
+EFI_STATUS
+GetProducerString (
+ IN EFI_GUID *ProducerGuid,
+ IN EFI_STRING_ID Token,
+ OUT CHAR16 **String
+ );
+
+BOOLEAN
+TimeCompare (
+ IN EFI_TIME *FirstTime,
+ IN EFI_TIME *SecondTime
+ );
+
+VOID
+PlatformBdsEnterFrontPage (
+ IN UINT16 TimeoutDefault,
+ IN BOOLEAN ConnectAllHappened
+ );
+
+#endif // _FRONT_PAGE_H_
+
diff --git a/MdeModulePkg/Universal/BdsDxe/FrontPageStrings.uni b/MdeModulePkg/Universal/BdsDxe/FrontPageStrings.uni Binary files differnew file mode 100644 index 0000000000..b22fa5aa2a --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/FrontPageStrings.uni diff --git a/MdeModulePkg/Universal/BdsDxe/FrontPageVfr.Vfr b/MdeModulePkg/Universal/BdsDxe/FrontPageVfr.Vfr new file mode 100644 index 0000000000..e7332aadbf --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/FrontPageVfr.Vfr @@ -0,0 +1,145 @@ +// *++
+//
+// Copyright (c) 2007, Intel Corporation
+// 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.
+//
+// Module Name:
+//
+// FrontPageVfr.vfr
+//
+// Abstract:
+//
+// Browser formset.
+//
+// Revision History:
+//
+// --*/
+
+#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;
diff --git a/MdeModulePkg/Universal/BdsDxe/Hotkey.c b/MdeModulePkg/Universal/BdsDxe/Hotkey.c new file mode 100644 index 0000000000..ea4bbf5578 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/Hotkey.c @@ -0,0 +1,769 @@ +/*++
+
+Copyright (c) 2007 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ Hotkey.h
+
+Abstract:
+
+ Provides a way for 3rd party applications to register themselves for launch by the
+ Boot Manager based on hot key
+
+Revision History
+
+--*/
+
+#include "Hotkey.h"
+
+
+LIST_ENTRY mHotkeyList = INITIALIZE_LIST_HEAD_VARIABLE (mHotkeyList);
+BOOLEAN mHotkeyCallbackPending = FALSE;
+EFI_EVENT mHotkeyEvent;
+VOID *mHotkeyRegistration;
+
+
+BOOLEAN
+IsKeyOptionValid (
+ IN EFI_KEY_OPTION *KeyOption
+)
+/*++
+
+Routine Description:
+
+ Check if the Key Option is valid or not.
+
+Arguments:
+
+ KeyOption - The Hot Key Option to be checked.
+
+Returns:
+
+ TRUE - The Hot Key Option is valid.
+ FALSE - The Hot Key Option is invalid.
+
+--*/
+{
+ 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);
+}
+
+EFI_STATUS
+RegisterHotkey (
+ IN EFI_KEY_OPTION *KeyOption,
+ OUT UINT16 *KeyOptionNumber
+)
+/*++
+
+Routine Description:
+
+ Create Key#### for the given hotkey.
+
+Arguments:
+
+ KeyOption - The Hot Key Option to be added.
+ KeyOptionNumber - The key option number for Key#### (optional).
+
+Returns:
+
+ EFI_SUCCESS - Register hotkey successfully.
+ EFI_INVALID_PARAMETER - The hotkey option is invalid.
+
+--*/
+{
+ 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->KeyOptions.PackedValue) * sizeof (EFI_INPUT_KEY);
+ UpdateBootOption = FALSE;
+
+ //
+ // check whether HotKey conflict with keys used by Setup Browser
+ //
+
+ KeyOrder = BdsLibGetVariableAndSize (
+ VarKeyOrder,
+ &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->KeyOptions.PackedValue == TempOption->KeyOptions.PackedValue) {
+ if (GET_KEY_CODE_COUNT (KeyOption->KeyOptions.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)) {
+ gBS->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) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (KeyOrder != NULL) {
+ CopyMem (NewKeyOrder, KeyOrder, KeyOrderSize);
+ }
+
+ NewKeyOrder[Index] = RegisterOptionNumber;
+
+ Status = gRT->SetVariable (
+ VarKeyOrder,
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ KeyOrderSize,
+ NewKeyOrder
+ );
+
+ FreePool (KeyOrder);
+ FreePool (NewKeyOrder);
+
+ return Status;
+}
+
+EFI_STATUS
+UnregisterHotkey (
+ IN UINT16 KeyOptionNumber
+)
+/*++
+
+Routine Description:
+
+ Delete Key#### for the given Key Option number.
+
+Arguments:
+
+ KeyOptionNumber - Key option number for Key####
+
+Returns:
+
+ EFI_SUCCESS - Unregister hotkey successfully.
+ EFI_NOT_FOUND - No Key#### is found for the given Key Option number.
+
+--*/
+{
+ 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 (
+ VarKeyOrder,
+ &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 (
+ VarKeyOrder,
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ KeyOrderSize,
+ KeyOrder
+ );
+
+ FreePool (KeyOrder);
+
+ return Status;
+}
+
+EFI_STATUS
+HotkeyCallback (
+ IN EFI_KEY_DATA *KeyData
+)
+/*++
+
+Routine Description:
+
+ This is the common notification function for HotKeys, it will be registered
+ with SimpleTextInEx protocol interface - RegisterKeyNotify() of ConIn handle.
+
+Arguments:
+
+ KeyData - A pointer to a buffer that is filled in with the keystroke
+ information for the key that was pressed.
+
+Returns:
+
+ EFI_SUCCESS - KeyData is successfully processed.
+
+--*/
+{
+ BOOLEAN HotkeyCatched;
+ LIST_ENTRY BootLists;
+ LIST_ENTRY *Link;
+ BDS_HOTKEY_OPTION *Hotkey;
+ UINT16 Buffer[10];
+ BDS_COMMON_OPTION *BootOption;
+ UINTN ExitDataSize;
+ CHAR16 *ExitData;
+ EFI_TPL OldTpl;
+ 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?
+ //
+ 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);
+ BootOption->BootCurrent = Hotkey->BootOptionNumber;
+ BdsLibConnectDevicePath (BootOption->DevicePath);
+
+ //
+ // Clear the screen before launch this BootOption
+ //
+ gST->ConOut->Reset (gST->ConOut, FALSE);
+
+ //
+ // BdsLibBootViaBootOption() is expected to be invoked at TPL level TPL_APPLICATION,
+ // so raise the TPL to TPL_APPLICATION first, then restore it
+ //
+ OldTpl = gBS->RaiseTPL (TPL_APPLICATION);
+
+ mHotkeyCallbackPending = TRUE;
+ Status = BdsLibBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData);
+ mHotkeyCallbackPending = FALSE;
+
+ gBS->RestoreTPL (OldTpl);
+
+ 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;
+}
+
+EFI_STATUS
+HotkeyRegisterNotify (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleTextInEx
+)
+/*++
+
+Routine Description:
+
+ Register the common HotKey notify function to given SimpleTextInEx protocol instance.
+
+Arguments:
+
+ SimpleTextInEx - Simple Text Input Ex protocol instance
+
+Returns:
+
+ EFI_SUCCESS - Register hotkey notification function successfully.
+ EFI_OUT_OF_RESOURCES - Unable to allocate necessary data structures.
+
+--*/
+{
+ 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;
+}
+
+VOID
+EFIAPI
+HotkeyEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+ Callback function for SimpleTextInEx protocol install events
+
+Arguments:
+
+ Standard event notification function arguments:
+ Event - the event that is signaled.
+ Context - not used here.
+
+Returns:
+
+--*/
+{
+ 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);
+ }
+}
+
+EFI_STATUS
+HotkeyInsertList (
+ IN EFI_KEY_OPTION *KeyOption
+)
+/*++
+
+Routine Description:
+
+ Insert Key Option to hotkey list.
+
+Arguments:
+
+ KeyOption - The Hot Key Option to be added to hotkey list.
+
+Returns:
+
+ EFI_SUCCESS - Add to hotkey list success.
+
+--*/
+{
+ 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->KeyOptions.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;
+}
+
+EFI_STATUS
+InitializeHotkeyService (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Process all the "Key####" variables, associate Hotkeys with corresponding Boot Options.
+
+Arguments:
+
+ None
+
+Returns:
+
+ EFI_SUCCESS - Hotkey services successfully initialized.
+
+--*/
+{
+ 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 (
+ VarKeyOrder,
+ &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;
+}
+
diff --git a/MdeModulePkg/Universal/BdsDxe/Hotkey.h b/MdeModulePkg/Universal/BdsDxe/Hotkey.h new file mode 100644 index 0000000000..87059e12e0 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/Hotkey.h @@ -0,0 +1,117 @@ +/*++
+
+Copyright (c) 2007 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ Hotkey.h
+
+Abstract:
+
+ Provides a way for 3rd party applications to register themselves for launch by the
+ Boot Manager based on hot key
+
+Revision History
+
+--*/
+
+#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 EFI_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 VarKeyOrder L"KeyOrder"
+
+EFI_STATUS
+RegisterHotkey (
+ IN EFI_KEY_OPTION *KeyOption,
+ OUT UINT16 *KeyOptionNumber
+)
+/*++
+
+Routine Description:
+
+ Create Key#### for the given hotkey.
+
+Arguments:
+
+ KeyOption - The Hot Key Option to be added.
+ KeyOptionNumber - The key option number for Key#### (optional).
+
+Returns:
+
+ EFI_SUCCESS - Register hotkey successfully.
+ EFI_INVALID_PARAMETER - The hotkey option is invalid.
+
+--*/
+;
+
+EFI_STATUS
+UnregisterHotkey (
+ IN UINT16 KeyOptionNumber
+)
+/*++
+
+Routine Description:
+
+ Delete Key#### for the given Key Option number.
+
+Arguments:
+
+ KeyOptionNumber - Key option number for Key####
+
+Returns:
+
+ EFI_SUCCESS - Unregister hotkey successfully.
+ EFI_NOT_FOUND - No Key#### is found for the given Key Option number.
+
+--*/
+;
+
+
+EFI_STATUS
+InitializeHotkeyService (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Process all the "Key####" variables, associate Hotkeys with corresponding Boot Options.
+
+Arguments:
+
+ None
+
+Returns:
+
+ EFI_SUCCESS - Hotkey services successfully initialized.
+
+--*/
+;
+
+#endif
diff --git a/MdeModulePkg/Universal/BdsDxe/HwErrRecSupport.c b/MdeModulePkg/Universal/BdsDxe/HwErrRecSupport.c new file mode 100644 index 0000000000..339361e195 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/HwErrRecSupport.c @@ -0,0 +1,62 @@ +/*++
+
+Copyright (c) 2007, Intel Corporation
+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.
+
+Module Name:
+
+ HwErrRecSupport.c
+
+Abstract:
+
+ Set the level of support for Hardware Error Record Persistence that is
+ implemented by the platform.
+
+Revision History
+
+--*/
+
+#include "HwErrRecSupport.h"
+
+VOID
+InitializeHwErrRecSupport (
+ IN UINT16 HwErrRecSupportLevel
+ )
+/*++
+
+ Routine Description:
+ 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.
+
+ Arguments:
+ 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.
+
+ Returns:
+
+--*/
+{
+ 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"));
+ }
+
+}
diff --git a/MdeModulePkg/Universal/BdsDxe/HwErrRecSupport.h b/MdeModulePkg/Universal/BdsDxe/HwErrRecSupport.h new file mode 100644 index 0000000000..fdd62bad0b --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/HwErrRecSupport.h @@ -0,0 +1,53 @@ +/*++
+
+Copyright (c) 2007, Intel Corporation
+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.
+
+Module Name:
+
+ HwErrRecSupport.h
+
+Abstract:
+
+ Set the level of support for Hardware Error Record Persistence that is
+ implemented by the platform.
+
+Revision History
+
+--*/
+
+#ifndef _HW_ERR_REC_SUPPORT_H
+#define _HW_ERR_REC_SUPPORT_H
+
+#include "Bds.h"
+
+VOID
+InitializeHwErrRecSupport (
+ IN UINT16 HwErrRecSupportLevel
+ )
+/*++
+
+ Routine Description:
+ 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.
+
+ Arguments:
+ 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.
+
+ Returns:
+
+--*/
+;
+
+#endif
diff --git a/MdeModulePkg/Universal/BdsDxe/Language.c b/MdeModulePkg/Universal/BdsDxe/Language.c new file mode 100644 index 0000000000..8a99e9bf82 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/Language.c @@ -0,0 +1,420 @@ +/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ Language.c
+
+Abstract:
+
+ Language settings
+
+Revision History
+
+--*/
+
+#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 PreparePackageList()
+ //
+ 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
+ }
+ }
+ }
+};
+
+VOID
+ExportFonts (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Routine to export glyphs to the HII database. This is in addition to whatever is defined in the Graphics Console driver.
+
+Arguments:
+ None
+
+Returns:
+
+--*/
+{
+ 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 = PreparePackageList (1, &mFontPackageGuid, &mFontBin);
+ ASSERT (PackageList != NULL);
+
+ gHiiDatabase->NewPackageList (gHiiDatabase, PackageList, DriverHandle, &HiiHandle);
+ FreePool (PackageList);
+}
+
+VOID
+InitializeLanguage (
+ BOOLEAN LangCodesSettingRequired
+ )
+/*++
+
+Routine Description:
+ Determine the current language that will be used
+ based on language related EFI Variables
+
+Arguments:
+ LangCodesSettingRequired - If required to set LangCode variable
+
+Returns:
+
+--*/
+{
+ 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 (PcdUefiVariableDefaultLangDepricate)) {
+ //
+ // 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 (PcdUefiVariableDefaultLangDepricate)) {
+ //
+ // 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
+ );
+ }
+}
diff --git a/MdeModulePkg/Universal/BdsDxe/Language.h b/MdeModulePkg/Universal/BdsDxe/Language.h new file mode 100644 index 0000000000..586a59a555 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/Language.h @@ -0,0 +1,47 @@ +/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ Language.h
+
+Abstract:
+
+ Language setting
+
+Revision History
+
+--*/
+
+#ifndef _LANGUAGE_H
+#define _LANGUAGE_H
+
+#include "String.h"
+
+VOID
+InitializeLanguage (
+ BOOLEAN LangCodesSettingRequired
+ )
+/*++
+
+Routine Description:
+ Determine the current language that will be used
+ based on language related EFI Variables
+
+Arguments:
+ LangCodesSettingRequired - If required to set LangCode variable
+
+Returns:
+
+--*/
+;
+
+#endif // _LANGUAGE_H_
diff --git a/MdeModulePkg/Universal/BdsDxe/MemoryTest.c b/MdeModulePkg/Universal/BdsDxe/MemoryTest.c new file mode 100644 index 0000000000..b9f24e6d4b --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/MemoryTest.c @@ -0,0 +1,431 @@ +/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ MemoryTest.c
+
+Abstract:
+
+ Perform the platform memory test
+
+--*/
+
+#include "Bds.h"
+#include "String.h"
+
+//
+// BDS Platform Functions
+//
+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
+ )
+/*++
+
+Routine Description:
+
+ Show progress bar with title above it. It only works in Graphics mode.
+
+Arguments:
+
+ TitleForeground - Foreground color for Title.
+ TitleBackground - Background color for Title.
+ Title - Title above progress bar.
+ ProgressColor - Progress bar color.
+ Progress - Progress (0-100)
+
+Returns:
+
+ EFI_STATUS - Success update the progress bar
+
+--*/
+{
+ 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)) {
+ GraphicsOutput = NULL;
+
+ Status = gBS->HandleProtocol (
+ gST->ConsoleOutHandle,
+ &gEfiUgaDrawProtocolGuid,
+ (VOID **) &UgaDraw
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ if (GraphicsOutput != NULL) {
+ SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;
+ SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;
+ } else {
+ Status = UgaDraw->GetMode (
+ UgaDraw,
+ &SizeOfX,
+ &SizeOfY,
+ &ColorDepth,
+ &RefreshRate
+ );
+ if (EFI_ERROR (Status)) {
+ 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 - GLYPH_HEIGHT - 1,
+ SizeOfX,
+ SizeOfY - (PosY - GLYPH_HEIGHT - 1),
+ SizeOfX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+ );
+ } else {
+ Status = UgaDraw->Blt (
+ UgaDraw,
+ (EFI_UGA_PIXEL *) &Color,
+ EfiUgaVideoFill,
+ 0,
+ 0,
+ 0,
+ PosY - GLYPH_HEIGHT - 1,
+ SizeOfX,
+ SizeOfY - (PosY - GLYPH_HEIGHT - 1),
+ SizeOfX * sizeof (EFI_UGA_PIXEL)
+ );
+ }
+ }
+ //
+ // 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 {
+ Status = UgaDraw->Blt (
+ UgaDraw,
+ (EFI_UGA_PIXEL *) &ProgressColor,
+ EfiUgaVideoFill,
+ 0,
+ 0,
+ PosX,
+ PosY,
+ BlockWidth - 1,
+ BlockHeight,
+ (BlockWidth) * sizeof (EFI_UGA_PIXEL)
+ );
+ }
+ }
+
+ PrintXY (
+ (SizeOfX - StrLen (Title) * GLYPH_WIDTH) / 2,
+ PosY - GLYPH_HEIGHT - 1,
+ &TitleForeground,
+ &TitleBackground,
+ Title
+ );
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+BdsMemoryTest (
+ IN EXTENDMEM_COVERAGE_LEVEL Level
+ )
+/*++
+
+Routine Description:
+
+ Perform the memory test base on the memory test intensive level,
+ and update the memory resource.
+
+Arguments:
+
+ Level - The memory test intensive level.
+
+Returns:
+
+ EFI_STATUS - Success test all the system memory and update
+ the memory resource
+
+--*/
+{
+ EFI_STATUS Status;
+ 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;
+
+ if (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;
+}
diff --git a/MdeModulePkg/Universal/BdsDxe/String.c b/MdeModulePkg/Universal/BdsDxe/String.c new file mode 100644 index 0000000000..84f9f96edf --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/String.c @@ -0,0 +1,104 @@ +/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ String.c
+
+Abstract:
+
+ String support
+
+--*/
+
+#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
+};
+
+EFI_STATUS
+InitializeStringSupport (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Initialize HII global accessor for string support
+
+Arguments:
+ None
+
+Returns:
+ EFI_SUCCESS - String support initialize success.
+
+--*/
+{
+ 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 = PreparePackageList (1, &mBdsStringPackGuid, &BdsStrings);
+ ASSERT (PackageList != NULL);
+
+ Status = gHiiDatabase->NewPackageList (
+ gHiiDatabase,
+ PackageList,
+ DriverHandle,
+ &gStringPackHandle
+ );
+
+ FreePool (PackageList);
+ return Status;
+}
+
+CHAR16 *
+GetStringById (
+ IN EFI_STRING_ID Id
+ )
+/*++
+
+Routine Description:
+ Get string by string id from HII Interface
+
+Arguments:
+ Id - String ID.
+
+Returns:
+ CHAR16 * - String from ID.
+ NULL - If error occurs.
+
+--*/
+{
+ CHAR16 *String;
+
+ String = NULL;
+ GetStringFromHandle (gStringPackHandle, Id, &String);
+
+ return String;
+}
diff --git a/MdeModulePkg/Universal/BdsDxe/String.h b/MdeModulePkg/Universal/BdsDxe/String.h new file mode 100644 index 0000000000..14c42a95d0 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/String.h @@ -0,0 +1,61 @@ +/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+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.
+
+Module Name:
+
+ String.h
+
+Abstract:
+
+ String support
+
+Revision History
+
+--*/
+
+#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 BdsStrings[];
+
+//
+// String Definition Guid for BDS Platform
+//
+#define EFI_BDS_PLATFORM_GUID \
+ { \
+ 0x7777E939, 0xD57E, 0x4DCB, 0xA0, 0x8E, 0x64, 0xD7, 0x98, 0x57, 0x1E, 0x0F \
+ }
+
+CHAR16 *
+GetStringById (
+ IN EFI_STRING_ID Id
+ );
+
+EFI_STATUS
+InitializeStringSupport (
+ VOID
+ );
+
+EFI_STATUS
+CallFrontPage (
+ VOID
+ );
+
+#endif // _STRING_H_
diff --git a/MdeModulePkg/Universal/BdsDxe/Strings.uni b/MdeModulePkg/Universal/BdsDxe/Strings.uni Binary files differnew file mode 100644 index 0000000000..c83bb8a991 --- /dev/null +++ b/MdeModulePkg/Universal/BdsDxe/Strings.uni |