From 94774441154ca4e11ab028490c66f1ef6105d267 Mon Sep 17 00:00:00 2001 From: vanjeff Date: Thu, 28 Jun 2007 11:29:10 +0000 Subject: [PATCH] add English.inf, EdkFvbServiceLib.inf and Variable.inf git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2842 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/Include/Common/FlashMap.h | 112 ++ .../Library/EdkFvbServiceLib/CommonHeader.h | 49 + .../EdkFvbServiceLib/EdkFvbServiceLib.inf | 123 ++ .../EdkFvbServiceLib/EdkFvbServiceLib.msa | 81 + .../Library/EdkFvbServiceLib/EntryPoint.c | 54 + MdeModulePkg/Library/EdkFvbServiceLib/Fvb.h | 44 + MdeModulePkg/MdeModulePkg.dsc | 23 +- .../Universal/Disk/DiskIo/Dxe/DiskIo.inf | 2 +- .../Universal/Disk/DiskIo/Dxe/DiskIo.msa | 2 +- .../English/Dxe/CommonHeader.h | 35 + .../UnicodeCollation/English/Dxe/English.inf | 93 ++ .../UnicodeCollation/English/Dxe/English.msa | 55 + .../English/Dxe/UnicodeCollationEng.c | 479 ++++++ .../English/Dxe/UnicodeCollationEng.h | 117 ++ .../VariableRuntimeDxe/CommonHeader.h | 46 + .../VariableRuntimeDxe/InitVariable.c | 234 +++ .../Universal/VariableRuntimeDxe/Variable.c | 1479 +++++++++++++++++ .../Universal/VariableRuntimeDxe/Variable.dxs | 32 + .../Universal/VariableRuntimeDxe/Variable.h | 158 ++ .../Universal/VariableRuntimeDxe/Variable.inf | 123 ++ .../Universal/VariableRuntimeDxe/Variable.msa | 108 ++ .../Universal/VariableRuntimeDxe/reclaim.c | 242 +++ .../Universal/VariableRuntimeDxe/reclaim.h | 50 + 23 files changed, 3738 insertions(+), 3 deletions(-) create mode 100644 MdeModulePkg/Include/Common/FlashMap.h create mode 100644 MdeModulePkg/Library/EdkFvbServiceLib/CommonHeader.h create mode 100644 MdeModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.inf create mode 100644 MdeModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.msa create mode 100644 MdeModulePkg/Library/EdkFvbServiceLib/EntryPoint.c create mode 100644 MdeModulePkg/Library/EdkFvbServiceLib/Fvb.h create mode 100644 MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/CommonHeader.h create mode 100644 MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/English.inf create mode 100644 MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/English.msa create mode 100644 MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/UnicodeCollationEng.c create mode 100644 MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/UnicodeCollationEng.h create mode 100644 MdeModulePkg/Universal/VariableRuntimeDxe/CommonHeader.h create mode 100644 MdeModulePkg/Universal/VariableRuntimeDxe/InitVariable.c create mode 100644 MdeModulePkg/Universal/VariableRuntimeDxe/Variable.c create mode 100644 MdeModulePkg/Universal/VariableRuntimeDxe/Variable.dxs create mode 100644 MdeModulePkg/Universal/VariableRuntimeDxe/Variable.h create mode 100644 MdeModulePkg/Universal/VariableRuntimeDxe/Variable.inf create mode 100644 MdeModulePkg/Universal/VariableRuntimeDxe/Variable.msa create mode 100644 MdeModulePkg/Universal/VariableRuntimeDxe/reclaim.c create mode 100644 MdeModulePkg/Universal/VariableRuntimeDxe/reclaim.h diff --git a/MdeModulePkg/Include/Common/FlashMap.h b/MdeModulePkg/Include/Common/FlashMap.h new file mode 100644 index 0000000000..0473a69355 --- /dev/null +++ b/MdeModulePkg/Include/Common/FlashMap.h @@ -0,0 +1,112 @@ +/*++ + +Copyright (c) 2006, 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: + + FlashMap.h + +Abstract: + + FlashMap PPI defined in Tiano + + This code abstracts FlashMap access + +--*/ + +#ifndef __COMMON_FLASHMAP_H__ +#define __COMMON_FLASHMAP_H__ + +#include +// +// Definition for flash map GUIDed HOBs +// +typedef UINT32 EFI_FLASH_AREA_ATTRIBUTES; + +#define EFI_FLASH_AREA_FV 0x0001 +#define EFI_FLASH_AREA_SUBFV 0x0002 +#define EFI_FLASH_AREA_MEMMAPPED_FV 0x0004 +#define EFI_FLASH_AREA_REQUIRED 0x0008 +#define EFI_FLASH_AREA_CORRUPT 0x0010 + +typedef UINT8 EFI_FLASH_AREA_TYPE; + +#define EFI_FLASH_AREA_RECOVERY_BIOS 0x0 // Recovery code +#define EFI_FLASH_AREA_MAIN_BIOS 0x1 // Regular BIOS code +#define EFI_FLASH_AREA_PAL_B 0x2 // PAL-B +#define EFI_FLASH_AREA_RESERVED_03 0x3 // Reserved for backwards compatibility +#define EFI_FLASH_AREA_RESERVED_04 0x4 // Reserved for backwards compatibility +#define EFI_FLASH_AREA_DMI_FRU 0x5 // DMI FRU information +#define EFI_FLASH_AREA_OEM_BINARY 0x6 // OEM Binary Code/data +#define EFI_FLASH_AREA_RESERVED_07 0x7 // Reserved for backwards compatibility +#define EFI_FLASH_AREA_RESERVED_08 0x8 // Reserved for backwards compatibility +#define EFI_FLASH_AREA_RESERVED_09 0x9 // Reserved for backwards compatibility +#define EFI_FLASH_AREA_RESERVED_0A 0x0a // Reserved for backwards compatibility +#define EFI_FLASH_AREA_EFI_VARIABLES 0x0b // EFI variables +#define EFI_FLASH_AREA_MCA_LOG 0x0c // MCA error log +#define EFI_FLASH_AREA_SMBIOS_LOG 0x0d // SMBIOS error log +#define EFI_FLASH_AREA_FTW_BACKUP 0x0e // A backup block during FTW operations +#define EFI_FLASH_AREA_FTW_STATE 0x0f // State information during FTW operations +#define EFI_FLASH_AREA_UNUSED 0x0fd // Not used +#define EFI_FLASH_AREA_GUID_DEFINED 0x0fe // Usage defined by a GUID +#pragma pack(1) +// +// An individual sub-area Entry. +// A single flash area may consist of more than one sub-area. +// +typedef struct { + EFI_FLASH_AREA_ATTRIBUTES Attributes; + UINT32 Reserved; + EFI_PHYSICAL_ADDRESS Base; + EFI_PHYSICAL_ADDRESS Length; + EFI_GUID FileSystem; +} EFI_FLASH_SUBAREA_ENTRY; + +typedef struct { + UINT8 Reserved[3]; + EFI_FLASH_AREA_TYPE AreaType; + EFI_GUID AreaTypeGuid; + UINT32 NumEntries; + EFI_FLASH_SUBAREA_ENTRY Entries[1]; +} EFI_FLASH_MAP_ENTRY_DATA; + +typedef struct { + EFI_HOB_GENERIC_HEADER Header; + EFI_GUID Name; + UINT8 Reserved[3]; + EFI_FLASH_AREA_TYPE AreaType; + EFI_GUID AreaTypeGuid; + UINT32 NumEntries; + EFI_FLASH_SUBAREA_ENTRY Entries[1]; +} EFI_HOB_FLASH_MAP_ENTRY_TYPE; + +// +// Internal definitions +// +typedef struct { + UINT8 Reserved[3]; + EFI_FLASH_AREA_TYPE AreaType; + EFI_GUID AreaTypeGuid; + UINT32 NumberOfEntries; + EFI_FLASH_SUBAREA_ENTRY SubAreaData; +} EFI_FLASH_AREA_HOB_DATA; + +typedef struct { + UINTN Base; + UINTN Length; + EFI_FLASH_AREA_ATTRIBUTES Attributes; + EFI_FLASH_AREA_TYPE AreaType; + UINT8 Reserved[3]; + EFI_GUID AreaTypeGuid; +} EFI_FLASH_AREA_DATA; + +#pragma pack() + +#endif diff --git a/MdeModulePkg/Library/EdkFvbServiceLib/CommonHeader.h b/MdeModulePkg/Library/EdkFvbServiceLib/CommonHeader.h new file mode 100644 index 0000000000..01f5eb96e5 --- /dev/null +++ b/MdeModulePkg/Library/EdkFvbServiceLib/CommonHeader.h @@ -0,0 +1,49 @@ +/**@file + Common header file shared by all source files. + + This file includes package header files, library classes and protocol, PPI & GUID definitions. + + Copyright (c) 2006 - 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. +**/ + +#ifndef __COMMON_HEADER_H_ +#define __COMMON_HEADER_H_ + + +// +// The package level header files this module uses +// +#include +// +// The protocols, PPI and GUID defintions for this module +// +#include +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include + +// +// Declaration for callback Event. +// +VOID +EFIAPI +FvbVirtualAddressChangeNotifyEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +#endif diff --git a/MdeModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.inf b/MdeModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.inf new file mode 100644 index 0000000000..9a89bfb898 --- /dev/null +++ b/MdeModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.inf @@ -0,0 +1,123 @@ +#/** @file +# FvbService Library for UEFI drivers +# +# This library instance provide sevice functions to access Firmware Volume Block protocol. +# Copyright (c) 2006 - 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. +# +# +#**/ + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = EdkFvbServiceLib + FILE_GUID = bd4d540e-04b0-4b10-8fd5-4a7bb533cf67 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = EdkFvbServiceLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + CONSTRUCTOR = FvbLibInitialize + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF +# +# VIRTUAL_ADDRESS_MAP_CALLBACK = FvbVirtualAddressChangeNotifyEvent +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources.common] + Fvb.h + +[Sources.Ia32] + Ia32/Fvb.c + +[Sources.X64] + x64/Fvb.c + +[Sources.IPF] + Ipf/Fvb.c + + +################################################################################ +# +# Includes Section - list of Include locations that are required for +# this module. +# +################################################################################ + +[Includes] + $(WORKSPACE)/MdePkg/Include/Library + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + +################################################################################ +# +# Library Class Section - list of Library Classes that are required for +# this module. +# +################################################################################ + +[LibraryClasses.IA32] + UefiBootServicesTableLib + UefiRuntimeLib + BaseMemoryLib + DebugLib + BaseLib + UefiLib + +[LibraryClasses.X64] + UefiBootServicesTableLib + UefiRuntimeLib + BaseMemoryLib + DebugLib + BaseLib + UefiLib + + +################################################################################ +# +# Protocol C Name Section - list of Protocol and Protocol Notify C Names +# that this module uses or produces. +# +################################################################################ + +[Protocols] + gEfiFirmwareVolumeBlockProtocolGuid # PROTOCOL_NOTIFY SOMETIMES_CONSUMED + +[Protocols.IA32] + gEfiFvbExtensionProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiFirmwareVolumeBlockProtocolGuid # PROTOCOL ALWAYS_CONSUMED + +[Protocols.X64] + gEfiFvbExtensionProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiFirmwareVolumeBlockProtocolGuid # PROTOCOL ALWAYS_CONSUMED + diff --git a/MdeModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.msa b/MdeModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.msa new file mode 100644 index 0000000000..2aa7abb34d --- /dev/null +++ b/MdeModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.msa @@ -0,0 +1,81 @@ + + + + EdkFvbServiceLib + DXE_DRIVER + bd4d540e-04b0-4b10-8fd5-4a7bb533cf67 + 1.0 + FvbService Library for UEFI drivers + This library instance provide sevice functions to access Firmware Volume Block protocol. + Copyright (c) 2006 - 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. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF + false + EdkFvbServiceLib + + + + EdkFvbServiceLib + + + UefiLib + + + BaseLib + + + DebugLib + + + BaseMemoryLib + + + UefiRuntimeLib + + + UefiBootServicesTableLib + + + EdkDxeSalLib + + + + Fvb.h + Ia32/Fvb.c + x64/Fvb.c + Ipf/Fvb.c + + + + + + + + gEfiFirmwareVolumeBlockProtocolGuid + + + gEfiFvbExtensionProtocolGuid + + + gEfiFirmwareVolumeBlockProtocolGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + FvbLibInitialize + + + FvbVirtualAddressChangeNotifyEvent + + + \ No newline at end of file diff --git a/MdeModulePkg/Library/EdkFvbServiceLib/EntryPoint.c b/MdeModulePkg/Library/EdkFvbServiceLib/EntryPoint.c new file mode 100644 index 0000000000..9cdf594c78 --- /dev/null +++ b/MdeModulePkg/Library/EdkFvbServiceLib/EntryPoint.c @@ -0,0 +1,54 @@ +/**@file + Entry Point Source file. + + This file contains the user entry point + + Copyright (c) 2006 - 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. +**/ + +// +// Include common header file for this module. +// +#include "CommonHeader.h" + +// +// Event for Exit Boot Services Callback +// +STATIC EFI_EVENT mExitBootServicesEvent = NULL; + +/** + The user Entry Point for module EdkFvbServiceLib. The user code starts with this function. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +InitializeEdkFvbServiceLib( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = gBS->CreateEvent ( + EVT_SIGNAL_EXIT_BOOT_SERVICES, + TPL_NOTIFY, + FvbVirtualAddressChangeNotifyEvent, + NULL, + &mExitBootServicesEvent + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/MdeModulePkg/Library/EdkFvbServiceLib/Fvb.h b/MdeModulePkg/Library/EdkFvbServiceLib/Fvb.h new file mode 100644 index 0000000000..0f17932b00 --- /dev/null +++ b/MdeModulePkg/Library/EdkFvbServiceLib/Fvb.h @@ -0,0 +1,44 @@ +/** + The internal header file for EdkFvbServiceLib. + +Copyright (c) 2006 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 + +**/ + +#ifndef __FVB_H__ +#define __FVB_H__ + +// +// The package level header files this module uses +// +#include +// +// The protocols, PPI and GUID defintions for this module +// +#include +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include + +#define MAX_FVB_COUNT 16 + +typedef struct { + EFI_HANDLE Handle; + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb; + EFI_FVB_EXTENSION_PROTOCOL *FvbExtension; + BOOLEAN IsRuntimeAccess; +} FVB_ENTRY; + +#endif diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 56e39e3b92..cb5410bc2a 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -96,6 +96,7 @@ DevicePathLib|${WORKSPACE}/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf UefiLib|${WORKSPACE}/MdePkg/Library/UefiLib/UefiLib.inf DxeServicesTableLib|${WORKSPACE}/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf + ReportStatusCodeLib|${WORKSPACE}/IntelFrameworkPkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf [LibraryClasses.common.DXE_DRIVER] HobLib|${WORKSPACE}/MdePkg/Library/DxeHobLib/DxeHobLib.inf @@ -110,6 +111,8 @@ UefiLib|${WORKSPACE}/MdePkg/Library/UefiLib/UefiLib.inf UefiRuntimeServicesTableLib|${WORKSPACE}/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf DxeServicesTableLib|${WORKSPACE}/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf + FvbServiceLib|${WORKSPACE}/MdeModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.inf + ReportStatusCodeLib|${WORKSPACE}/IntelFrameworkPkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf [LibraryClasses.common.DXE_RUNTIME_DRIVER] HobLib|${WORKSPACE}/MdePkg/Library/DxeHobLib/DxeHobLib.inf @@ -124,6 +127,8 @@ UefiLib|${WORKSPACE}/MdePkg/Library/UefiLib/UefiLib.inf UefiRuntimeServicesTableLib|${WORKSPACE}/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf DxeServicesTableLib|${WORKSPACE}/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf + FvbServiceLib|${WORKSPACE}/MdeModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.inf + ReportStatusCodeLib|${WORKSPACE}/IntelFrameworkPkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf [LibraryClasses.common.DXE_SAL_DRIVER] HobLib|${WORKSPACE}/MdePkg/Library/DxeHobLib/DxeHobLib.inf @@ -138,6 +143,9 @@ UefiDriverEntryPoint|${WORKSPACE}/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf UefiLib|${WORKSPACE}/MdePkg/Library/UefiLib/UefiLib.inf UefiRuntimeServicesTableLib|${WORKSPACE}/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf + FvbServiceLib|${WORKSPACE}/MdeModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.inf + ReportStatusCodeLib|${WORKSPACE}/IntelFrameworkPkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf + [LibraryClasses.common.DXE_SMM_DRIVER] HobLib|${WORKSPACE}/MdePkg/Library/DxeHobLib/DxeHobLib.inf @@ -151,6 +159,9 @@ DevicePathLib|${WORKSPACE}/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf UefiLib|${WORKSPACE}/MdePkg/Library/UefiLib/UefiLib.inf UefiRuntimeServicesTableLib|${WORKSPACE}/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf + FvbServiceLib|${WORKSPACE}/MdeModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.inf + ReportStatusCodeLib|${WORKSPACE}/IntelFrameworkPkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf + [LibraryClasses.common.UEFI_DRIVER] HobLib|${WORKSPACE}/MdePkg/Library/DxeHobLib/DxeHobLib.inf @@ -165,6 +176,9 @@ UefiDriverEntryPoint|${WORKSPACE}/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf UefiLib|${WORKSPACE}/MdePkg/Library/UefiLib/UefiLib.inf UefiRuntimeServicesTableLib|${WORKSPACE}/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf + FvbServiceLib|${WORKSPACE}/MdeModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.inf + ReportStatusCodeLib|${WORKSPACE}/IntelFrameworkPkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf + [LibraryClasses.common.UEFI_APPLICATION] HobLib|${WORKSPACE}/MdePkg/Library/DxeHobLib/DxeHobLib.inf @@ -178,6 +192,8 @@ UefiLib|${WORKSPACE}/MdePkg/Library/UefiLib/UefiLib.inf UefiRuntimeServicesTableLib|${WORKSPACE}/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf DebugLib|${WORKSPACE}/MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf + FvbServiceLib|${WORKSPACE}/MdeModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.inf + ReportStatusCodeLib|${WORKSPACE}/IntelFrameworkPkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf [LibraryClasses.IA32.BASE] @@ -273,6 +289,8 @@ PcdDriverDiagnostics2Disable|gEfiMdePkgTokenSpaceGuid|TRUE PcdSupportUpdateCapsuleRest|gEfiEdkModulePkgTokenSpaceGuid|FALSE +# PcdStatusCodeUseOEM|gEfiIntelFrameworkModulePkgTokenSpaceGuid|FALSE + [PcdsFixedAtBuild.common] PcdMaximumUnicodeStringLength|gEfiMdePkgTokenSpaceGuid|1000000 PcdMaximumAsciiStringLength|gEfiMdePkgTokenSpaceGuid|1000000 @@ -293,6 +311,8 @@ PcdFlashNvStorageFtwSpareSize|gEfiGenericPlatformTokenSpaceGuid|0x0 PcdFlashNvStorageFtwWorkingBase|gEfiGenericPlatformTokenSpaceGuid|0x0 PcdFlashNvStorageFtwWorkingSize|gEfiGenericPlatformTokenSpaceGuid|0x0 + PcdFlashNvStorageVariableBase|gEfiGenericPlatformTokenSpaceGuid|0x0 + PcdFlashNvStorageVariableSize|gEfiGenericPlatformTokenSpaceGuid|0x0 [PcdsPatchableInModule.common] PcdDebugPrintErrorLevel|gEfiMdePkgTokenSpaceGuid|0x80000000 @@ -317,6 +337,7 @@ ${WORKSPACE}/MdeModulePkg/Universal/GenericMemoryTest/Dxe/NullMemoryTest.inf ${WORKSPACE}/MdeModulePkg/Universal/FirmwareVolume/FaultTolerantWriteLite/Dxe/FtwLite.inf #${WORKSPACE}/MdeModulePkg/Universal/FirmwareVolume/GuidedSectionExtraction/Crc32SectionExtract/Dxe/Crc32SectionExtract.inf + ${WORKSPACE}/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.inf ${WORKSPACE}/MdeModulePkg/Bus/Pci/AtapiPassThru/Dxe/AtapiPassThru.inf ${WORKSPACE}/MdeModulePkg/Universal/WatchDogTimerDxe/WatchDogTimer.inf - ${WORKSPACE}/MdeModulePkg/Universal/VariablePei/Variable.inf \ No newline at end of file + ${WORKSPACE}/MdeModulePkg/Universal/VariablePei/Variable.inf diff --git a/MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.inf b/MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.inf index ad73679302..7b4f93d64d 100644 --- a/MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.inf +++ b/MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.inf @@ -47,7 +47,7 @@ [Sources.common] ComponentName.c DiskIo.h - diskio.c + DiskIo.c ################################################################################ diff --git a/MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.msa b/MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.msa index f5b93c83e4..3ee0feef0d 100644 --- a/MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.msa +++ b/MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.msa @@ -49,7 +49,7 @@ - diskio.c + DiskIo.h ComponentName.c diff --git a/MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/CommonHeader.h b/MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/CommonHeader.h new file mode 100644 index 0000000000..f1a8cc662c --- /dev/null +++ b/MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/CommonHeader.h @@ -0,0 +1,35 @@ +/**@file + Common header file shared by all source files. + + This file includes package header files, library classes and protocol, PPI & GUID definitions. + + Copyright (c) 2006 - 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. +**/ + +#ifndef __COMMON_HEADER_H_ +#define __COMMON_HEADER_H_ + + +// +// The package level header files this module uses +// +#include + +// +// The protocols, PPI and GUID defintions for this module +// +#include +// +// The Library classes this module consumes +// +#include +#include +#include + +#endif diff --git a/MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/English.inf b/MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/English.inf new file mode 100644 index 0000000000..7022ab19df --- /dev/null +++ b/MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/English.inf @@ -0,0 +1,93 @@ +#/** @file +# Component description file for English module for unicode collation. +# +# This driver installs UEFI EFI_UNICODE_COLLATION_PROTOCOL protocol to provide Unicode strings function. +# Copyright (c) 2006 - 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. +# +# +#**/ + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = English + FILE_GUID = CD3BAFB6-50FB-4fe8-8E4E-AB74D2C1A600 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + ENTRY_POINT = InitializeUnicodeCollationEng + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources.common] + UnicodeCollationEng.c + UnicodeCollationEng.h + + +################################################################################ +# +# Includes Section - list of Include locations that are required for +# this module. +# +################################################################################ + +[Includes] + $(WORKSPACE)/MdePkg/Include/Library + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + $(WORKSPACE)/MdeModulePkg/MdeModulePkg.dec + $(WORKSPACE)/MdePkg/MdePkg.dec + +################################################################################ +# +# Library Class Section - list of Library Classes that are required for +# this module. +# +################################################################################ + +[LibraryClasses] + UefiBootServicesTableLib + UefiDriverEntryPoint + DebugLib + + +################################################################################ +# +# Protocol C Name Section - list of Protocol and Protocol Notify C Names +# that this module uses or produces. +# +################################################################################ + +[Protocols] + gEfiUnicodeCollationProtocolGuid # PROTOCOL ALWAYS_PRODUCED + diff --git a/MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/English.msa b/MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/English.msa new file mode 100644 index 0000000000..3a72998ba3 --- /dev/null +++ b/MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/English.msa @@ -0,0 +1,55 @@ + + + + English + UEFI_DRIVER + CD3BAFB6-50FB-4fe8-8E4E-AB74D2C1A600 + 1.0 + Component description file for English module for unicode collation. + This driver installs UEFI EFI_UNICODE_COLLATION_PROTOCOL protocol to provide Unicode strings function. + Copyright (c) 2006 - 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. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + English + + + + DebugLib + Recommended libary Instance is PeiDxeDebugLibReportStatusCode instance in MdePkg. + + + UefiDriverEntryPoint + + + UefiBootServicesTableLib + + + + UnicodeCollationEng.h + UnicodeCollationEng.c + + + + + + + gEfiUnicodeCollationProtocolGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + InitializeUnicodeCollationEng + + + \ No newline at end of file diff --git a/MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/UnicodeCollationEng.c b/MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/UnicodeCollationEng.c new file mode 100644 index 0000000000..5b543e939e --- /dev/null +++ b/MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/UnicodeCollationEng.c @@ -0,0 +1,479 @@ +/*++ + +Copyright (c) 2006, 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: + + UnicodeCollationEng.c + +Abstract: + + Unicode Collation Protocol (English) + +Revision History + +--*/ + + +#include "UnicodeCollationEng.h" + +CHAR8 mEngUpperMap[0x100]; +CHAR8 mEngLowerMap[0x100]; +CHAR8 mEngInfoMap[0x100]; + +CHAR8 mOtherChars[] = { + '0', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + '\\', + '.', + '_', + '^', + '$', + '~', + '!', + '#', + '%', + '&', + '-', + '{', + '}', + '(', + ')', + '@', + '`', + '\'', + '\0' +}; + +EFI_HANDLE mHandle = NULL; + +EFI_UNICODE_COLLATION_PROTOCOL UnicodeEng = { + EngStriColl, + EngMetaiMatch, + EngStrLwr, + EngStrUpr, + EngFatToStr, + EngStrToFat, + "eng" +}; + +// +// +// +EFI_STATUS +InitializeUnicodeCollationEng ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + + Initializes the Unicode Collation Driver + +Arguments: + + ImageHandle - + + SystemTable - + +Returns: + + EFI_SUCCESS + EFI_OUT_OF_RESOURCES + +--*/ +{ + UINTN Index; + UINTN Index2; + + // + // Initialize mapping tables for the supported languages + // + for (Index = 0; Index < 0x100; Index++) { + mEngUpperMap[Index] = (CHAR8) Index; + mEngLowerMap[Index] = (CHAR8) Index; + mEngInfoMap[Index] = 0; + + if ((Index >= 'a' && Index <= 'z') || (Index >= 0xe0 && Index <= 0xf6) || (Index >= 0xf8 && Index <= 0xfe)) { + + Index2 = Index - 0x20; + mEngUpperMap[Index] = (CHAR8) Index2; + mEngLowerMap[Index2] = (CHAR8) Index; + + mEngInfoMap[Index] |= CHAR_FAT_VALID; + mEngInfoMap[Index2] |= CHAR_FAT_VALID; + } + } + + for (Index = 0; mOtherChars[Index]; Index++) { + Index2 = mOtherChars[Index]; + mEngInfoMap[Index2] |= CHAR_FAT_VALID; + } + // + // Create a handle for the device + // + return gBS->InstallProtocolInterface ( + &mHandle, + &gEfiUnicodeCollationProtocolGuid, + EFI_NATIVE_INTERFACE, + &UnicodeEng + ); +} + +INTN +EFIAPI +EngStriColl ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *s1, + IN CHAR16 *s2 + ) +/*++ + +Routine Description: + + Performs a case-insensitive comparison of two Null-terminated Unicode strings. + +Arguments: + + This + s1 + s2 + +Returns: + +--*/ +{ + while (*s1) { + if (ToUpper (*s1) != ToUpper (*s2)) { + break; + } + + s1 += 1; + s2 += 1; + } + + return ToUpper (*s1) - ToUpper (*s2); +} + +VOID +EFIAPI +EngStrLwr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ) +/*++ + +Routine Description: + + Converts all the Unicode characters in a Null-terminated Unicode string + to lower case Unicode characters. + +Arguments: + + This - A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + Str1 - A pointer to a Null-terminated Unicode string. + Str2 - A pointer to a Null-terminated Unicode string. + +Returns: + + 0 - s1 is equivalent to s2. + > 0 - s1 is lexically greater than s2. + < 0 - s1 is lexically less than s2. + +--*/ +{ + while (*Str) { + *Str = ToLower (*Str); + Str += 1; + } +} + +VOID +EFIAPI +EngStrUpr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ) +/*++ + +Routine Description: + + Converts all the Unicode characters in a Null-terminated + Unicode string to upper case Unicode characters. + +Arguments: + This + Str + +Returns: + None + +--*/ +{ + while (*Str) { + *Str = ToUpper (*Str); + Str += 1; + } +} + +BOOLEAN +EFIAPI +EngMetaiMatch ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN CHAR16 *Pattern + ) +/*++ + +Routine Description: + + Performs a case-insensitive comparison between a Null-terminated + Unicode pattern string and a Null-terminated Unicode string. + + The pattern string can use the '?' wildcard to match any character, + and the '*' wildcard to match any sub-string. + +Arguments: + + This - A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + String - A pointer to a Null-terminated Unicode string. + Pattern - A pointer to a Null-terminated Unicode pattern string. + +Returns: + + TRUE - Pattern was found in String. + FALSE - Pattern was not found in String. + +--*/ +{ + CHAR16 CharC; + CHAR16 CharP; + CHAR16 Index3; + + for (;;) { + CharP = *Pattern; + Pattern += 1; + + switch (CharP) { + case 0: + // + // End of pattern. If end of string, TRUE match + // + if (*String) { + return FALSE; + } else { + return TRUE; + } + + case '*': + // + // Match zero or more chars + // + while (*String) { + if (EngMetaiMatch (This, String, Pattern)) { + return TRUE; + } + + String += 1; + } + + return EngMetaiMatch (This, String, Pattern); + + case '?': + // + // Match any one char + // + if (!*String) { + return FALSE; + } + + String += 1; + break; + + case '[': + // + // Match char set + // + CharC = *String; + if (!CharC) { + // + // syntax problem + // + return FALSE; + } + + Index3 = 0; + CharP = *Pattern++; + while (CharP) { + if (CharP == ']') { + return FALSE; + } + + if (CharP == '-') { + // + // if range of chars, get high range + // + CharP = *Pattern; + if (CharP == 0 || CharP == ']') { + // + // syntax problem + // + return FALSE; + } + + if (ToUpper (CharC) >= ToUpper (Index3) && ToUpper (CharC) <= ToUpper (CharP)) { + // + // if in range, it's a match + // + break; + } + } + + Index3 = CharP; + if (ToUpper (CharC) == ToUpper (CharP)) { + // + // if char matches + // + break; + } + + CharP = *Pattern++; + } + // + // skip to end of match char set + // + while (CharP && CharP != ']') { + CharP = *Pattern; + Pattern += 1; + } + + String += 1; + break; + + default: + CharC = *String; + if (ToUpper (CharC) != ToUpper (CharP)) { + return FALSE; + } + + String += 1; + break; + } + } +} + +VOID +EFIAPI +EngFatToStr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN UINTN FatSize, + IN CHAR8 *Fat, + OUT CHAR16 *String + ) +/*++ + +Routine Description: + + Converts an 8.3 FAT file name using an OEM character set + to a Null-terminated Unicode string. + + BUGBUG: Function has to expand DBCS FAT chars, currently not. + +Arguments: + This + FatSize + Fat + String + +Returns: + +--*/ +{ + // + // No DBCS issues, just expand and add null terminate to end of string + // + while (*Fat && FatSize) { + *String = *Fat; + String += 1; + Fat += 1; + FatSize -= 1; + } + + *String = 0; +} + +BOOLEAN +EFIAPI +EngStrToFat ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN UINTN FatSize, + OUT CHAR8 *Fat + ) +/*++ + +Routine Description: + + Converts a Null-terminated Unicode string to legal characters + in a FAT filename using an OEM character set. + + Functions has to crunch string to a fat string. Replacing + any chars that can't be represented in the fat name. + +Arguments: + This + String + FatSize + Fat + +Returns: + TRUE + FALSE +--*/ +{ + BOOLEAN SpecialCharExist; + + SpecialCharExist = FALSE; + while (*String && FatSize) { + // + // Skip '.' or ' ' when making a fat name + // + if (*String != '.' && *String != ' ') { + // + // If this is a valid fat char, move it. + // Otherwise, move a '_' and flag the fact that the name needs an Lfn + // + if (*String < 0x100 && (mEngInfoMap[*String] & CHAR_FAT_VALID)) { + *Fat = mEngUpperMap[*String]; + } else { + *Fat = '_'; + SpecialCharExist = TRUE; + } + + Fat += 1; + FatSize -= 1; + } + + String += 1; + } + // + // Do not terminate that fat string + // + return SpecialCharExist; +} diff --git a/MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/UnicodeCollationEng.h b/MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/UnicodeCollationEng.h new file mode 100644 index 0000000000..c8485aca17 --- /dev/null +++ b/MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/UnicodeCollationEng.h @@ -0,0 +1,117 @@ +/*++ + +Copyright (c) 2006, 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: + + UnicodeCollationEng.h + +Abstract: + + Head file for Unicode Collation Protocol (English) + +Revision History + +--*/ + +#ifndef _UNICODE_COLLATION_ENG_H +#define _UNICODE_COLLATION_ENG_H + + +// +// The package level header files this module uses +// +#include + +// +// The protocols, PPI and GUID defintions for this module +// +#include +// +// The Library classes this module consumes +// +#include +#include +#include + +// +// Defines +// +#define CHAR_FAT_VALID 0x01 + +#define ToUpper(a) (CHAR16) (a <= 0xFF ? mEngUpperMap[a] : a) +#define ToLower(a) (CHAR16) (a <= 0xFF ? mEngLowerMap[a] : a) + +// +// Prototypes +// +INTN +EFIAPI +EngStriColl ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *s1, + IN CHAR16 *s2 + ) +; + +BOOLEAN +EFIAPI +EngMetaiMatch ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN CHAR16 *Pattern + ) +; + +VOID +EFIAPI +EngStrLwr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ) +; + +VOID +EFIAPI +EngStrUpr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ) +; + +VOID +EFIAPI +EngFatToStr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN UINTN FatSize, + IN CHAR8 *Fat, + OUT CHAR16 *String + ) +; + +BOOLEAN +EFIAPI +EngStrToFat ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN UINTN FatSize, + OUT CHAR8 *Fat + ) +; + +EFI_STATUS +EFIAPI +InitializeUnicodeCollationEng ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +; + +#endif diff --git a/MdeModulePkg/Universal/VariableRuntimeDxe/CommonHeader.h b/MdeModulePkg/Universal/VariableRuntimeDxe/CommonHeader.h new file mode 100644 index 0000000000..4f16113639 --- /dev/null +++ b/MdeModulePkg/Universal/VariableRuntimeDxe/CommonHeader.h @@ -0,0 +1,46 @@ +/**@file + Common header file shared by all source files. + + This file includes package header files, library classes and protocol, PPI & GUID definitions. + + Copyright (c) 2006 - 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. +**/ + +#ifndef __COMMON_HEADER_H_ +#define __COMMON_HEADER_H_ + + +// +// The package level header files this module uses +// +#include +// +// The protocols, PPI and GUID defintions for this module +// +#include +#include +#include +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#endif diff --git a/MdeModulePkg/Universal/VariableRuntimeDxe/InitVariable.c b/MdeModulePkg/Universal/VariableRuntimeDxe/InitVariable.c new file mode 100644 index 0000000000..15e84e8b23 --- /dev/null +++ b/MdeModulePkg/Universal/VariableRuntimeDxe/InitVariable.c @@ -0,0 +1,234 @@ +/*++ + +Copyright (c) 2006 - 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: + + InitVariable.c + +Abstract: + +Revision History + +--*/ + +// +// Include common header file for this module. +// +#include "CommonHeader.h" + +#include "Variable.h" + +// +// Event for Exit Boot Services Callback +// +STATIC EFI_EVENT mExitBootServicesEvent = NULL; + + +// +// Don't use module globals after the SetVirtualAddress map is signaled +// +extern ESAL_VARIABLE_GLOBAL *mVariableModuleGlobal; + +EFI_STATUS +EFIAPI +RuntimeServiceGetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID * VendorGuid, + OUT UINT32 *Attributes OPTIONAL, + IN OUT UINTN *DataSize, + OUT VOID *Data + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + +--*/ +{ + return GetVariable ( + VariableName, + VendorGuid, + Attributes OPTIONAL, + DataSize, + Data, + &mVariableModuleGlobal->VariableGlobal[Physical], + mVariableModuleGlobal->FvbInstance + ); +} + +EFI_STATUS +EFIAPI +RuntimeServiceGetNextVariableName ( + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VendorGuid + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + +--*/ +{ + return GetNextVariableName ( + VariableNameSize, + VariableName, + VendorGuid, + &mVariableModuleGlobal->VariableGlobal[Physical], + mVariableModuleGlobal->FvbInstance + ); +} + +EFI_STATUS +EFIAPI +RuntimeServiceSetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + +--*/ +{ + return SetVariable ( + VariableName, + VendorGuid, + Attributes, + DataSize, + Data, + &mVariableModuleGlobal->VariableGlobal[Physical], + &mVariableModuleGlobal->VolatileLastVariableOffset, + &mVariableModuleGlobal->NonVolatileLastVariableOffset, + mVariableModuleGlobal->FvbInstance + ); +} + +EFI_STATUS +EFIAPI +RuntimeServiceQueryVariableInfo ( + IN UINT32 Attributes, + OUT UINT64 *MaximumVariableStorageSize, + OUT UINT64 *RemainingVariableStorageSize, + OUT UINT64 *MaximumVariableSize + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + +--*/ +{ + return QueryVariableInfo ( + Attributes, + MaximumVariableStorageSize, + RemainingVariableStorageSize, + MaximumVariableSize, + &mVariableModuleGlobal->VariableGlobal[Physical], + mVariableModuleGlobal->FvbInstance + ); +} + +VOID +EFIAPI +VariableClassAddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + +--*/ +{ + EfiConvertPointer ( + 0x0, + (VOID **) &mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase + ); + EfiConvertPointer ( + 0x0, + (VOID **) &mVariableModuleGlobal->VariableGlobal[Physical].VolatileVariableBase + ); + EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal); +} + +EFI_STATUS +EFIAPI +VariableServiceInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + +--*/ +{ + EFI_HANDLE NewHandle; + EFI_STATUS Status; + + Status = VariableCommonInitialize (ImageHandle, SystemTable); + ASSERT_EFI_ERROR (Status); + + SystemTable->RuntimeServices->GetVariable = RuntimeServiceGetVariable; + SystemTable->RuntimeServices->GetNextVariableName = RuntimeServiceGetNextVariableName; + SystemTable->RuntimeServices->SetVariable = RuntimeServiceSetVariable; + SystemTable->RuntimeServices->QueryVariableInfo = RuntimeServiceQueryVariableInfo; + + // + // Now install the Variable Runtime Architectural Protocol on a new handle + // + NewHandle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &NewHandle, + &gEfiVariableArchProtocolGuid, + NULL, + &gEfiVariableWriteArchProtocolGuid, + NULL, + NULL + ); + ASSERT_EFI_ERROR (Status); + + Status = gBS->CreateEvent ( + EVT_SIGNAL_EXIT_BOOT_SERVICES, + TPL_NOTIFY, + VariableClassAddressChangeEvent, + NULL, + &mExitBootServicesEvent + ); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Universal/VariableRuntimeDxe/Variable.c b/MdeModulePkg/Universal/VariableRuntimeDxe/Variable.c new file mode 100644 index 0000000000..f6aa468e35 --- /dev/null +++ b/MdeModulePkg/Universal/VariableRuntimeDxe/Variable.c @@ -0,0 +1,1479 @@ +/*++ + +Copyright (c) 2006 - 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: + + Variable.c + +Abstract: + +Revision History + +--*/ + + +#include "Variable.h" +#include "reclaim.h" + +#include + +// +// Don't use module globals after the SetVirtualAddress map is signaled +// +ESAL_VARIABLE_GLOBAL *mVariableModuleGlobal; + +// +// This is a temperary function which will be removed +// when EfiAcquireLock in UefiLib can handle the +// the call in UEFI Runtimer driver in RT phase. +// +STATIC +VOID +AcquireLockOnlyAtBootTime ( + IN EFI_LOCK *Lock + ) +{ + if (!EfiAtRuntime ()) { + EfiAcquireLock (Lock); + } +} + +// +// This is a temperary function which will be removed +// when EfiAcquireLock in UefiLib can handle the +// the call in UEFI Runtimer driver in RT phase. +// +STATIC +VOID +ReleaseLockOnlyAtBootTime ( + IN EFI_LOCK *Lock + ) +{ + if (!EfiAtRuntime ()) { + EfiReleaseLock (Lock); + } +} + +STATIC +BOOLEAN +EFIAPI +IsValidVariableHeader ( + IN VARIABLE_HEADER *Variable + ) +/*++ + +Routine Description: + + This code checks if variable header is valid or not. + +Arguments: + Variable Pointer to the Variable Header. + +Returns: + TRUE Variable header is valid. + FALSE Variable header is not valid. + +--*/ +{ + if (Variable == NULL || + Variable->StartId != VARIABLE_DATA || + (sizeof (VARIABLE_HEADER) + Variable->NameSize + Variable->DataSize) > MAX_VARIABLE_SIZE + ) { + return FALSE; + } + + return TRUE; +} + +STATIC +EFI_STATUS +EFIAPI +UpdateVariableStore ( + IN VARIABLE_GLOBAL *Global, + IN BOOLEAN Volatile, + IN BOOLEAN SetByIndex, + IN UINTN Instance, + IN UINTN DataPtrIndex, + IN UINT32 DataSize, + IN UINT8 *Buffer + ) +/*++ + +Routine Description: + + This function writes data to the FWH at the correct LBA even if the LBAs + are fragmented. + +Arguments: + + Global Pointer to VARAIBLE_GLOBAL structure + Volatile If the Variable is Volatile or Non-Volatile + SetByIndex TRUE: Target pointer is given as index + FALSE: Target pointer is absolute + Instance Instance of FV Block services + DataPtrIndex Pointer to the Data from the end of VARIABLE_STORE_HEADER + structure + DataSize Size of data to be written. + Buffer Pointer to the buffer from which data is written + +Returns: + + EFI STATUS + +--*/ +{ + EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry; + UINTN BlockIndex2; + UINTN LinearOffset; + UINTN CurrWriteSize; + UINTN CurrWritePtr; + UINT8 *CurrBuffer; + EFI_LBA LbaNumber; + UINTN Size; + FRAMEWORK_EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + VARIABLE_STORE_HEADER *VolatileBase; + EFI_PHYSICAL_ADDRESS FvVolHdr; + EFI_PHYSICAL_ADDRESS DataPtr; + EFI_STATUS Status; + + FwVolHeader = NULL; + DataPtr = DataPtrIndex; + + // + // Check if the Data is Volatile + // + if (!Volatile) { + EfiFvbGetPhysicalAddress (Instance, &FvVolHdr); + FwVolHeader = (FRAMEWORK_EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvVolHdr); + // + // Data Pointer should point to the actual Address where data is to be + // written + // + if (SetByIndex) { + DataPtr += Global->NonVolatileVariableBase; + } + + if ((DataPtr + DataSize) >= ((EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) FwVolHeader + FwVolHeader->FvLength))) { + return EFI_INVALID_PARAMETER; + } + } else { + // + // Data Pointer should point to the actual Address where data is to be + // written + // + VolatileBase = (VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase); + if (SetByIndex) { + DataPtr += Global->VolatileVariableBase; + } + + if ((DataPtr + DataSize) >= ((UINTN) ((UINT8 *) VolatileBase + VolatileBase->Size))) { + return EFI_INVALID_PARAMETER; + } + } + // + // If Volatile Variable just do a simple mem copy. + // + if (Volatile) { + CopyMem ((UINT8 *) ((UINTN) DataPtr), Buffer, DataSize); + return EFI_SUCCESS; + } + // + // If we are here we are dealing with Non-Volatile Variables + // + LinearOffset = (UINTN) FwVolHeader; + CurrWritePtr = (UINTN) DataPtr; + CurrWriteSize = DataSize; + CurrBuffer = Buffer; + LbaNumber = 0; + + if (CurrWritePtr < LinearOffset) { + return EFI_INVALID_PARAMETER; + } + + for (PtrBlockMapEntry = FwVolHeader->FvBlockMap; PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) { + for (BlockIndex2 = 0; BlockIndex2 < PtrBlockMapEntry->NumBlocks; BlockIndex2++) { + // + // Check to see if the Variable Writes are spanning through multiple + // blocks. + // + if ((CurrWritePtr >= LinearOffset) && (CurrWritePtr < LinearOffset + PtrBlockMapEntry->Length)) { + if ((CurrWritePtr + CurrWriteSize) <= (LinearOffset + PtrBlockMapEntry->Length)) { + Status = EfiFvbWriteBlock ( + Instance, + LbaNumber, + (UINTN) (CurrWritePtr - LinearOffset), + &CurrWriteSize, + CurrBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + } else { + Size = (UINT32) (LinearOffset + PtrBlockMapEntry->Length - CurrWritePtr); + Status = EfiFvbWriteBlock ( + Instance, + LbaNumber, + (UINTN) (CurrWritePtr - LinearOffset), + &Size, + CurrBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + + CurrWritePtr = LinearOffset + PtrBlockMapEntry->Length; + CurrBuffer = CurrBuffer + Size; + CurrWriteSize = CurrWriteSize - Size; + } + } + + LinearOffset += PtrBlockMapEntry->Length; + LbaNumber++; + } + } + + return EFI_SUCCESS; +} + +STATIC +VARIABLE_STORE_STATUS +EFIAPI +GetVariableStoreStatus ( + IN VARIABLE_STORE_HEADER *VarStoreHeader + ) +/*++ + +Routine Description: + + This code gets the current status of Variable Store. + +Arguments: + + VarStoreHeader Pointer to the Variable Store Header. + +Returns: + + EfiRaw Variable store status is raw + EfiValid Variable store status is valid + EfiInvalid Variable store status is invalid + +--*/ +{ + if (VarStoreHeader->Signature == VARIABLE_STORE_SIGNATURE && + VarStoreHeader->Format == VARIABLE_STORE_FORMATTED && + VarStoreHeader->State == VARIABLE_STORE_HEALTHY + ) { + + return EfiValid; + } else if (VarStoreHeader->Signature == 0xffffffff && + VarStoreHeader->Size == 0xffffffff && + VarStoreHeader->Format == 0xff && + VarStoreHeader->State == 0xff + ) { + + return EfiRaw; + } else { + return EfiInvalid; + } +} + +STATIC +UINT8 * +EFIAPI +GetVariableDataPtr ( + IN VARIABLE_HEADER *Variable + ) +/*++ + +Routine Description: + + This code gets the pointer to the variable data. + +Arguments: + + Variable Pointer to the Variable Header. + +Returns: + + UINT8* Pointer to Variable Data + +--*/ +{ + // + // Be careful about pad size for alignment + // + return (UINT8 *) ((UINTN) GET_VARIABLE_NAME_PTR (Variable) + Variable->NameSize + GET_PAD_SIZE (Variable->NameSize)); +} + +STATIC +VARIABLE_HEADER * +EFIAPI +GetNextVariablePtr ( + IN VARIABLE_HEADER *Variable + ) +/*++ + +Routine Description: + + This code gets the pointer to the next variable header. + +Arguments: + + Variable Pointer to the Variable Header. + +Returns: + + VARIABLE_HEADER* Pointer to next variable header. + +--*/ +{ + if (!IsValidVariableHeader (Variable)) { + return NULL; + } + // + // Be careful about pad size for alignment + // + return (VARIABLE_HEADER *) ((UINTN) GetVariableDataPtr (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize)); +} + +STATIC +VARIABLE_HEADER * +EFIAPI +GetEndPointer ( + IN VARIABLE_STORE_HEADER *VarStoreHeader + ) +/*++ + +Routine Description: + + This code gets the pointer to the last variable memory pointer byte + +Arguments: + + VarStoreHeader Pointer to the Variable Store Header. + +Returns: + + VARIABLE_HEADER* Pointer to last unavailable Variable Header + +--*/ +{ + // + // The end of variable store + // + return (VARIABLE_HEADER *) ((UINTN) VarStoreHeader + VarStoreHeader->Size); +} + +STATIC +EFI_STATUS +EFIAPI +Reclaim ( + IN EFI_PHYSICAL_ADDRESS VariableBase, + OUT UINTN *LastVariableOffset, + IN BOOLEAN IsVolatile + ) +/*++ + +Routine Description: + + Variable store garbage collection and reclaim operation + +Arguments: + + VariableBase Base address of variable store + LastVariableOffset Offset of last variable + IsVolatile The variable store is volatile or not, + if it is non-volatile, need FTW + +Returns: + + EFI STATUS + +--*/ +{ + VARIABLE_HEADER *Variable; + VARIABLE_HEADER *NextVariable; + VARIABLE_STORE_HEADER *VariableStoreHeader; + UINT8 *ValidBuffer; + UINTN ValidBufferSize; + UINTN VariableSize; + UINT8 *CurrPtr; + EFI_STATUS Status; + + VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase); + + // + // Start Pointers for the variable. + // + Variable = (VARIABLE_HEADER *) (VariableStoreHeader + 1); + + ValidBufferSize = sizeof (VARIABLE_STORE_HEADER); + + while (IsValidVariableHeader (Variable)) { + NextVariable = GetNextVariablePtr (Variable); + if (Variable->State == VAR_ADDED) { + VariableSize = (UINTN) NextVariable - (UINTN) Variable; + ValidBufferSize += VariableSize; + } + + Variable = NextVariable; + } + + ValidBuffer = AllocatePool (ValidBufferSize); + if (ValidBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + SetMem (ValidBuffer, ValidBufferSize, 0xff); + + CurrPtr = ValidBuffer; + + // + // Copy variable store header + // + CopyMem (CurrPtr, VariableStoreHeader, sizeof (VARIABLE_STORE_HEADER)); + CurrPtr += sizeof (VARIABLE_STORE_HEADER); + + // + // Start Pointers for the variable. + // + Variable = (VARIABLE_HEADER *) (VariableStoreHeader + 1); + + while (IsValidVariableHeader (Variable)) { + NextVariable = GetNextVariablePtr (Variable); + if (Variable->State == VAR_ADDED) { + VariableSize = (UINTN) NextVariable - (UINTN) Variable; + CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize); + CurrPtr += VariableSize; + } + + Variable = NextVariable; + } + + if (IsVolatile) { + // + // If volatile variable store, just copy valid buffer + // + SetMem ((UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size, 0xff); + CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, ValidBufferSize); + *LastVariableOffset = ValidBufferSize; + Status = EFI_SUCCESS; + } else { + // + // If non-volatile variable store, perform FTW here. + // + Status = FtwVariableSpace ( + VariableBase, + ValidBuffer, + ValidBufferSize + ); + if (!EFI_ERROR (Status)) { + *LastVariableOffset = ValidBufferSize; + } + } + + FreePool (ValidBuffer); + + if (EFI_ERROR (Status)) { + *LastVariableOffset = 0; + } + + return Status; +} + +STATIC +EFI_STATUS +EFIAPI +FindVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + OUT VARIABLE_POINTER_TRACK *PtrTrack, + IN VARIABLE_GLOBAL *Global + ) +/*++ + +Routine Description: + + This code finds variable in storage blocks (Volatile or Non-Volatile) + +Arguments: + + VariableName Name of the variable to be found + VendorGuid Vendor GUID to be found. + PtrTrack Variable Track Pointer structure that contains + Variable Information. + Contains the pointer of Variable header. + Global VARIABLE_GLOBAL pointer + +Returns: + + EFI STATUS + +--*/ +{ + VARIABLE_HEADER *Variable[2]; + VARIABLE_STORE_HEADER *VariableStoreHeader[2]; + UINTN Index; + + // + // We aquire the lock at the entry of FindVariable as GetVariable, GetNextVariableName + // SetVariable all call FindVariable at entry point. Please move "Aquire Lock" to + // the correct places if this assumption does not hold TRUE anymore. + // + AcquireLockOnlyAtBootTime(&Global->VariableServicesLock); + + // + // 0: Non-Volatile, 1: Volatile + // + VariableStoreHeader[0] = (VARIABLE_STORE_HEADER *) ((UINTN) Global->NonVolatileVariableBase); + VariableStoreHeader[1] = (VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase); + + // + // Start Pointers for the variable. + // Actual Data Pointer where data can be written. + // + Variable[0] = (VARIABLE_HEADER *) (VariableStoreHeader[0] + 1); + Variable[1] = (VARIABLE_HEADER *) (VariableStoreHeader[1] + 1); + + if (VariableName[0] != 0 && VendorGuid == NULL) { + return EFI_INVALID_PARAMETER; + } + // + // Find the variable by walk through non-volatile and volatile variable store + // + for (Index = 0; Index < 2; Index++) { + PtrTrack->StartPtr = (VARIABLE_HEADER *) (VariableStoreHeader[Index] + 1); + PtrTrack->EndPtr = GetEndPointer (VariableStoreHeader[Index]); + + while (IsValidVariableHeader (Variable[Index]) && (Variable[Index] <= GetEndPointer (VariableStoreHeader[Index]))) { + if (Variable[Index]->State == VAR_ADDED) { + if (!(EfiAtRuntime () && !(Variable[Index]->Attributes & EFI_VARIABLE_RUNTIME_ACCESS))) { + if (VariableName[0] == 0) { + PtrTrack->CurrPtr = Variable[Index]; + PtrTrack->Volatile = (BOOLEAN) Index; + return EFI_SUCCESS; + } else { + if (CompareGuid (VendorGuid, &Variable[Index]->VendorGuid)) { + if (!CompareMem (VariableName, GET_VARIABLE_NAME_PTR (Variable[Index]), Variable[Index]->NameSize)) { + PtrTrack->CurrPtr = Variable[Index]; + PtrTrack->Volatile = (BOOLEAN) Index; + return EFI_SUCCESS; + } + } + } + } + } + + Variable[Index] = GetNextVariablePtr (Variable[Index]); + } + // + // While (...) + // + } + // + // for (...) + // + PtrTrack->CurrPtr = NULL; + return EFI_NOT_FOUND; +} + +EFI_STATUS +EFIAPI +GetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID * VendorGuid, + OUT UINT32 *Attributes OPTIONAL, + IN OUT UINTN *DataSize, + OUT VOID *Data, + IN VARIABLE_GLOBAL * Global, + IN UINT32 Instance + ) +/*++ + +Routine Description: + + This code finds variable in storage blocks (Volatile or Non-Volatile) + +Arguments: + + VariableName Name of Variable to be found + VendorGuid Variable vendor GUID + Attributes OPTIONAL Attribute value of the variable found + DataSize Size of Data found. If size is less than the + data, this value contains the required size. + Data Data pointer + Global Pointer to VARIABLE_GLOBAL structure + Instance Instance of the Firmware Volume. + +Returns: + + EFI STATUS + +--*/ +{ + VARIABLE_POINTER_TRACK Variable; + UINTN VarDataSize; + EFI_STATUS Status; + + if (VariableName == NULL || VendorGuid == NULL || DataSize == NULL) { + return EFI_INVALID_PARAMETER; + } + // + // Find existing variable + // + Status = FindVariable (VariableName, VendorGuid, &Variable, Global); + + if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) { + goto Done; + } + // + // Get data size + // + VarDataSize = Variable.CurrPtr->DataSize; + if (*DataSize >= VarDataSize) { + if (Data == NULL) { + Status = EFI_INVALID_PARAMETER; + goto Done; + } + + CopyMem (Data, GetVariableDataPtr (Variable.CurrPtr), VarDataSize); + if (Attributes != NULL) { + *Attributes = Variable.CurrPtr->Attributes; + } + + *DataSize = VarDataSize; + Status = EFI_SUCCESS; + goto Done; + } else { + *DataSize = VarDataSize; + Status = EFI_BUFFER_TOO_SMALL; + goto Done; + } + +Done: + ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock); + return Status; +} + +EFI_STATUS +EFIAPI +GetNextVariableName ( + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VendorGuid, + IN VARIABLE_GLOBAL *Global, + IN UINT32 Instance + ) +/*++ + +Routine Description: + + This code Finds the Next available variable + +Arguments: + + VariableNameSize Size of the variable + VariableName Pointer to variable name + VendorGuid Variable Vendor Guid + Global VARIABLE_GLOBAL structure pointer. + Instance FV instance + +Returns: + + EFI STATUS + +--*/ +{ + VARIABLE_POINTER_TRACK Variable; + UINTN VarNameSize; + EFI_STATUS Status; + + if (VariableNameSize == NULL || VariableName == NULL || VendorGuid == NULL) { + return EFI_INVALID_PARAMETER; + } + + Status = FindVariable (VariableName, VendorGuid, &Variable, Global); + + if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) { + goto Done; + } + + if (VariableName[0] != 0) { + // + // If variable name is not NULL, get next variable + // + Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr); + } + + while (TRUE) { + // + // If both volatile and non-volatile variable store are parsed, + // return not found + // + if (Variable.CurrPtr >= Variable.EndPtr || Variable.CurrPtr == NULL) { + Variable.Volatile = (BOOLEAN) (Variable.Volatile ^ ((BOOLEAN) 0x1)); + if (Variable.Volatile) { + Variable.StartPtr = (VARIABLE_HEADER *) ((UINTN) (Global->VolatileVariableBase + sizeof (VARIABLE_STORE_HEADER))); + Variable.EndPtr = (VARIABLE_HEADER *) GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase)); + } else { + Status = EFI_NOT_FOUND; + goto Done; + } + + Variable.CurrPtr = Variable.StartPtr; + if (!IsValidVariableHeader (Variable.CurrPtr)) { + continue; + } + } + // + // Variable is found + // + if (IsValidVariableHeader (Variable.CurrPtr) && Variable.CurrPtr->State == VAR_ADDED) { + if (!(EfiAtRuntime () && !(Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS))) { + VarNameSize = Variable.CurrPtr->NameSize; + if (VarNameSize <= *VariableNameSize) { + CopyMem ( + VariableName, + GET_VARIABLE_NAME_PTR (Variable.CurrPtr), + VarNameSize + ); + CopyMem ( + VendorGuid, + &Variable.CurrPtr->VendorGuid, + sizeof (EFI_GUID) + ); + Status = EFI_SUCCESS; + } else { + Status = EFI_BUFFER_TOO_SMALL; + } + + *VariableNameSize = VarNameSize; + goto Done; + } + } + + Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr); + } + +Done: + ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock); + return Status; +} + +EFI_STATUS +EFIAPI +SetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data, + IN VARIABLE_GLOBAL *Global, + IN UINTN *VolatileOffset, + IN UINTN *NonVolatileOffset, + IN UINT32 Instance + ) +/*++ + +Routine Description: + + This code sets variable in storage blocks (Volatile or Non-Volatile) + +Arguments: + + VariableName Name of Variable to be found + VendorGuid Variable vendor GUID + Attributes Attribute value of the variable found + DataSize Size of Data found. If size is less than the + data, this value contains the required size. + Data Data pointer + Global Pointer to VARIABLE_GLOBAL structure + VolatileOffset The offset of last volatile variable + NonVolatileOffset The offset of last non-volatile variable + Instance Instance of the Firmware Volume. + +Returns: + + EFI STATUS + EFI_INVALID_PARAMETER - Invalid parameter + EFI_SUCCESS - Set successfully + EFI_OUT_OF_RESOURCES - Resource not enough to set variable + EFI_NOT_FOUND - Not found + +--*/ +{ + VARIABLE_POINTER_TRACK Variable; + EFI_STATUS Status; + VARIABLE_HEADER *NextVariable; + UINTN VarNameSize; + UINTN VarNameOffset; + UINTN VarDataOffset; + UINTN VarSize; + UINT8 State; + BOOLEAN Reclaimed; + + Reclaimed = FALSE; + + if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) { + return EFI_INVALID_PARAMETER; + } + + Status = FindVariable (VariableName, VendorGuid, &Variable, Global); + + if (Status == EFI_INVALID_PARAMETER) { + goto Done; + } else if (!EFI_ERROR (Status) && Variable.Volatile && EfiAtRuntime()) { + // + // If EfiAtRuntime and the variable is Volatile and Runtime Access, + // the volatile is ReadOnly, and SetVariable should be aborted and + // return EFI_WRITE_PROTECTED. + // + Status = EFI_WRITE_PROTECTED; + goto Done; + } else if (sizeof (VARIABLE_HEADER) + StrSize (VariableName) + DataSize > MAX_VARIABLE_SIZE) { + // + // The size of the VariableName, including the Unicode Null in bytes plus + // the DataSize is limited to maximum size of MAX_VARIABLE_SIZE (1024) bytes. + // + Status = EFI_INVALID_PARAMETER; + goto Done; + } else if (Attributes == EFI_VARIABLE_NON_VOLATILE) { + // + // Make sure not only EFI_VARIABLE_NON_VOLATILE is set + // + Status = EFI_INVALID_PARAMETER; + goto Done; + } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == + EFI_VARIABLE_RUNTIME_ACCESS) { + // + // Make sure if runtime bit is set, boot service bit is set also + // + Status = EFI_INVALID_PARAMETER; + goto Done; + } else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) { + // + // Runtime but Attribute is not Runtime + // + Status = EFI_INVALID_PARAMETER; + goto Done; + } else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_NON_VOLATILE)) { + // + // Cannot set volatile variable in Runtime + // + Status = EFI_INVALID_PARAMETER; + goto Done; + } else if (DataSize == 0 || (Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 0) { + // + // Setting a data variable with no access, or zero DataSize attributes + // specified causes it to be deleted. + // + if (!EFI_ERROR (Status)) { + State = Variable.CurrPtr->State; + State &= VAR_DELETED; + + Status = UpdateVariableStore ( + Global, + Variable.Volatile, + FALSE, + Instance, + (UINTN) &Variable.CurrPtr->State, + sizeof (UINT8), + &State + ); + if (EFI_ERROR (Status)) { + goto Done; + } + + Status = EFI_SUCCESS; + goto Done; + } + + Status = EFI_NOT_FOUND; + goto Done; + } else { + if (!EFI_ERROR (Status)) { + // + // If the variable is marked valid and the same data has been passed in + // then return to the caller immediately. + // + if (Variable.CurrPtr->DataSize == DataSize && + !CompareMem (Data, GetVariableDataPtr (Variable.CurrPtr), DataSize) + ) { + Status = EFI_SUCCESS; + goto Done; + } else if (Variable.CurrPtr->State == VAR_ADDED) { + // + // Mark the old variable as in delete transition + // + State = Variable.CurrPtr->State; + State &= VAR_IN_DELETED_TRANSITION; + + Status = UpdateVariableStore ( + Global, + Variable.Volatile, + FALSE, + Instance, + (UINTN) &Variable.CurrPtr->State, + sizeof (UINT8), + &State + ); + if (EFI_ERROR (Status)) { + goto Done; + } + } + } + // + // Create a new variable and copy the data. + // + // Tricky part: Use scratch data area at the end of volatile variable store + // as a temporary storage. + // + NextVariable = GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase)); + + SetMem (NextVariable, SCRATCH_SIZE, 0xff); + + NextVariable->StartId = VARIABLE_DATA; + NextVariable->Attributes = Attributes; + // + // NextVariable->State = VAR_ADDED; + // + NextVariable->Reserved = 0; + VarNameOffset = sizeof (VARIABLE_HEADER); + VarNameSize = StrSize (VariableName); + CopyMem ( + (UINT8 *) ((UINTN) NextVariable + VarNameOffset), + VariableName, + VarNameSize + ); + VarDataOffset = VarNameOffset + VarNameSize + GET_PAD_SIZE (VarNameSize); + CopyMem ( + (UINT8 *) ((UINTN) NextVariable + VarDataOffset), + Data, + DataSize + ); + CopyMem (&NextVariable->VendorGuid, VendorGuid, sizeof (EFI_GUID)); + // + // There will be pad bytes after Data, the NextVariable->NameSize and + // NextVariable->DataSize should not include pad size so that variable + // service can get actual size in GetVariable + // + NextVariable->NameSize = (UINT32)VarNameSize; + NextVariable->DataSize = (UINT32)DataSize; + + // + // The actual size of the variable that stores in storage should + // include pad size. + // + VarSize = VarDataOffset + DataSize + GET_PAD_SIZE (DataSize); + if (Attributes & EFI_VARIABLE_NON_VOLATILE) { + if ((UINT32) (VarSize +*NonVolatileOffset) > + ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size + ) { + if (EfiAtRuntime ()) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + // + // Perform garbage collection & reclaim operation + // + Status = Reclaim (Global->NonVolatileVariableBase, NonVolatileOffset, FALSE); + if (EFI_ERROR (Status)) { + goto Done; + } + // + // If still no enough space, return out of resources + // + if ((UINT32) (VarSize +*NonVolatileOffset) > + ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size + ) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + Reclaimed = TRUE; + } + // + // Three steps + // 1. Write variable header + // 2. Write variable data + // 3. Set variable state to valid + // + // + // Step 1: + // + Status = UpdateVariableStore ( + Global, + FALSE, + TRUE, + Instance, + *NonVolatileOffset, + sizeof (VARIABLE_HEADER), + (UINT8 *) NextVariable + ); + + if (EFI_ERROR (Status)) { + goto Done; + } + // + // Step 2: + // + Status = UpdateVariableStore ( + Global, + FALSE, + TRUE, + Instance, + *NonVolatileOffset + sizeof (VARIABLE_HEADER), + (UINT32) VarSize - sizeof (VARIABLE_HEADER), + (UINT8 *) NextVariable + sizeof (VARIABLE_HEADER) + ); + + if (EFI_ERROR (Status)) { + goto Done; + } + // + // Step 3: + // + NextVariable->State = VAR_ADDED; + Status = UpdateVariableStore ( + Global, + FALSE, + TRUE, + Instance, + *NonVolatileOffset, + sizeof (VARIABLE_HEADER), + (UINT8 *) NextVariable + ); + + if (EFI_ERROR (Status)) { + goto Done; + } + + *NonVolatileOffset = *NonVolatileOffset + VarSize; + + } else { + if (EfiAtRuntime ()) { + Status = EFI_INVALID_PARAMETER; + goto Done; + } + + if ((UINT32) (VarSize +*VolatileOffset) > + ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size + ) { + // + // Perform garbage collection & reclaim operation + // + Status = Reclaim (Global->VolatileVariableBase, VolatileOffset, TRUE); + if (EFI_ERROR (Status)) { + goto Done; + } + // + // If still no enough space, return out of resources + // + if ((UINT32) (VarSize +*VolatileOffset) > + ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size + ) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + Reclaimed = TRUE; + } + + NextVariable->State = VAR_ADDED; + Status = UpdateVariableStore ( + Global, + TRUE, + TRUE, + Instance, + *VolatileOffset, + (UINT32) VarSize, + (UINT8 *) NextVariable + ); + + if (EFI_ERROR (Status)) { + goto Done; + } + + *VolatileOffset = *VolatileOffset + VarSize; + } + // + // Mark the old variable as deleted + // + if (!Reclaimed && !EFI_ERROR (Status) && Variable.CurrPtr != NULL) { + State = Variable.CurrPtr->State; + State &= VAR_DELETED; + + Status = UpdateVariableStore ( + Global, + Variable.Volatile, + FALSE, + Instance, + (UINTN) &Variable.CurrPtr->State, + sizeof (UINT8), + &State + ); + + if (EFI_ERROR (Status)) { + goto Done; + } + } + } + + Status = EFI_SUCCESS; +Done: + ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock); + return Status; +} + +EFI_STATUS +EFIAPI +QueryVariableInfo ( + IN UINT32 Attributes, + OUT UINT64 *MaximumVariableStorageSize, + OUT UINT64 *RemainingVariableStorageSize, + OUT UINT64 *MaximumVariableSize, + IN VARIABLE_GLOBAL *Global, + IN UINT32 Instance + ) +/*++ + +Routine Description: + + This code returns information about the EFI variables. + +Arguments: + + Attributes Attributes bitmask to specify the type of variables + on which to return information. + MaximumVariableStorageSize Pointer to the maximum size of the storage space available + for the EFI variables associated with the attributes specified. + RemainingVariableStorageSize Pointer to the remaining size of the storage space available + for the EFI variables associated with the attributes specified. + MaximumVariableSize Pointer to the maximum size of the individual EFI variables + associated with the attributes specified. + Global Pointer to VARIABLE_GLOBAL structure. + Instance Instance of the Firmware Volume. + +Returns: + + EFI STATUS + EFI_INVALID_PARAMETER - An invalid combination of attribute bits was supplied. + EFI_SUCCESS - Query successfully. + EFI_UNSUPPORTED - The attribute is not supported on this platform. + +--*/ +{ + VARIABLE_HEADER *Variable; + VARIABLE_HEADER *NextVariable; + UINT64 VariableSize; + VARIABLE_STORE_HEADER *VariableStoreHeader; + + if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL) { + return EFI_INVALID_PARAMETER; + } + + if((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS)) == 0) { + // + // Make sure the Attributes combination is supported by the platform. + // + return EFI_UNSUPPORTED; + } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) { + // + // Make sure if runtime bit is set, boot service bit is set also. + // + return EFI_INVALID_PARAMETER; + } else if (EfiAtRuntime () && !(Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) { + // + // Make sure RT Attribute is set if we are in Runtime phase. + // + return EFI_INVALID_PARAMETER; + } + + AcquireLockOnlyAtBootTime(&Global->VariableServicesLock); + + if((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) { + // + // Query is Volatile related. + // + VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase); + } else { + // + // Query is Non-Volatile related. + // + VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) Global->NonVolatileVariableBase); + } + + // + // Now let's fill *MaximumVariableStorageSize *RemainingVariableStorageSize + // with the storage size (excluding the storage header size). + // + *MaximumVariableStorageSize = VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER); + *RemainingVariableStorageSize = VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER); + + // + // Let *MaximumVariableSize be MAX_VARIABLE_SIZE. + // + *MaximumVariableSize = MAX_VARIABLE_SIZE; + + // + // Point to the starting address of the variables. + // + Variable = (VARIABLE_HEADER *) (VariableStoreHeader + 1); + + // + // Now walk through the related variable store. + // + while (IsValidVariableHeader (Variable) && (Variable < GetEndPointer (VariableStoreHeader))) { + NextVariable = GetNextVariablePtr (Variable); + VariableSize = (UINT64) (UINTN) NextVariable - (UINT64) (UINTN) Variable; + + if (EfiAtRuntime ()) { + // + // we don't take the state of the variables in mind + // when calculating RemainingVariableStorageSize, + // since the space occupied by variables not marked with + // VAR_ADDED is not allowed to be reclaimed in Runtime. + // + *RemainingVariableStorageSize -= VariableSize; + } else { + // + // Only care about Variables with State VAR_ADDED,because + // the space not marked as VAR_ADDED is reclaimable now. + // + if (Variable->State == VAR_ADDED) { + *RemainingVariableStorageSize -= VariableSize; + } + } + + // + // Go to the next one + // + Variable = NextVariable; + } + + ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock); + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +VariableCommonInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + This function does common initialization for variable services + +Arguments: + + ImageHandle - The firmware allocated handle for the EFI image. + SystemTable - A pointer to the EFI System Table. + +Returns: + + Status code. + + EFI_NOT_FOUND - Variable store area not found. + EFI_UNSUPPORTED - Currently only one non-volatile variable store is supported. + EFI_SUCCESS - Variable services successfully initialized. + +--*/ +{ + EFI_STATUS Status; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + CHAR8 *CurrPtr; + VARIABLE_STORE_HEADER *VolatileVariableStore; + VARIABLE_STORE_HEADER *VariableStoreHeader; + VARIABLE_HEADER *NextVariable; + UINT32 Instance; + EFI_PHYSICAL_ADDRESS FvVolHdr; + + UINT64 TempVariableStoreHeader; + + EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor; + EFI_FLASH_SUBAREA_ENTRY VariableStoreEntry; + UINT64 BaseAddress; + UINT64 Length; + UINTN Index; + UINT8 Data; + + mVariableModuleGlobal = AllocateRuntimePool (sizeof (ESAL_VARIABLE_GLOBAL)); + if (mVariableModuleGlobal == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + EfiInitializeLock(&mVariableModuleGlobal->VariableGlobal[Physical].VariableServicesLock, TPL_NOTIFY); + + // + // Allocate memory for volatile variable store + // + VolatileVariableStore = AllocateRuntimePool (VARIABLE_STORE_SIZE + SCRATCH_SIZE); + if (VolatileVariableStore == NULL) { + FreePool (mVariableModuleGlobal); + return EFI_OUT_OF_RESOURCES; + } + + SetMem (VolatileVariableStore, VARIABLE_STORE_SIZE + SCRATCH_SIZE, 0xff); + + // + // Variable Specific Data + // + mVariableModuleGlobal->VariableGlobal[Physical].VolatileVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VolatileVariableStore; + mVariableModuleGlobal->VolatileLastVariableOffset = sizeof (VARIABLE_STORE_HEADER); + + VolatileVariableStore->Signature = VARIABLE_STORE_SIGNATURE; + VolatileVariableStore->Size = VARIABLE_STORE_SIZE; + VolatileVariableStore->Format = VARIABLE_STORE_FORMATTED; + VolatileVariableStore->State = VARIABLE_STORE_HEALTHY; + VolatileVariableStore->Reserved = 0; + VolatileVariableStore->Reserved1 = 0; + + // + // Get non volatile varaible store + // + + TempVariableStoreHeader = (UINT64) PcdGet32 (PcdFlashNvStorageVariableBase); + VariableStoreEntry.Base = TempVariableStoreHeader + \ + (((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (TempVariableStoreHeader)) -> HeaderLength); + VariableStoreEntry.Length = (UINT64) PcdGet32 (PcdFlashNvStorageVariableSize) - \ + (((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (TempVariableStoreHeader)) -> HeaderLength); + // + // Mark the variable storage region of the FLASH as RUNTIME + // + BaseAddress = VariableStoreEntry.Base & (~EFI_PAGE_MASK); + Length = VariableStoreEntry.Length + (VariableStoreEntry.Base - BaseAddress); + Length = (Length + EFI_PAGE_SIZE - 1) & (~EFI_PAGE_MASK); + + Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &GcdDescriptor); + if (EFI_ERROR (Status)) { + FreePool (mVariableModuleGlobal); + FreePool (VolatileVariableStore); + return EFI_UNSUPPORTED; + } + + Status = gDS->SetMemorySpaceAttributes ( + BaseAddress, + Length, + GcdDescriptor.Attributes | EFI_MEMORY_RUNTIME + ); + if (EFI_ERROR (Status)) { + FreePool (mVariableModuleGlobal); + FreePool (VolatileVariableStore); + return EFI_UNSUPPORTED; + } + // + // Get address of non volatile variable store base + // + mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase = VariableStoreEntry.Base; + + // + // Check Integrity + // + // + // Find the Correct Instance of the FV Block Service. + // + Instance = 0; + CurrPtr = (CHAR8 *) ((UINTN) mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase); + while (EfiFvbGetPhysicalAddress (Instance, &FvVolHdr) == EFI_SUCCESS) { + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvVolHdr); + if (CurrPtr >= (CHAR8 *) FwVolHeader && CurrPtr < (((CHAR8 *) FwVolHeader) + FwVolHeader->FvLength)) { + mVariableModuleGlobal->FvbInstance = Instance; + break; + } + + Instance++; + } + + VariableStoreHeader = (VARIABLE_STORE_HEADER *) CurrPtr; + if (GetVariableStoreStatus (VariableStoreHeader) == EfiValid) { + if (~VariableStoreHeader->Size == 0) { + Status = UpdateVariableStore ( + &mVariableModuleGlobal->VariableGlobal[Physical], + FALSE, + FALSE, + mVariableModuleGlobal->FvbInstance, + (UINTN) &VariableStoreHeader->Size, + sizeof (UINT32), + (UINT8 *) &VariableStoreEntry.Length + ); + // + // As Variables are stored in NV storage, which are slow devices,such as flash. + // Variable operation may skip checking variable program result to improve performance, + // We can assume Variable program is OK through some check point. + // Variable Store Size Setting should be the first Variable write operation, + // We can assume all Read/Write is OK if we can set Variable store size successfully. + // If write fail, we will assert here + // + ASSERT(VariableStoreHeader->Size == VariableStoreEntry.Length); + + if (EFI_ERROR (Status)) { + return Status; + } + } + + mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase = (EFI_PHYSICAL_ADDRESS) ((UINTN) CurrPtr); + // + // Parse non-volatile variable data and get last variable offset + // + NextVariable = (VARIABLE_HEADER *) (CurrPtr + sizeof (VARIABLE_STORE_HEADER)); + Status = EFI_SUCCESS; + + while (IsValidVariableHeader (NextVariable)) { + NextVariable = GetNextVariablePtr (NextVariable); + } + + mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN) NextVariable - (UINTN) CurrPtr; + + // + // Check if the free area is blow a threshold + // + if ((((VARIABLE_STORE_HEADER *)((UINTN) CurrPtr))->Size - mVariableModuleGlobal->NonVolatileLastVariableOffset) < VARIABLE_RECLAIM_THRESHOLD) { + Status = Reclaim ( + mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase, + &mVariableModuleGlobal->NonVolatileLastVariableOffset, + FALSE + ); + } + + if (EFI_ERROR (Status)) { + FreePool (mVariableModuleGlobal); + FreePool (VolatileVariableStore); + return Status; + } + + // + // Check if the free area is really free. + // + for (Index = mVariableModuleGlobal->NonVolatileLastVariableOffset; Index < VariableStoreHeader->Size; Index++) { + Data = ((UINT8 *) (UINTN) mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase)[Index]; + if (Data != 0xff) { + // + // There must be something wrong in variable store, do reclaim operation. + // + Status = Reclaim ( + mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase, + &mVariableModuleGlobal->NonVolatileLastVariableOffset, + FALSE + ); + break; + } + } + } + + if (EFI_ERROR (Status)) { + FreePool (mVariableModuleGlobal); + FreePool (VolatileVariableStore); + } + + return Status; +} diff --git a/MdeModulePkg/Universal/VariableRuntimeDxe/Variable.dxs b/MdeModulePkg/Universal/VariableRuntimeDxe/Variable.dxs new file mode 100644 index 0000000000..f4aa840e42 --- /dev/null +++ b/MdeModulePkg/Universal/VariableRuntimeDxe/Variable.dxs @@ -0,0 +1,32 @@ +/*++ + +Copyright (c) 2006, 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: + + Ia32Variable.dxs + +Abstract: + + Dependency expression source file. + +--*/ +// +// Include common header file for this module. +// +#include "CommonHeader.h" + +#include + +DEPENDENCY_START + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID AND + EFI_ALTERNATE_FV_BLOCK_GUID AND + EFI_FTW_LITE_PROTOCOL_GUID +DEPENDENCY_END diff --git a/MdeModulePkg/Universal/VariableRuntimeDxe/Variable.h b/MdeModulePkg/Universal/VariableRuntimeDxe/Variable.h new file mode 100644 index 0000000000..aff0b8265b --- /dev/null +++ b/MdeModulePkg/Universal/VariableRuntimeDxe/Variable.h @@ -0,0 +1,158 @@ +/*++ + +Copyright (c) 2006 - 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: + + Variable.h + +Abstract: + +--*/ + +#ifndef _VARIABLE_H +#define _VARIABLE_H + +// +// Include common header file for this module. +// +#include "CommonHeader.h" + +// +// Statements that include other header files +// + +// +// BugBug: We need relcate the head file. +// +#include + +#define VARIABLE_RECLAIM_THRESHOLD (1024) + +#define VARIABLE_STORE_SIZE (64 * 1024) +#define SCRATCH_SIZE (4 * 1024) + +// +// Define GET_PAD_SIZE to optimize compiler +// +#if ((ALIGNMENT == 0) || (ALIGNMENT == 1)) +#define GET_PAD_SIZE(a) (0) +#else +#define GET_PAD_SIZE(a) (((~a) + 1) & (ALIGNMENT - 1)) +#endif + +#define GET_VARIABLE_NAME_PTR(a) (CHAR16 *) ((UINTN) (a) + sizeof (VARIABLE_HEADER)) + +typedef enum { + Physical, + Virtual +} VARIABLE_POINTER_TYPE; + +typedef struct { + VARIABLE_HEADER *CurrPtr; + VARIABLE_HEADER *EndPtr; + VARIABLE_HEADER *StartPtr; + BOOLEAN Volatile; +} VARIABLE_POINTER_TRACK; + +typedef struct { + EFI_PHYSICAL_ADDRESS VolatileVariableBase; + EFI_PHYSICAL_ADDRESS NonVolatileVariableBase; + EFI_LOCK VariableServicesLock; +} VARIABLE_GLOBAL; + +typedef struct { + VARIABLE_GLOBAL VariableGlobal[2]; + UINTN VolatileLastVariableOffset; + UINTN NonVolatileLastVariableOffset; + UINT32 FvbInstance; +} ESAL_VARIABLE_GLOBAL; + +extern ESAL_VARIABLE_GLOBAL *mVariableModuleGlobal; + +// +// Functions +// +EFI_STATUS +EFIAPI +VariableCommonInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +; + +EFI_STATUS +EFIAPI +VariableServiceInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +; + +VOID +EFIAPI +VariableClassAddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +; + +EFI_STATUS +EFIAPI +GetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID * VendorGuid, + OUT UINT32 *Attributes OPTIONAL, + IN OUT UINTN *DataSize, + OUT VOID *Data, + IN VARIABLE_GLOBAL * Global, + IN UINT32 Instance + ) +; + +EFI_STATUS +EFIAPI +GetNextVariableName ( + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VendorGuid, + IN VARIABLE_GLOBAL *Global, + IN UINT32 Instance + ) +; + +EFI_STATUS +EFIAPI +SetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data, + IN VARIABLE_GLOBAL *Global, + IN UINTN *VolatileOffset, + IN UINTN *NonVolatileOffset, + IN UINT32 Instance + ) +; + +EFI_STATUS +EFIAPI +QueryVariableInfo ( + IN UINT32 Attributes, + OUT UINT64 *MaximumVariableStorageSize, + OUT UINT64 *RemainingVariableStorageSize, + OUT UINT64 *MaximumVariableSize, + IN VARIABLE_GLOBAL *Global, + IN UINT32 Instance + ) +; + +#endif diff --git a/MdeModulePkg/Universal/VariableRuntimeDxe/Variable.inf b/MdeModulePkg/Universal/VariableRuntimeDxe/Variable.inf new file mode 100644 index 0000000000..c9d9f928dc --- /dev/null +++ b/MdeModulePkg/Universal/VariableRuntimeDxe/Variable.inf @@ -0,0 +1,123 @@ +#/** @file +# Component description file for Variable module. +# +# This module installs three EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName. +# Copyright (c) 2006 - 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. +# +# +#**/ + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = Variable + FILE_GUID = CBD2E4D5-7068-4FF5-B462-9822B4AD8D60 + MODULE_TYPE = DXE_RUNTIME_DRIVER + VERSION_STRING = 1.0 + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + ENTRY_POINT = VariableServiceInitialize + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# +# VIRTUAL_ADDRESS_MAP_CALLBACK = VariableClassAddressChangeEvent +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources.common] + Variable.dxs + InitVariable.c + reclaim.c + reclaim.h + Variable.c + Variable.h + CommonHeader.h + + +################################################################################ +# +# Includes Section - list of Include locations that are required for +# this module. +# +################################################################################ + +[Includes] + $(WORKSPACE)/MdePkg/Include/Library + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + $(WORKSPACE)/IntelFrameworkPkg/IntelFrameworkPkg.dec + $(WORKSPACE)/MdePkg/MdePkg.dec + $(WORKSPACE)/MdeModulePkg/MdeModulePkg.dec + +################################################################################ +# +# Library Class Section - list of Library Classes that are required for +# this module. +# +################################################################################ + +[LibraryClasses] + MemoryAllocationLib + BaseLib + UefiLib + UefiBootServicesTableLib + FvbServiceLib + BaseMemoryLib + DebugLib + UefiRuntimeLib + DxeServicesTableLib + UefiDriverEntryPoint + PcdLib + + +################################################################################ +# +# Protocol C Name Section - list of Protocol and Protocol Notify C Names +# that this module uses or produces. +# +################################################################################ + +[Protocols] + gEfiFirmwareVolumeBlockProtocolGuid # PROTOCOL SOMETIMES_CONSUMED + gEfiFaultTolerantWriteLiteProtocolGuid # PROTOCOL SOMETIMES_CONSUMED + gEfiVariableWriteArchProtocolGuid # PROTOCOL ALWAYS_PRODUCED + gEfiVariableArchProtocolGuid # PROTOCOL ALWAYS_PRODUCED + + +################################################################################ +# +# Pcd DYNAMIC - list of PCDs that this module is coded for. +# +################################################################################ + +[PcdsDynamic.common] + PcdFlashNvStorageVariableSize|gEfiGenericPlatformTokenSpaceGuid + PcdFlashNvStorageVariableBase|gEfiGenericPlatformTokenSpaceGuid + diff --git a/MdeModulePkg/Universal/VariableRuntimeDxe/Variable.msa b/MdeModulePkg/Universal/VariableRuntimeDxe/Variable.msa new file mode 100644 index 0000000000..56f19b0437 --- /dev/null +++ b/MdeModulePkg/Universal/VariableRuntimeDxe/Variable.msa @@ -0,0 +1,108 @@ + + + + Variable + DXE_RUNTIME_DRIVER + CBD2E4D5-7068-4FF5-B462-9822B4AD8D60 + 1.0 + Component description file for Variable module. + This module installs three EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName. + Copyright (c) 2006 - 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. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 + false + Variable + + + + PcdLib + + + UefiDriverEntryPoint + + + DxeServicesTableLib + + + UefiRuntimeLib + + + DebugLib + + + BaseMemoryLib + + + EdkFvbServiceLib + + + UefiBootServicesTableLib + + + UefiLib + + + BaseLib + + + MemoryAllocationLib + + + + Variable.h + Variable.c + reclaim.h + reclaim.c + InitVariable.c + Variable.dxs + + + + + + + + gEfiVariableArchProtocolGuid + + + gEfiVariableWriteArchProtocolGuid + + + gEfiFaultTolerantWriteLiteProtocolGuid + + + gEfiFirmwareVolumeBlockProtocolGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + VariableServiceInitialize + + + VariableClassAddressChangeEvent + + + + + PcdFlashNvStorageVariableBase + gEfiGenericPlatformTokenSpaceGuid + The driver gets the Variable store base address from this PCD. This base address point to + an EFI_FIRMWARE_VOLUMN_HEADER struct. + + + PcdFlashNvStorageVariableSize + gEfiGenericPlatformTokenSpaceGuid + The driver gets the NvStorage Variable Size from this PCD. + + + \ No newline at end of file diff --git a/MdeModulePkg/Universal/VariableRuntimeDxe/reclaim.c b/MdeModulePkg/Universal/VariableRuntimeDxe/reclaim.c new file mode 100644 index 0000000000..309d285e1d --- /dev/null +++ b/MdeModulePkg/Universal/VariableRuntimeDxe/reclaim.c @@ -0,0 +1,242 @@ +/*++ + +Copyright (c) 2006 - 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: + + reclaim.c + +Abstract: + + Handles non-volatile variable store garbage collection, using FTW + (Fault Tolerant Write) protocol. + +Revision History + +--*/ + + +#include "reclaim.h" +#include "Common/Variable.h" + +EFI_STATUS +GetFvbHandleByAddress ( + IN EFI_PHYSICAL_ADDRESS Address, + OUT EFI_HANDLE *FvbHandle + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN HandleCount; + UINTN Index; + EFI_PHYSICAL_ADDRESS FvbBaseAddress; + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + + *FvbHandle = NULL; + // + // Locate all handles of Fvb protocol + // + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiFirmwareVolumeBlockProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + // + // Get the FVB to access variable store + // + for (Index = 0; Index < HandleCount; Index += 1) { + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiFirmwareVolumeBlockProtocolGuid, + (VOID **) &Fvb + ); + if (EFI_ERROR (Status)) { + Status = EFI_NOT_FOUND; + break; + } + // + // Compare the address and select the right one + // + Status = Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress); + if (EFI_ERROR (Status)) { + continue; + } + + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvbBaseAddress); + if ((Address >= FvbBaseAddress) && (Address <= (FvbBaseAddress + FwVolHeader->FvLength))) { + *FvbHandle = HandleBuffer[Index]; + Status = EFI_SUCCESS; + break; + } + } + + FreePool (HandleBuffer); + return Status; +} + +STATIC +EFI_STATUS +GetLbaAndOffsetByAddress ( + IN EFI_PHYSICAL_ADDRESS Address, + OUT EFI_LBA *Lba, + OUT UINTN *Offset + ) +{ + EFI_STATUS Status; + EFI_HANDLE FvbHandle; + EFI_PHYSICAL_ADDRESS FvbBaseAddress; + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb; + FRAMEWORK_EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + EFI_FV_BLOCK_MAP_ENTRY *FvbMapEntry; + UINT32 LbaIndex; + + *Lba = (EFI_LBA) (-1); + *Offset = 0; + + // + // Get the proper FVB + // + Status = GetFvbHandleByAddress (Address, &FvbHandle); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->HandleProtocol ( + FvbHandle, + &gEfiFirmwareVolumeBlockProtocolGuid, + (VOID **) &Fvb + ); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Get the Base Address of FV + // + Status = Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress); + if (EFI_ERROR (Status)) { + return Status; + } + + FwVolHeader = (FRAMEWORK_EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvbBaseAddress); + + // + // Get the (LBA, Offset) of Address + // + if ((Address >= FvbBaseAddress) && (Address <= (FvbBaseAddress + FwVolHeader->FvLength))) { + if ((FwVolHeader->FvLength) > (FwVolHeader->HeaderLength)) { + // + // BUGBUG: Assume one FV has one type of BlockLength + // + FvbMapEntry = &FwVolHeader->FvBlockMap[0]; + for (LbaIndex = 1; LbaIndex <= FvbMapEntry->NumBlocks; LbaIndex += 1) { + if (Address < (FvbBaseAddress + FvbMapEntry->Length * LbaIndex)) { + // + // Found the (Lba, Offset) + // + *Lba = LbaIndex - 1; + *Offset = (UINTN) (Address - (FvbBaseAddress + FvbMapEntry->Length * (LbaIndex - 1))); + return EFI_SUCCESS; + } + } + } + } + + return EFI_ABORTED; +} + +EFI_STATUS +FtwVariableSpace ( + IN EFI_PHYSICAL_ADDRESS VariableBase, + IN UINT8 *Buffer, + IN UINTN BufferSize + ) +/*++ + +Routine Description: + Write a buffer to Variable space, in the working block. + +Arguments: + FvbHandle - Indicates a handle to FVB to access variable store + Buffer - Point to the input buffer + BufferSize - The number of bytes of the input Buffer + +Returns: + EFI_SUCCESS - The function completed successfully + EFI_ABORTED - The function could not complete successfully + EFI_NOT_FOUND - Locate FVB protocol by handle fails + +--*/ +{ + EFI_STATUS Status; + EFI_HANDLE FvbHandle; + EFI_FTW_LITE_PROTOCOL *FtwLiteProtocol; + EFI_LBA VarLba; + UINTN VarOffset; + UINT8 *FtwBuffer; + UINTN FtwBufferSize; + + // + // Locate fault tolerant write protocol + // + Status = gBS->LocateProtocol ( + &gEfiFaultTolerantWriteLiteProtocolGuid, + NULL, + (VOID **) &FtwLiteProtocol + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + // + // Locate Fvb handle by address + // + Status = GetFvbHandleByAddress (VariableBase, &FvbHandle); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Get LBA and Offset by address + // + Status = GetLbaAndOffsetByAddress (VariableBase, &VarLba, &VarOffset); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + // + // Prepare for the variable data + // + FtwBufferSize = ((VARIABLE_STORE_HEADER *) ((UINTN) VariableBase))->Size; + FtwBuffer = AllocateRuntimePool (FtwBufferSize); + if (FtwBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + SetMem (FtwBuffer, FtwBufferSize, (UINT8) 0xff); + CopyMem (FtwBuffer, Buffer, BufferSize); + + // + // FTW write record + // + Status = FtwLiteProtocol->Write ( + FtwLiteProtocol, + FvbHandle, + VarLba, // LBA + VarOffset, // Offset + &FtwBufferSize, // NumBytes, + FtwBuffer + ); + + FreePool (FtwBuffer); + return Status; +} diff --git a/MdeModulePkg/Universal/VariableRuntimeDxe/reclaim.h b/MdeModulePkg/Universal/VariableRuntimeDxe/reclaim.h new file mode 100644 index 0000000000..393b5901f8 --- /dev/null +++ b/MdeModulePkg/Universal/VariableRuntimeDxe/reclaim.h @@ -0,0 +1,50 @@ +/*++ + +Copyright (c) 2006, 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: + + reclaim.h + +Abstract: + + Definitions for non-volatile variable store garbage collection + +Revision History + +--*/ + +#ifndef _VAR_RECLAIM_H +#define _VAR_RECLAIM_H + +// +// Include common header file for this module. +// +#include "CommonHeader.h" + +// +// Functions +// +EFI_STATUS +GetFvbHandleByAddress ( + IN EFI_PHYSICAL_ADDRESS VariableStoreBase, + OUT EFI_HANDLE *FvbHandle + ) +; + +EFI_STATUS +FtwVariableSpace ( + IN EFI_PHYSICAL_ADDRESS VariableBaseAddress, + IN UINT8 *Buffer, + IN UINTN BufferSize + ) +; + +#endif -- 2.39.2