summaryrefslogtreecommitdiff
path: root/MdeModulePkg
diff options
context:
space:
mode:
Diffstat (limited to 'MdeModulePkg')
-rw-r--r--MdeModulePkg/Include/Common/FlashMap.h112
-rw-r--r--MdeModulePkg/Library/EdkFvbServiceLib/CommonHeader.h49
-rw-r--r--MdeModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.inf123
-rw-r--r--MdeModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.msa81
-rw-r--r--MdeModulePkg/Library/EdkFvbServiceLib/EntryPoint.c54
-rw-r--r--MdeModulePkg/Library/EdkFvbServiceLib/Fvb.h44
-rw-r--r--MdeModulePkg/MdeModulePkg.dsc23
-rw-r--r--MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.inf2
-rw-r--r--MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.msa2
-rw-r--r--MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/CommonHeader.h35
-rw-r--r--MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/English.inf93
-rw-r--r--MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/English.msa55
-rw-r--r--MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/UnicodeCollationEng.c479
-rw-r--r--MdeModulePkg/Universal/Disk/UnicodeCollation/English/Dxe/UnicodeCollationEng.h117
-rw-r--r--MdeModulePkg/Universal/VariableRuntimeDxe/CommonHeader.h46
-rw-r--r--MdeModulePkg/Universal/VariableRuntimeDxe/InitVariable.c234
-rw-r--r--MdeModulePkg/Universal/VariableRuntimeDxe/Variable.c1479
-rw-r--r--MdeModulePkg/Universal/VariableRuntimeDxe/Variable.dxs32
-rw-r--r--MdeModulePkg/Universal/VariableRuntimeDxe/Variable.h158
-rw-r--r--MdeModulePkg/Universal/VariableRuntimeDxe/Variable.inf123
-rw-r--r--MdeModulePkg/Universal/VariableRuntimeDxe/Variable.msa108
-rw-r--r--MdeModulePkg/Universal/VariableRuntimeDxe/reclaim.c242
-rw-r--r--MdeModulePkg/Universal/VariableRuntimeDxe/reclaim.h50
23 files changed, 3738 insertions, 3 deletions
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 <Common/FrameworkHob.h>
+//
+// 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 <PiDxe.h>
+//
+// The protocols, PPI and GUID defintions for this module
+//
+#include <Protocol/FirmwareVolumeBlock.h>
+#include <Protocol/FvbExtension.h>
+//
+// The Library classes this module consumes
+//
+#include <Library/FvbServiceLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+//
+// 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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <MsaHeader>
+ <ModuleName>EdkFvbServiceLib</ModuleName>
+ <ModuleType>DXE_DRIVER</ModuleType>
+ <GuidValue>bd4d540e-04b0-4b10-8fd5-4a7bb533cf67</GuidValue>
+ <Version>1.0</Version>
+ <Abstract>FvbService Library for UEFI drivers</Abstract>
+ <Description>This library instance provide sevice functions to access Firmware Volume Block protocol.</Description>
+ <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>
+ <License>All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
+ </MsaHeader>
+ <ModuleDefinitions>
+ <SupportedArchitectures>IA32 X64 IPF</SupportedArchitectures>
+ <BinaryModule>false</BinaryModule>
+ <OutputFileBasename>EdkFvbServiceLib</OutputFileBasename>
+ </ModuleDefinitions>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_PRODUCED" SupModuleList="DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER">
+ <Keyword>EdkFvbServiceLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED" SupArchList="IA32 X64">
+ <Keyword>UefiLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED" SupArchList="IA32 X64">
+ <Keyword>BaseLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED" SupArchList="IA32 X64">
+ <Keyword>DebugLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED" SupArchList="IA32 X64">
+ <Keyword>BaseMemoryLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED" SupArchList="IA32 X64">
+ <Keyword>UefiRuntimeLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED" SupArchList="IA32 X64">
+ <Keyword>UefiBootServicesTableLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED" SupArchList="IPF">
+ <Keyword>EdkDxeSalLib</Keyword>
+ </LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>Fvb.h</Filename>
+ <Filename SupArchList="IA32">Ia32/Fvb.c</Filename>
+ <Filename SupArchList="X64">x64/Fvb.c</Filename>
+ <Filename SupArchList="IPF">Ipf/Fvb.c</Filename>
+ </SourceFiles>
+ <PackageDependencies>
+ <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
+ </PackageDependencies>
+ <Protocols>
+ <Protocol Usage="ALWAYS_CONSUMED" SupArchList="IA32 X64">
+ <ProtocolCName>gEfiFirmwareVolumeBlockProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED" SupArchList="IA32 X64">
+ <ProtocolCName>gEfiFvbExtensionProtocolGuid</ProtocolCName>
+ </Protocol>
+ <ProtocolNotify Usage="SOMETIMES_CONSUMED">
+ <ProtocolNotifyCName>gEfiFirmwareVolumeBlockProtocolGuid</ProtocolNotifyCName>
+ </ProtocolNotify>
+ </Protocols>
+ <Externs>
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
+ <Extern>
+ <Constructor>FvbLibInitialize</Constructor>
+ </Extern>
+ <Extern>
+ <SetVirtualAddressMapCallBack>FvbVirtualAddressChangeNotifyEvent</SetVirtualAddressMapCallBack>
+ </Extern>
+ </Externs>
+</ModuleSurfaceArea> \ 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. <BR>
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+**/
+
+#ifndef __FVB_H__
+#define __FVB_H__
+
+//
+// The package level header files this module uses
+//
+#include <PiDxe.h>
+//
+// The protocols, PPI and GUID defintions for this module
+//
+#include <Protocol/FirmwareVolumeBlock.h>
+#include <Protocol/FvbExtension.h>
+//
+// The Library classes this module consumes
+//
+#include <Library/FvbServiceLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#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 @@
</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
- <Filename>diskio.c</Filename>
+ <FilenameDiskIo.c</Filename>
<Filename>DiskIo.h</Filename>
<Filename>ComponentName.c</Filename>
</SourceFiles>
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 <PiDxe.h>
+
+//
+// The protocols, PPI and GUID defintions for this module
+//
+#include <Protocol/UnicodeCollation.h>
+//
+// The Library classes this module consumes
+//
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
+ <MsaHeader>
+ <ModuleName>English</ModuleName>
+ <ModuleType>UEFI_DRIVER</ModuleType>
+ <GuidValue>CD3BAFB6-50FB-4fe8-8E4E-AB74D2C1A600</GuidValue>
+ <Version>1.0</Version>
+ <Abstract>Component description file for English module for unicode collation.</Abstract>
+ <Description>This driver installs UEFI EFI_UNICODE_COLLATION_PROTOCOL protocol to provide Unicode strings function.</Description>
+ <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>
+ <License>All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
+ </MsaHeader>
+ <ModuleDefinitions>
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
+ <BinaryModule>false</BinaryModule>
+ <OutputFileBasename>English</OutputFileBasename>
+ </ModuleDefinitions>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED" RecommendedInstanceGuid="bda39d3a-451b-4350-8266-81ab10fa0523">
+ <Keyword>DebugLib</Keyword>
+ <HelpText>Recommended libary Instance is PeiDxeDebugLibReportStatusCode instance in MdePkg.</HelpText>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverEntryPoint</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiBootServicesTableLib</Keyword>
+ </LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>UnicodeCollationEng.h</Filename>
+ <Filename>UnicodeCollationEng.c</Filename>
+ </SourceFiles>
+ <PackageDependencies>
+ <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ </PackageDependencies>
+ <Protocols>
+ <Protocol Usage="ALWAYS_PRODUCED">
+ <ProtocolCName>gEfiUnicodeCollationProtocolGuid</ProtocolCName>
+ </Protocol>
+ </Protocols>
+ <Externs>
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
+ <Extern>
+ <ModuleEntryPoint>InitializeUnicodeCollationEng</ModuleEntryPoint>
+ </Extern>
+ </Externs>
+</ModuleSurfaceArea> \ 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 <PiDxe.h>
+
+//
+// The protocols, PPI and GUID defintions for this module
+//
+#include <Protocol/UnicodeCollation.h>
+//
+// The Library classes this module consumes
+//
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+//
+// 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 <FrameworkDxe.h>
+//
+// The protocols, PPI and GUID defintions for this module
+//
+#include <Protocol/VariableWrite.h>
+#include <Protocol/FaultTolerantWriteLite.h>
+#include <Protocol/FirmwareVolumeBlock.h>
+#include <Protocol/Variable.h>
+//
+// The Library classes this module consumes
+//
+#include <Library/PcdLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/FvbServiceLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+
+#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 <Common/FlashMap.h>
+
+//
+// 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 <DxeDepex.h>
+
+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 <Common/Variable.h>
+
+#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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <MsaHeader>
+ <ModuleName>Variable</ModuleName>
+ <ModuleType>DXE_RUNTIME_DRIVER</ModuleType>
+ <GuidValue>CBD2E4D5-7068-4FF5-B462-9822B4AD8D60</GuidValue>
+ <Version>1.0</Version>
+ <Abstract>Component description file for Variable module.</Abstract>
+ <Description>This module installs three EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName.</Description>
+ <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>
+ <License>All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
+ </MsaHeader>
+ <ModuleDefinitions>
+ <SupportedArchitectures>IA32 X64</SupportedArchitectures>
+ <BinaryModule>false</BinaryModule>
+ <OutputFileBasename>Variable</OutputFileBasename>
+ </ModuleDefinitions>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>PcdLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverEntryPoint</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DxeServicesTableLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiRuntimeLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DebugLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseMemoryLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>EdkFvbServiceLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiBootServicesTableLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>MemoryAllocationLib</Keyword>
+ </LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>Variable.h</Filename>
+ <Filename>Variable.c</Filename>
+ <Filename>reclaim.h</Filename>
+ <Filename>reclaim.c</Filename>
+ <Filename>InitVariable.c</Filename>
+ <Filename>Variable.dxs</Filename>
+ </SourceFiles>
+ <PackageDependencies>
+ <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
+ </PackageDependencies>
+ <Protocols>
+ <Protocol Usage="ALWAYS_PRODUCED">
+ <ProtocolCName>gEfiVariableArchProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_PRODUCED">
+ <ProtocolCName>gEfiVariableWriteArchProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="SOMETIMES_CONSUMED">
+ <ProtocolCName>gEfiFaultTolerantWriteLiteProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="SOMETIMES_CONSUMED">
+ <ProtocolCName>gEfiFirmwareVolumeBlockProtocolGuid</ProtocolCName>
+ </Protocol>
+ </Protocols>
+ <Externs>
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
+ <Extern>
+ <ModuleEntryPoint>VariableServiceInitialize</ModuleEntryPoint>
+ </Extern>
+ <Extern>
+ <SetVirtualAddressMapCallBack>VariableClassAddressChangeEvent</SetVirtualAddressMapCallBack>
+ </Extern>
+ </Externs>
+ <PcdCoded>
+ <PcdEntry PcdItemType="DYNAMIC">
+ <C_Name>PcdFlashNvStorageVariableBase</C_Name>
+ <TokenSpaceGuidCName>gEfiGenericPlatformTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText>The driver gets the Variable store base address from this PCD. This base address point to
+ an EFI_FIRMWARE_VOLUMN_HEADER struct.</HelpText>
+ </PcdEntry>
+ <PcdEntry PcdItemType="DYNAMIC">
+ <C_Name>PcdFlashNvStorageVariableSize</C_Name>
+ <TokenSpaceGuidCName>gEfiGenericPlatformTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText>The driver gets the NvStorage Variable Size from this PCD.</HelpText>
+ </PcdEntry>
+ </PcdCoded>
+</ModuleSurfaceArea> \ 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