summaryrefslogtreecommitdiff
path: root/MdeModulePkg
diff options
context:
space:
mode:
Diffstat (limited to 'MdeModulePkg')
-rw-r--r--MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c2
-rw-r--r--MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c95
-rw-r--r--MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h18
-rw-r--r--MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c50
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h1
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c32
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c76
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.h2
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c23
-rw-r--r--MdeModulePkg/Core/Dxe/DxeMain.h2
-rw-r--r--MdeModulePkg/Core/Dxe/DxeMain.inf6
-rw-r--r--MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c32
-rw-r--r--MdeModulePkg/Core/Dxe/Event/Timer.c5
-rw-r--r--MdeModulePkg/Core/Dxe/Mem/Pool.c15
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/DxeIpl.h3
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf3
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c28
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c37
-rw-r--r--MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c186
-rw-r--r--MdeModulePkg/Core/Pei/PeiMain.h14
-rw-r--r--MdeModulePkg/Core/Pei/PeiMain.inf3
-rw-r--r--MdeModulePkg/Core/Pei/PeiMain/PeiMain.c34
-rw-r--r--MdeModulePkg/Core/Pei/Ppi/Ppi.c212
-rw-r--r--MdeModulePkg/Core/PiSmmCore/Notify.c36
-rw-r--r--MdeModulePkg/Include/Guid/PcdDataBaseSignatureGuid.h147
-rw-r--r--MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h86
-rw-r--r--MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.c86
-rw-r--r--MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf4
-rw-r--r--MdeModulePkg/Library/DxeNetLib/DxeNetLib.c2
-rw-r--r--MdeModulePkg/MdeModulePkg.dec4
-rw-r--r--MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf5
-rw-r--r--MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/IA32/SetIdtEntry.c6
-rw-r--r--MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c244
-rw-r--r--MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.h7
-rw-r--r--MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/SetIdtEntry.c28
-rw-r--r--MdeModulePkg/Universal/CapsulePei/X64/X64Entry.c5
-rw-r--r--MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c942
-rw-r--r--MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c70
-rw-r--r--MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c179
-rw-r--r--MdeModulePkg/Universal/HiiDatabaseDxe/Image.c5
-rw-r--r--MdeModulePkg/Universal/Network/IScsiDxe/IScsiDriver.c67
-rw-r--r--MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.c55
-rw-r--r--MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.h16
-rw-r--r--MdeModulePkg/Universal/PCD/Dxe/Pcd.c258
-rw-r--r--MdeModulePkg/Universal/PCD/Dxe/Pcd.inf41
-rw-r--r--MdeModulePkg/Universal/PCD/Dxe/Service.c755
-rw-r--r--MdeModulePkg/Universal/PCD/Dxe/Service.h108
-rw-r--r--MdeModulePkg/Universal/PCD/Pei/Pcd.c312
-rw-r--r--MdeModulePkg/Universal/PCD/Pei/Pcd.inf42
-rw-r--r--MdeModulePkg/Universal/PCD/Pei/Service.c492
-rw-r--r--MdeModulePkg/Universal/PCD/Pei/Service.h119
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Expression.c88
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c26
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c208
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Setup.c680
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Setup.h25
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/Reclaim.c24
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c272
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h6
59 files changed, 4106 insertions, 2223 deletions
diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c
index ed1c4bf39..4f187e3ab 100644
--- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c
+++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c
@@ -129,7 +129,7 @@ EnumerateNvmeDevNamespace (
Device->Media.WriteCaching = FALSE;
Flbas = NamespaceData->Flbas;
- LbaFmtIdx = Flbas & 3;
+ LbaFmtIdx = Flbas & 0xF;
Lbads = NamespaceData->LbaFormat[LbaFmtIdx].Lbads;
Device->Media.BlockSize = (UINT32)1 << Lbads;
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
index 443df729d..5ca58fbb9 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
@@ -32,6 +32,13 @@ USB_PORT_STATE_MAP mUsbPortChangeMap[] = {
{XHC_PORTSC_PRC, USB_PORT_STAT_C_RESET}
};
+USB_CLEAR_PORT_MAP mUsbClearPortChangeMap[] = {
+ {XHC_PORTSC_CSC, EfiUsbPortConnectChange},
+ {XHC_PORTSC_PEC, EfiUsbPortEnableChange},
+ {XHC_PORTSC_OCC, EfiUsbPortOverCurrentChange},
+ {XHC_PORTSC_PRC, EfiUsbPortResetChange}
+};
+
USB_PORT_STATE_MAP mUsbHubPortStateMap[] = {
{XHC_HUB_PORTSC_CCS, USB_PORT_STAT_CONNECTION},
{XHC_HUB_PORTSC_PED, USB_PORT_STAT_ENABLE},
@@ -46,6 +53,14 @@ USB_PORT_STATE_MAP mUsbHubPortChangeMap[] = {
{XHC_HUB_PORTSC_PRC, USB_PORT_STAT_C_RESET}
};
+USB_CLEAR_PORT_MAP mUsbHubClearPortChangeMap[] = {
+ {XHC_HUB_PORTSC_CSC, EfiUsbPortConnectChange},
+ {XHC_HUB_PORTSC_PEC, EfiUsbPortEnableChange},
+ {XHC_HUB_PORTSC_OCC, EfiUsbPortOverCurrentChange},
+ {XHC_HUB_PORTSC_PRC, EfiUsbPortResetChange},
+ {XHC_HUB_PORTSC_BHRC, Usb3PortBHPortResetChange}
+};
+
EFI_DRIVER_BINDING_PROTOCOL gXhciDriverBinding = {
XhcDriverBindingSupported,
XhcDriverBindingStart,
@@ -432,6 +447,14 @@ XhcGetRootHubPortStatus (
}
}
+ MapSize = sizeof (mUsbClearPortChangeMap) / sizeof (USB_CLEAR_PORT_MAP);
+
+ for (Index = 0; Index < MapSize; Index++) {
+ if (XHC_BIT_IS_SET (State, mUsbClearPortChangeMap[Index].HwState)) {
+ XhcClearRootHubPortFeature (This, PortNumber, mUsbClearPortChangeMap[Index].Selector);
+ }
+ }
+
//
// Poll the root port status register to enable/disable corresponding device slot if there is a device attached/detached.
// For those devices behind hub, we get its attach/detach event by hooking Get_Port_Status request at control transfer for those hub.
@@ -469,8 +492,6 @@ XhcSetRootHubPortFeature (
UINT32 Offset;
UINT32 State;
UINT32 TotalPort;
- UINT8 SlotId;
- USB_DEV_ROUTE RouteChart;
EFI_STATUS Status;
EFI_TPL OldTpl;
@@ -526,24 +547,13 @@ XhcSetRootHubPortFeature (
}
}
- RouteChart.Route.RouteString = 0;
- RouteChart.Route.RootPortNum = PortNumber + 1;
- RouteChart.Route.TierNum = 1;
//
- // If the port reset operation happens after the usb super speed device is enabled,
- // The subsequent configuration, such as getting device descriptor, will fail.
- // So here a workaround is introduced to skip the reset operation if the device is enabled.
+ // 4.3.1 Resetting a Root Hub Port
+ // 1) Write the PORTSC register with the Port Reset (PR) bit set to '1'.
//
- SlotId = XhcRouteStringToSlotId (Xhc, RouteChart);
- if (SlotId == 0) {
- //
- // 4.3.1 Resetting a Root Hub Port
- // 1) Write the PORTSC register with the Port Reset (PR) bit set to '1'.
- //
- State |= XHC_PORTSC_RESET;
- XhcWriteOpReg (Xhc, Offset, State);
- XhcWaitOpRegBit(Xhc, Offset, XHC_PORTSC_PRC, TRUE, XHC_GENERIC_TIMEOUT);
- }
+ State |= XHC_PORTSC_RESET;
+ XhcWriteOpReg (Xhc, Offset, State);
+ XhcWaitOpRegBit(Xhc, Offset, XHC_PORTSC_PRC, TRUE, XHC_GENERIC_TIMEOUT);
break;
case EfiUsbPortPower:
@@ -763,6 +773,8 @@ XhcControlTransfer (
UINTN MapSize;
EFI_USB_PORT_STATUS PortStatus;
UINT32 State;
+ EFI_USB_DEVICE_REQUEST ClearPortRequest;
+ UINTN Len;
//
// Validate parameters
@@ -808,6 +820,7 @@ XhcControlTransfer (
Status = EFI_DEVICE_ERROR;
*TransferResult = EFI_USB_ERR_SYSTEM;
+ Len = 0;
if (XhcIsHalt (Xhc) || XhcIsSysError (Xhc)) {
DEBUG ((EFI_D_ERROR, "XhcControlTransfer: HC halted at entrance\n"));
@@ -839,6 +852,11 @@ XhcControlTransfer (
Xhc->UsbDevContext[Index + 1].BusDevAddr = 0;
}
}
+
+ if (Xhc->UsbDevContext[SlotId].XhciDevAddr == 0) {
+ Status = EFI_DEVICE_ERROR;
+ goto ON_EXIT;
+ }
//
// The actual device address has been assigned by XHCI during initializing the device slot.
// So we just need establish the mapping relationship between the device address requested from UsbBus
@@ -849,20 +867,6 @@ XhcControlTransfer (
Status = EFI_SUCCESS;
goto ON_EXIT;
}
-
- //
- // If the port reset operation happens after the usb super speed device is enabled,
- // The subsequent configuration, such as getting device descriptor, will fail.
- // So here a workaround is introduced to skip the reset operation if the device is enabled.
- //
- if ((Request->Request == USB_REQ_SET_FEATURE) &&
- (Request->RequestType == USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_CLASS, USB_TARGET_OTHER)) &&
- (Request->Value == EfiUsbPortReset)) {
- if (DeviceSpeed == EFI_USB_SPEED_SUPER) {
- Status = EFI_SUCCESS;
- goto ON_EXIT;
- }
- }
//
// Create a new URB, insert it into the asynchronous
@@ -1050,6 +1054,33 @@ XhcControlTransfer (
}
}
+ MapSize = sizeof (mUsbHubClearPortChangeMap) / sizeof (USB_CLEAR_PORT_MAP);
+
+ for (Index = 0; Index < MapSize; Index++) {
+ if (XHC_BIT_IS_SET (State, mUsbHubClearPortChangeMap[Index].HwState)) {
+ ZeroMem (&ClearPortRequest, sizeof (EFI_USB_DEVICE_REQUEST));
+ ClearPortRequest.RequestType = USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_CLASS, USB_TARGET_OTHER);
+ ClearPortRequest.Request = (UINT8) USB_REQ_CLEAR_FEATURE;
+ ClearPortRequest.Value = mUsbHubClearPortChangeMap[Index].Selector;
+ ClearPortRequest.Index = Request->Index;
+ ClearPortRequest.Length = 0;
+
+ XhcControlTransfer (
+ This,
+ DeviceAddress,
+ DeviceSpeed,
+ MaximumPacketLength,
+ &ClearPortRequest,
+ EfiUsbNoData,
+ NULL,
+ &Len,
+ Timeout,
+ Translator,
+ TransferResult
+ );
+ }
+ }
+
XhcPollPortStatusChange (Xhc, Xhc->UsbDevContext[SlotId].RouteString, (UINT8)Request->Index, &PortStatus);
*(UINT32 *)Data = *(UINT32*)&PortStatus;
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h b/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h
index 20a5510bf..dc8281198 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h
@@ -2,7 +2,7 @@
This file contains the register definition of XHCI host controller.
-Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -169,7 +169,7 @@ typedef union {
#define XHC_PORTSC_RESET BIT4 // Port Reset
#define XHC_PORTSC_PLS (BIT5|BIT6|BIT7|BIT8) // Port Link State
#define XHC_PORTSC_PP BIT9 // Port Power
-#define XHC_PORTSC_PS (BIT10|BIT11|BIT12|BIT13) // Port Speed
+#define XHC_PORTSC_PS (BIT10|BIT11|BIT12) // Port Speed
#define XHC_PORTSC_LWS BIT16 // Port Link State Write Strobe
#define XHC_PORTSC_CSC BIT17 // Connect Status Change
#define XHC_PORTSC_PEC BIT18 // Port Enabled/Disabled Change
@@ -189,6 +189,7 @@ typedef union {
#define XHC_HUB_PORTSC_PEC BIT17 // Hub's Port Enabled/Disabled Change
#define XHC_HUB_PORTSC_OCC BIT19 // Hub's Over-Current Change
#define XHC_HUB_PORTSC_PRC BIT20 // Hub's Port Reset Change
+#define XHC_HUB_PORTSC_BHRC BIT21 // Hub's Port Warm Reset Change
#define XHC_IMAN_IP BIT0 // Interrupt Pending
#define XHC_IMAN_IE BIT1 // Interrupt Enable
@@ -196,6 +197,11 @@ typedef union {
#define XHC_IMODC_MASK 0xFFFF0000 // Interrupt Moderation Counter
//
+// Hub Class Feature Selector for Clear Port Feature Request
+//
+#define Usb3PortBHPortResetChange 29
+
+//
// Structure to map the hardware port states to the
// UEFI's port states.
//
@@ -204,6 +210,14 @@ typedef struct {
UINT16 UefiState;
} USB_PORT_STATE_MAP;
+//
+// Structure to map the hardware port states to feature selector for clear port feature request.
+//
+typedef struct {
+ UINT32 HwState;
+ UINT16 Selector;
+} USB_CLEAR_PORT_MAP;
+
/**
Read 1-byte width XHCI capability register.
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
index dea5b1af1..ec13e49a7 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
@@ -1105,25 +1105,25 @@ XhcCheckUrbResult (
CheckedUrb->Result |= EFI_USB_ERR_STALL;
CheckedUrb->Finished = TRUE;
DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: STALL_ERROR! Completecode = %x\n",EvtTrb->Completecode));
- break;
+ goto EXIT;
case TRB_COMPLETION_BABBLE_ERROR:
CheckedUrb->Result |= EFI_USB_ERR_BABBLE;
CheckedUrb->Finished = TRUE;
DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: BABBLE_ERROR! Completecode = %x\n",EvtTrb->Completecode));
- break;
+ goto EXIT;
case TRB_COMPLETION_DATA_BUFFER_ERROR:
CheckedUrb->Result |= EFI_USB_ERR_BUFFER;
CheckedUrb->Finished = TRUE;
DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: ERR_BUFFER! Completecode = %x\n",EvtTrb->Completecode));
- break;
+ goto EXIT;
case TRB_COMPLETION_USB_TRANSACTION_ERROR:
CheckedUrb->Result |= EFI_USB_ERR_TIMEOUT;
CheckedUrb->Finished = TRUE;
DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: TRANSACTION_ERROR! Completecode = %x\n",EvtTrb->Completecode));
- break;
+ goto EXIT;
case TRB_COMPLETION_SHORT_PACKET:
case TRB_COMPLETION_SUCCESS:
@@ -1144,7 +1144,7 @@ XhcCheckUrbResult (
DEBUG ((EFI_D_ERROR, "Transfer Default Error Occur! Completecode = 0x%x!\n",EvtTrb->Completecode));
CheckedUrb->Result |= EFI_USB_ERR_TIMEOUT;
CheckedUrb->Finished = TRUE;
- break;
+ goto EXIT;
}
//
@@ -1535,6 +1535,10 @@ XhcPollPortStatusChange (
Status = EFI_SUCCESS;
+ if ((PortState->PortChangeStatus & (USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE | USB_PORT_STAT_C_OVERCURRENT | USB_PORT_STAT_C_RESET)) == 0) {
+ return EFI_SUCCESS;
+ }
+
if (ParentRouteChart.Dword == 0) {
RouteChart.Route.RouteString = 0;
RouteChart.Route.RootPortNum = Port + 1;
@@ -1549,6 +1553,15 @@ XhcPollPortStatusChange (
RouteChart.Route.TierNum = ParentRouteChart.Route.TierNum + 1;
}
+ SlotId = XhcRouteStringToSlotId (Xhc, RouteChart);
+ if (SlotId != 0) {
+ if (Xhc->HcCParams.Data.Csz == 0) {
+ Status = XhcDisableSlotCmd (Xhc, SlotId);
+ } else {
+ Status = XhcDisableSlotCmd64 (Xhc, SlotId);
+ }
+ }
+
if (((PortState->PortStatus & USB_PORT_STAT_ENABLE) != 0) &&
((PortState->PortStatus & USB_PORT_STAT_CONNECTION) != 0)) {
//
@@ -1566,26 +1579,15 @@ XhcPollPortStatusChange (
// Execute Enable_Slot cmd for attached device, initialize device context and assign device address.
//
SlotId = XhcRouteStringToSlotId (Xhc, RouteChart);
- if (SlotId == 0) {
+ if ((SlotId == 0) && ((PortState->PortChangeStatus & USB_PORT_STAT_C_RESET) != 0)) {
if (Xhc->HcCParams.Data.Csz == 0) {
Status = XhcInitializeDeviceSlot (Xhc, ParentRouteChart, Port, RouteChart, Speed);
} else {
Status = XhcInitializeDeviceSlot64 (Xhc, ParentRouteChart, Port, RouteChart, Speed);
}
}
- } else if ((PortState->PortStatus & USB_PORT_STAT_CONNECTION) == 0) {
- //
- // Device is detached. Disable the allocated device slot and release resource.
- //
- SlotId = XhcRouteStringToSlotId (Xhc, RouteChart);
- if (SlotId != 0) {
- if (Xhc->HcCParams.Data.Csz == 0) {
- Status = XhcDisableSlotCmd (Xhc, SlotId);
- } else {
- Status = XhcDisableSlotCmd64 (Xhc, SlotId);
- }
- }
- }
+ }
+
return Status;
}
@@ -2633,9 +2635,10 @@ XhcSetConfigCmd (
if ((DeviceSpeed == EFI_USB_SPEED_FULL) || (DeviceSpeed == EFI_USB_SPEED_LOW)) {
Interval = EpDesc->Interval;
//
- // Hard code the interval to MAX first, need calculate through the bInterval field of Endpoint descriptor.
+ // Calculate through the bInterval field of Endpoint descriptor.
//
- InputContext->EP[Dci-1].Interval = 6;
+ ASSERT (Interval != 0);
+ InputContext->EP[Dci-1].Interval = (UINT32)HighBitSet32((UINT32)Interval) + 3;
} else if ((DeviceSpeed == EFI_USB_SPEED_HIGH) || (DeviceSpeed == EFI_USB_SPEED_SUPER)) {
Interval = EpDesc->Interval;
ASSERT (Interval >= 1 && Interval <= 16);
@@ -2830,9 +2833,10 @@ XhcSetConfigCmd64 (
if ((DeviceSpeed == EFI_USB_SPEED_FULL) || (DeviceSpeed == EFI_USB_SPEED_LOW)) {
Interval = EpDesc->Interval;
//
- // Hard code the interval to MAX first, need calculate through the bInterval field of Endpoint descriptor.
+ // Calculate through the bInterval field of Endpoint descriptor.
//
- InputContext->EP[Dci-1].Interval = 6;
+ ASSERT (Interval != 0);
+ InputContext->EP[Dci-1].Interval = (UINT32)HighBitSet32((UINT32)Interval) + 3;
} else if ((DeviceSpeed == EFI_USB_SPEED_HIGH) || (DeviceSpeed == EFI_USB_SPEED_SUPER)) {
Interval = EpDesc->Interval;
ASSERT (Interval >= 1 && Interval <= 16);
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h
index d503a278a..9ede83ab7 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h
@@ -198,6 +198,7 @@ struct _USB_DEVICE {
USB_INTERFACE *ParentIf;
UINT8 ParentPort; // Start at 0
UINT8 Tier;
+ BOOLEAN DisconnectFail;
};
//
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c
index b2401ca40..9687eb0bc 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c
@@ -142,15 +142,15 @@ UsbFreeDevDesc (
VOID *
UsbCreateDesc (
IN UINT8 *DescBuf,
- IN INTN Len,
+ IN UINTN Len,
IN UINT8 Type,
- OUT INTN *Consumed
+ OUT UINTN *Consumed
)
{
USB_DESC_HEAD *Head;
- INTN DescLen;
- INTN CtrlLen;
- INTN Offset;
+ UINTN DescLen;
+ UINTN CtrlLen;
+ UINTN Offset;
VOID *Desc;
DescLen = 0;
@@ -188,7 +188,15 @@ UsbCreateDesc (
while ((Offset < Len) && (Head->Type != Type)) {
Offset += Head->Len;
+ if (Len <= Offset) {
+ DEBUG (( EFI_D_ERROR, "UsbCreateDesc: met mal-format descriptor, Beyond boundary!\n"));
+ return NULL;
+ }
Head = (USB_DESC_HEAD*)(DescBuf + Offset);
+ if (Head->Len == 0) {
+ DEBUG (( EFI_D_ERROR, "UsbCreateDesc: met mal-format descriptor, Head->Len = 0!\n"));
+ return NULL;
+ }
}
if ((Len <= Offset) || (Len < Offset + DescLen) ||
@@ -223,16 +231,16 @@ UsbCreateDesc (
USB_INTERFACE_SETTING *
UsbParseInterfaceDesc (
IN UINT8 *DescBuf,
- IN INTN Len,
- OUT INTN *Consumed
+ IN UINTN Len,
+ OUT UINTN *Consumed
)
{
USB_INTERFACE_SETTING *Setting;
USB_ENDPOINT_DESC *Ep;
UINTN Index;
UINTN NumEp;
- INTN Used;
- INTN Offset;
+ UINTN Used;
+ UINTN Offset;
*Consumed = 0;
Setting = UsbCreateDesc (DescBuf, Len, USB_DESC_TYPE_INTERFACE, &Used);
@@ -265,7 +273,7 @@ UsbParseInterfaceDesc (
//
// Create the endpoints for this interface
//
- for (Index = 0; Index < NumEp; Index++) {
+ for (Index = 0; (Index < NumEp) && (Offset < Len); Index++) {
Ep = UsbCreateDesc (DescBuf + Offset, Len - Offset, USB_DESC_TYPE_ENDPOINT, &Used);
if (Ep == NULL) {
@@ -300,7 +308,7 @@ ON_ERROR:
USB_CONFIG_DESC *
UsbParseConfigDesc (
IN UINT8 *DescBuf,
- IN INTN Len
+ IN UINTN Len
)
{
USB_CONFIG_DESC *Config;
@@ -308,7 +316,7 @@ UsbParseConfigDesc (
USB_INTERFACE_DESC *Interface;
UINTN Index;
UINTN NumIf;
- INTN Consumed;
+ UINTN Consumed;
ASSERT (DescBuf != NULL);
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
index 79635cb18..430f5aa3d 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
@@ -450,7 +450,7 @@ UsbSelectConfig (
@param UsbIf The interface to disconnect driver from.
**/
-VOID
+EFI_STATUS
UsbDisconnectDriver (
IN USB_INTERFACE *UsbIf
)
@@ -462,8 +462,9 @@ UsbDisconnectDriver (
// Release the hub if it's a hub controller, otherwise
// disconnect the driver if it is managed by other drivers.
//
+ Status = EFI_SUCCESS;
if (UsbIf->IsHub) {
- UsbIf->HubApi->Release (UsbIf);
+ Status = UsbIf->HubApi->Release (UsbIf);
} else if (UsbIf->IsManaged) {
//
@@ -479,13 +480,17 @@ UsbDisconnectDriver (
gBS->RestoreTPL (TPL_CALLBACK);
Status = gBS->DisconnectController (UsbIf->Handle, NULL, NULL);
- UsbIf->IsManaged = FALSE;
-
+ if (!EFI_ERROR (Status)) {
+ UsbIf->IsManaged = FALSE;
+ }
+
DEBUG (( EFI_D_INFO, "UsbDisconnectDriver: TPL after disconnect is %d, %d\n", (UINT32)UsbGetCurrentTpl(), Status));
ASSERT (UsbGetCurrentTpl () == TPL_CALLBACK);
gBS->RaiseTPL (OldTpl);
}
+
+ return Status;
}
@@ -495,17 +500,20 @@ UsbDisconnectDriver (
@param Device The USB device to remove configuration from.
**/
-VOID
+EFI_STATUS
UsbRemoveConfig (
IN USB_DEVICE *Device
)
{
USB_INTERFACE *UsbIf;
UINTN Index;
+ EFI_STATUS Status;
+ EFI_STATUS ReturnStatus;
//
// Remove each interface of the device
//
+ ReturnStatus = EFI_SUCCESS;
for (Index = 0; Index < Device->NumOfInterface; Index++) {
ASSERT (Index < USB_MAX_INTERFACE);
UsbIf = Device->Interfaces[Index];
@@ -514,13 +522,17 @@ UsbRemoveConfig (
continue;
}
- UsbDisconnectDriver (UsbIf);
- UsbFreeInterface (UsbIf);
- Device->Interfaces[Index] = NULL;
+ Status = UsbDisconnectDriver (UsbIf);
+ if (!EFI_ERROR (Status)) {
+ UsbFreeInterface (UsbIf);
+ Device->Interfaces[Index] = NULL;
+ } else {
+ ReturnStatus = Status;
+ }
}
Device->ActiveConfig = NULL;
- Device->NumOfInterface = 0;
+ return ReturnStatus;
}
@@ -540,6 +552,7 @@ UsbRemoveDevice (
USB_BUS *Bus;
USB_DEVICE *Child;
EFI_STATUS Status;
+ EFI_STATUS ReturnStatus;
UINTN Index;
Bus = Device->Bus;
@@ -548,6 +561,7 @@ UsbRemoveDevice (
// Remove all the devices on its downstream ports. Search from devices[1].
// Devices[0] is the root hub.
//
+ ReturnStatus = EFI_SUCCESS;
for (Index = 1; Index < Bus->MaxDevices; Index++) {
Child = Bus->Devices[Index];
@@ -557,21 +571,31 @@ UsbRemoveDevice (
Status = UsbRemoveDevice (Child);
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "UsbRemoveDevice: failed to remove child, ignore error\n"));
+ if (!EFI_ERROR (Status)) {
Bus->Devices[Index] = NULL;
+ } else {
+ Bus->Devices[Index]->DisconnectFail = TRUE;
+ ReturnStatus = Status;
+ DEBUG ((EFI_D_INFO, "UsbRemoveDevice: failed to remove child %p at parent %p\n", Child, Device));
}
}
- UsbRemoveConfig (Device);
+ if (EFI_ERROR (ReturnStatus)) {
+ return ReturnStatus;
+ }
- DEBUG (( EFI_D_INFO, "UsbRemoveDevice: device %d removed\n", Device->Address));
+ Status = UsbRemoveConfig (Device);
- ASSERT (Device->Address < Bus->MaxDevices);
- Bus->Devices[Device->Address] = NULL;
- UsbFreeDevice (Device);
+ if (!EFI_ERROR (Status)) {
+ DEBUG (( EFI_D_INFO, "UsbRemoveDevice: device %d removed\n", Device->Address));
- return EFI_SUCCESS;
+ ASSERT (Device->Address < Bus->MaxDevices);
+ Bus->Devices[Device->Address] = NULL;
+ UsbFreeDevice (Device);
+ } else {
+ Bus->Devices[Device->Address]->DisconnectFail = TRUE;
+ }
+ return Status;
}
@@ -968,11 +992,20 @@ UsbHubEnumeration (
UINT8 Byte;
UINT8 Bit;
UINT8 Index;
-
+ USB_DEVICE *Child;
+
ASSERT (Context != NULL);
HubIf = (USB_INTERFACE *) Context;
+ for (Index = 0; Index < HubIf->NumOfPort; Index++) {
+ Child = UsbFindChild (HubIf, Index);
+ if ((Child != NULL) && (Child->DisconnectFail == TRUE)) {
+ DEBUG (( EFI_D_INFO, "UsbEnumeratePort: The device disconnect fails at port %d from hub %p, try again\n", Index, HubIf));
+ UsbRemoveDevice (Child);
+ }
+ }
+
if (HubIf->ChangeMap == NULL) {
return ;
}
@@ -1015,10 +1048,17 @@ UsbRootHubEnumeration (
{
USB_INTERFACE *RootHub;
UINT8 Index;
+ USB_DEVICE *Child;
RootHub = (USB_INTERFACE *) Context;
for (Index = 0; Index < RootHub->NumOfPort; Index++) {
+ Child = UsbFindChild (RootHub, Index);
+ if ((Child != NULL) && (Child->DisconnectFail == TRUE)) {
+ DEBUG (( EFI_D_INFO, "UsbEnumeratePort: The device disconnect fails at port %d from root hub %p, try again\n", Index, RootHub));
+ UsbRemoveDevice (Child);
+ }
+
UsbEnumeratePort (RootHub, Index);
}
}
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.h b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.h
index 288d38f63..ef7d44091 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.h
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.h
@@ -151,7 +151,7 @@ UsbSelectConfig (
@return None.
**/
-VOID
+EFI_STATUS
UsbRemoveConfig (
IN USB_DEVICE *Device
);
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c
index 9e5299c0e..e3752d1f8 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c
@@ -968,6 +968,15 @@ UsbHubResetPort (
UINTN Index;
EFI_STATUS Status;
+ Status = UsbHubGetPortStatus (HubIf, Port, &PortState);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ } else if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_RESET)) {
+ DEBUG (( EFI_D_INFO, "UsbHubResetPort: skip reset on hub %p port %d\n", HubIf, Port));
+ return EFI_SUCCESS;
+ }
+
Status = UsbHubSetPortFeature (HubIf, Port, (EFI_USB_PORT_FEATURE) USB_HUB_PORT_RESET);
if (EFI_ERROR (Status)) {
@@ -988,6 +997,10 @@ UsbHubResetPort (
for (Index = 0; Index < USB_WAIT_PORT_STS_CHANGE_LOOP; Index++) {
Status = UsbHubGetPortStatus (HubIf, Port, &PortState);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
if (!EFI_ERROR (Status) &&
USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_RESET)) {
gBS->Stall (USB_SET_PORT_RECOVERY_STALL);
@@ -1268,6 +1281,16 @@ UsbRootHubResetPort (
// should be handled in the EHCI driver.
//
Bus = RootIf->Device->Bus;
+
+ Status = UsbHcGetRootHubPortStatus (Bus, Port, &PortState);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ } else if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_RESET)) {
+ DEBUG (( EFI_D_INFO, "UsbRootHubResetPort: skip reset on root port %d\n", Port));
+ return EFI_SUCCESS;
+ }
+
Status = UsbHcSetRootHubPortFeature (Bus, Port, EfiUsbPortReset);
if (EFI_ERROR (Status)) {
diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h
index 1e057a5d9..3b2b11d27 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain.h
+++ b/MdeModulePkg/Core/Dxe/DxeMain.h
@@ -67,6 +67,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Guid/EventExitBootServiceFailed.h>
#include <Guid/LoadModuleAtFixedAddress.h>
#include <Guid/IdleLoopEvent.h>
+#include <Guid/VectorHandoffTable.h>
+#include <Ppi/VectorHandoffInfo.h>
#include <Library/DxeCoreEntryPoint.h>
#include <Library/DebugLib.h>
diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf
index 58a4dd9b5..bd9a4bd56 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain.inf
+++ b/MdeModulePkg/Core/Dxe/DxeMain.inf
@@ -2,7 +2,7 @@
# This is core module in DXE phase. It provides an implementation of DXE Core that is
# compliant with DXE CIS.
#
-# Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
# 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
@@ -112,6 +112,10 @@
gLoadFixedAddressConfigurationTableGuid ## SOMETIMES_CONSUMES
gIdleLoopEventGuid ## CONSUMES ## GUID
gEventExitBootServicesFailedGuid ## CONSUMES ## GUID
+ gEfiVectorHandoffTableGuid ## SOMETIMES_PRODUCES ## Configuration
+
+[Ppis]
+ gEfiVectorHandoffInfoPpiGuid ## UNDEFINED
[Protocols]
gEfiStatusCodeRuntimeProtocolGuid ## SOMETIMES_CONSUMES
diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
index ed5a3c9e1..6d2ff8202 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
+++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
@@ -1,7 +1,7 @@
/** @file
DXE Core Main Entry Point
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -242,11 +242,21 @@ DxeMain (
EFI_PHYSICAL_ADDRESS MemoryBaseAddress;
UINT64 MemoryLength;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ UINTN Index;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ EFI_VECTOR_HANDOFF_INFO *VectorInfoList;
+ EFI_VECTOR_HANDOFF_INFO *VectorInfo;
//
// Setup the default exception handlers
//
- SetupCpuExceptionHandlers ();
+ VectorInfoList = NULL;
+ GuidHob = GetNextGuidHob (&gEfiVectorHandoffInfoPpiGuid, HobStart);
+ if (GuidHob != NULL) {
+ VectorInfoList = (EFI_VECTOR_HANDOFF_INFO *) (GET_GUID_HOB_DATA(GuidHob));
+ }
+ Status = InitializeCpuExceptionHandlers (VectorInfoList);
+ ASSERT_EFI_ERROR (Status);
//
// Initialize Debug Agent to support source level debug in DXE phase
@@ -371,6 +381,24 @@ DxeMain (
Status = CoreInitializeEventServices ();
ASSERT_EFI_ERROR (Status);
+ //
+ // Get persisted vector hand-off info from GUIDeed HOB again due to HobStart may be updated,
+ // and install configuration table
+ //
+ GuidHob = GetNextGuidHob (&gEfiVectorHandoffInfoPpiGuid, HobStart);
+ if (GuidHob != NULL) {
+ VectorInfoList = (EFI_VECTOR_HANDOFF_INFO *) (GET_GUID_HOB_DATA(GuidHob));
+ VectorInfo = VectorInfoList;
+ Index = 1;
+ while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) {
+ VectorInfo ++;
+ Index ++;
+ }
+ VectorInfo = AllocateCopyPool (sizeof (EFI_VECTOR_HANDOFF_INFO) * Index, (VOID *) VectorInfoList);
+ ASSERT (VectorInfo != NULL);
+ Status = CoreInstallConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID *) VectorInfo);
+ ASSERT_EFI_ERROR (Status);
+ }
//
// Get the Protocols that were passed in from PEI to DXE through GUIDed HOBs
diff --git a/MdeModulePkg/Core/Dxe/Event/Timer.c b/MdeModulePkg/Core/Dxe/Event/Timer.c
index 3b17ae917..087e55e64 100644
--- a/MdeModulePkg/Core/Dxe/Event/Timer.c
+++ b/MdeModulePkg/Core/Dxe/Event/Timer.c
@@ -1,7 +1,7 @@
/** @file
Core Timer Services
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -281,6 +281,9 @@ CoreSetTimer (
if (Type != TimerCancel) {
if (Type == TimerPeriodic) {
+ if (TriggerTime == 0) {
+ gTimer->GetTimerPeriod (gTimer, &TriggerTime);
+ }
Event->Timer.Period = TriggerTime;
}
diff --git a/MdeModulePkg/Core/Dxe/Mem/Pool.c b/MdeModulePkg/Core/Dxe/Mem/Pool.c
index e0f0869e5..bc785a8b9 100644
--- a/MdeModulePkg/Core/Dxe/Mem/Pool.c
+++ b/MdeModulePkg/Core/Dxe/Mem/Pool.c
@@ -1,7 +1,7 @@
/** @file
UEFI Memory pool management functions.
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -26,9 +26,9 @@ typedef struct {
#define POOL_HEAD_SIGNATURE SIGNATURE_32('p','h','d','0')
typedef struct {
UINT32 Signature;
- UINT32 Size;
+ UINT32 Reserved;
EFI_MEMORY_TYPE Type;
- UINTN Reserved;
+ UINTN Size;
CHAR8 Data[1];
} POOL_HEAD;
@@ -37,7 +37,8 @@ typedef struct {
#define POOL_TAIL_SIGNATURE SIGNATURE_32('p','t','a','l')
typedef struct {
UINT32 Signature;
- UINT32 Size;
+ UINT32 Reserved;
+ UINTN Size;
} POOL_TAIL;
@@ -97,7 +98,7 @@ CoreInitializePool (
mPoolHead[Type].Used = 0;
mPoolHead[Type].MemoryType = (EFI_MEMORY_TYPE) Type;
for (Index=0; Index < MAX_POOL_LIST; Index++) {
- InitializeListHead (&mPoolHead[Type].FreeList[Index]);
+ InitializeListHead (&mPoolHead[Type].FreeList[Index]);
}
}
}
@@ -331,11 +332,11 @@ Done:
// If we have a pool buffer, fill in the header & tail info
//
Head->Signature = POOL_HEAD_SIGNATURE;
- Head->Size = (UINT32) Size;
+ Head->Size = Size;
Head->Type = (EFI_MEMORY_TYPE) PoolType;
Tail = HEAD_TO_TAIL (Head);
Tail->Signature = POOL_TAIL_SIGNATURE;
- Tail->Size = (UINT32) Size;
+ Tail->Size = Size;
Buffer = Head->Data;
DEBUG_CLEAR_MEMORY (Buffer, Size - POOL_OVERHEAD);
diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h
index 97086345a..75372ace8 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h
@@ -2,7 +2,7 @@
Master header file for DxeIpl PEIM. All source files in this module should
include this file for common definitions.
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -27,6 +27,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Ppi/LoadFile.h>
#include <Ppi/S3Resume2.h>
#include <Ppi/RecoveryModule.h>
+#include <Ppi/VectorHandoffInfo.h>
#include <Guid/MemoryTypeInformation.h>
#include <Guid/MemoryAllocationHob.h>
diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
index 986250bdc..85d0069c2 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
@@ -5,7 +5,7 @@
# PPI to discover and dispatch the DXE Foundation and components that are
# needed to run the DXE Foundation.
#
-# Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
# 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
@@ -83,6 +83,7 @@
gEfiPeiLoadFilePpiGuid ## CONSUMES
gEfiPeiS3Resume2PpiGuid ## SOMETIMES_CONSUMES(Consumed on S3 boot path)
gEfiPeiRecoveryModulePpiGuid ## SOMETIMES_CONSUMES(Consumed on recovery boot path)
+ gEfiVectorHandoffInfoPpiGuid ## SOMETIMES_CONSUMES
[Guids]
gEfiMemoryTypeInformationGuid ## SOMETIMES_CONSUMES ## Variable:L"MemoryTypeInformation"
diff --git a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c b/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
index b121e2439..38832cc36 100644
--- a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
+++ b/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
@@ -1,7 +1,7 @@
/** @file
Ia32-specific functionality for DxeLoad.
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -83,6 +83,8 @@ HandOffToDxeCore (
EFI_PHYSICAL_ADDRESS VectorAddress;
UINT32 Index;
X64_IDT_TABLE *IdtTableForX64;
+ EFI_VECTOR_HANDOFF_INFO *VectorInfo;
+ EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi;
Status = PeiServicesAllocatePages (EfiBootServicesData, EFI_SIZE_TO_PAGES (STACK_SIZE), &BaseOfStack);
ASSERT_EFI_ERROR (Status);
@@ -183,6 +185,30 @@ HandOffToDxeCore (
);
} else {
//
+ // Get Vector Hand-off Info PPI and build Guided HOB
+ //
+ Status = PeiServicesLocatePpi (
+ &gEfiVectorHandoffInfoPpiGuid,
+ 0,
+ NULL,
+ (VOID **)&VectorHandoffInfoPpi
+ );
+ if (Status == EFI_SUCCESS) {
+ DEBUG ((EFI_D_INFO, "Vector Hand-off Info PPI is gotten, GUIDed HOB is created!\n"));
+ VectorInfo = VectorHandoffInfoPpi->Info;
+ Index = 1;
+ while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) {
+ VectorInfo ++;
+ Index ++;
+ }
+ BuildGuidDataHob (
+ &gEfiVectorHandoffInfoPpiGuid,
+ VectorHandoffInfoPpi->Info,
+ sizeof (EFI_VECTOR_HANDOFF_INFO) * Index
+ );
+ }
+
+ //
// Compute the top of the stack we were allocated. Pre-allocate a UINTN
// for safety.
//
diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c b/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c
index a6e5c2804..88f1f4746 100644
--- a/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c
+++ b/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c
@@ -1,7 +1,7 @@
/** @file
x64-specifc functionality for DxeLoad.
-Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -34,10 +34,37 @@ HandOffToDxeCore (
IN EFI_PEI_HOB_POINTERS HobList
)
{
- VOID *BaseOfStack;
- VOID *TopOfStack;
- EFI_STATUS Status;
- UINTN PageTables;
+ VOID *BaseOfStack;
+ VOID *TopOfStack;
+ EFI_STATUS Status;
+ UINTN PageTables;
+ UINT32 Index;
+ EFI_VECTOR_HANDOFF_INFO *VectorInfo;
+ EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi;
+
+ //
+ // Get Vector Hand-off Info PPI and build Guided HOB
+ //
+ Status = PeiServicesLocatePpi (
+ &gEfiVectorHandoffInfoPpiGuid,
+ 0,
+ NULL,
+ (VOID **)&VectorHandoffInfoPpi
+ );
+ if (Status == EFI_SUCCESS) {
+ DEBUG ((EFI_D_INFO, "Vector Hand-off Info PPI is gotten, GUIDed HOB is created!\n"));
+ VectorInfo = VectorHandoffInfoPpi->Info;
+ Index = 1;
+ while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) {
+ VectorInfo ++;
+ Index ++;
+ }
+ BuildGuidDataHob (
+ &gEfiVectorHandoffInfoPpiGuid,
+ VectorHandoffInfoPpi->Info,
+ sizeof (EFI_VECTOR_HANDOFF_INFO) * Index
+ );
+ }
//
// Allocate 128KB for the Stack
diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
index f4392b78d..96381cd8c 100644
--- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
+++ b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
@@ -606,6 +606,29 @@ PeiLoadFixAddressHook(
PrivateData->PhysicalMemoryBegin = TopLoadingAddress - TotalReservedMemorySize;
PrivateData->FreePhysicalMemoryTop = PrivateData->PhysicalMemoryBegin + PeiMemorySize;
}
+
+/**
+ This routine is invoked in switch stack as PeiCore Entry.
+
+ @param SecCoreData Points to a data structure containing information about the PEI core's operating
+ environment, such as the size and location of temporary RAM, the stack location and
+ the BFV location.
+ @param Private Pointer to old core data that is used to initialize the
+ core's data areas.
+**/
+VOID
+EFIAPI
+PeiCoreEntry (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN PEI_CORE_INSTANCE *Private
+ )
+{
+ //
+ // Entry PEI Phase 2
+ //
+ PeiCore (SecCoreData, NULL, Private);
+}
+
/**
Conduct PEIM dispatch.
@@ -637,17 +660,28 @@ PeiDispatcher (
PEIM_FILE_HANDLE_EXTENDED_DATA ExtendedData;
EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI *TemporaryRamSupportPpi;
UINT64 NewStackSize;
+ EFI_PHYSICAL_ADDRESS BaseOfNewHeap;
EFI_PHYSICAL_ADDRESS TopOfNewStack;
EFI_PHYSICAL_ADDRESS TopOfOldStack;
EFI_PHYSICAL_ADDRESS TemporaryRamBase;
UINTN TemporaryRamSize;
- EFI_PHYSICAL_ADDRESS TemporaryStackSize;
+ UINTN TemporaryStackSize;
+ VOID *TemporaryStackBase;
+ UINTN PeiTemporaryRamSize;
+ VOID *PeiTemporaryRamBase;
UINTN StackOffset;
BOOLEAN StackOffsetPositive;
+ EFI_PHYSICAL_ADDRESS HoleMemBase;
+ UINTN HoleMemSize;
EFI_FV_FILE_INFO FvFileInfo;
PEI_CORE_FV_HANDLE *CoreFvHandle;
VOID *LoadFixPeiCodeBegin;
-
+ EFI_PHYSICAL_ADDRESS TempBase1;
+ UINTN TempSize1;
+ EFI_PHYSICAL_ADDRESS TempBase2;
+ UINTN TempSize2;
+ UINTN Index;
+
PeiServices = (CONST EFI_PEI_SERVICES **) &Private->Ps;
PeimEntryPoint = NULL;
PeimFileHandle = NULL;
@@ -881,13 +915,6 @@ PeiDispatcher (
//
TopOfOldStack = (UINTN)SecCoreData->StackBase + SecCoreData->StackSize;
TopOfNewStack = Private->PhysicalMemoryBegin + NewStackSize;
- if (TopOfNewStack >= (UINTN)SecCoreData->PeiTemporaryRamBase) {
- Private->HeapOffsetPositive = TRUE;
- Private->HeapOffset = (UINTN)(TopOfNewStack - (UINTN)SecCoreData->PeiTemporaryRamBase);
- } else {
- Private->HeapOffsetPositive = FALSE;
- Private->HeapOffset = (UINTN)((UINTN)SecCoreData->PeiTemporaryRamBase - TopOfNewStack);
- }
if (TopOfNewStack >= TopOfOldStack) {
StackOffsetPositive = TRUE;
StackOffset = (UINTN)(TopOfNewStack - TopOfOldStack);
@@ -909,21 +936,13 @@ PeiDispatcher (
//
// Cache information from SecCoreData into locals before SecCoreData is converted to a permanent memory address
//
- TemporaryRamBase = (EFI_PHYSICAL_ADDRESS)(UINTN)SecCoreData->TemporaryRamBase;
- TemporaryRamSize = SecCoreData->TemporaryRamSize;
- TemporaryStackSize = SecCoreData->StackSize;
-
- //
- // Caculate new HandOffTable and PrivateData address in permanent memory's stack
- //
- if (StackOffsetPositive) {
- SecCoreData = (CONST EFI_SEC_PEI_HAND_OFF *)((UINTN)(VOID *)SecCoreData + StackOffset);
- Private = (PEI_CORE_INSTANCE *)((UINTN)(VOID *)Private + StackOffset);
- } else {
- SecCoreData = (CONST EFI_SEC_PEI_HAND_OFF *)((UINTN)(VOID *)SecCoreData - StackOffset);
- Private = (PEI_CORE_INSTANCE *)((UINTN)(VOID *)Private - StackOffset);
- }
-
+ TemporaryRamBase = (EFI_PHYSICAL_ADDRESS)(UINTN)SecCoreData->TemporaryRamBase;
+ TemporaryRamSize = SecCoreData->TemporaryRamSize;
+ TemporaryStackSize = SecCoreData->StackSize;
+ TemporaryStackBase = SecCoreData->StackBase;
+ PeiTemporaryRamSize = SecCoreData->PeiTemporaryRamSize;
+ PeiTemporaryRamBase = SecCoreData->PeiTemporaryRamBase;
+
//
// TemporaryRamSupportPpi is produced by platform's SEC
//
@@ -935,6 +954,29 @@ PeiDispatcher (
);
if (!EFI_ERROR (Status)) {
//
+ // Heap Offset
+ //
+ BaseOfNewHeap = TopOfNewStack;
+ if (BaseOfNewHeap >= (UINTN)SecCoreData->PeiTemporaryRamBase) {
+ Private->HeapOffsetPositive = TRUE;
+ Private->HeapOffset = (UINTN)(BaseOfNewHeap - (UINTN)SecCoreData->PeiTemporaryRamBase);
+ } else {
+ Private->HeapOffsetPositive = FALSE;
+ Private->HeapOffset = (UINTN)((UINTN)SecCoreData->PeiTemporaryRamBase - BaseOfNewHeap);
+ }
+
+ //
+ // Caculate new HandOffTable and PrivateData address in permanent memory's stack
+ //
+ if (StackOffsetPositive) {
+ SecCoreData = (CONST EFI_SEC_PEI_HAND_OFF *)((UINTN)(VOID *)SecCoreData + StackOffset);
+ Private = (PEI_CORE_INSTANCE *)((UINTN)(VOID *)Private + StackOffset);
+ } else {
+ SecCoreData = (CONST EFI_SEC_PEI_HAND_OFF *)((UINTN)(VOID *)SecCoreData - StackOffset);
+ Private = (PEI_CORE_INSTANCE *)((UINTN)(VOID *)Private - StackOffset);
+ }
+
+ //
// Temporary Ram Support PPI is provided by platform, it will copy
// temporary memory to permenent memory and do stack switching.
// After invoking Temporary Ram Support PPI, the following code's
@@ -947,18 +989,98 @@ PeiDispatcher (
TemporaryRamSize
);
+ //
+ // Entry PEI Phase 2
+ //
+ PeiCore (SecCoreData, NULL, Private);
} else {
//
- // In IA32/x64/Itanium architecture, we need platform provide
- // TEMPORARY_RAM_MIGRATION_PPI.
+ // Heap Offset
//
- ASSERT (FALSE);
- }
+ BaseOfNewHeap = TopOfNewStack;
+ HoleMemBase = TopOfNewStack;
+ HoleMemSize = TemporaryRamSize - PeiTemporaryRamSize - TemporaryStackSize;
+ if (HoleMemSize != 0) {
+ BaseOfNewHeap = BaseOfNewHeap + HoleMemSize;
+ }
+ if (BaseOfNewHeap >= (UINTN)SecCoreData->PeiTemporaryRamBase) {
+ Private->HeapOffsetPositive = TRUE;
+ Private->HeapOffset = (UINTN)(BaseOfNewHeap - (UINTN)SecCoreData->PeiTemporaryRamBase);
+ } else {
+ Private->HeapOffsetPositive = FALSE;
+ Private->HeapOffset = (UINTN)((UINTN)SecCoreData->PeiTemporaryRamBase - BaseOfNewHeap);
+ }
- //
- // Entry PEI Phase 2
- //
- PeiCore (SecCoreData, NULL, Private);
+ //
+ // Migrate Heap
+ //
+ CopyMem ((UINT8 *) (UINTN) BaseOfNewHeap, (UINT8 *) PeiTemporaryRamBase, PeiTemporaryRamSize);
+
+ //
+ // Migrate Stack
+ //
+ CopyMem ((UINT8 *) (UINTN) (TopOfNewStack - TemporaryStackSize), TemporaryStackBase, TemporaryStackSize);
+
+ //
+ // Copy Hole Range Data
+ // Convert PPI from Hole.
+ //
+ if (HoleMemSize != 0) {
+ //
+ // Prepare Hole
+ //
+ if (PeiTemporaryRamBase < TemporaryStackBase) {
+ TempBase1 = (EFI_PHYSICAL_ADDRESS) (UINTN) PeiTemporaryRamBase;
+ TempSize1 = PeiTemporaryRamSize;
+ TempBase2 = (EFI_PHYSICAL_ADDRESS) (UINTN) TemporaryStackBase;
+ TempSize2 = TemporaryStackSize;
+ } else {
+ TempBase1 = (EFI_PHYSICAL_ADDRESS) (UINTN) TemporaryStackBase;
+ TempSize1 = TemporaryStackSize;
+ TempBase2 =(EFI_PHYSICAL_ADDRESS) (UINTN) PeiTemporaryRamBase;
+ TempSize2 = PeiTemporaryRamSize;
+ }
+ if (TemporaryRamBase < TempBase1) {
+ Private->HoleData[0].Base = TemporaryRamBase;
+ Private->HoleData[0].Size = (UINTN) (TempBase1 - TemporaryRamBase);
+ }
+ if (TempBase1 + TempSize1 < TempBase2) {
+ Private->HoleData[1].Base = TempBase1 + TempSize1;
+ Private->HoleData[1].Size = (UINTN) (TempBase2 - TempBase1 - TempSize1);
+ }
+ if (TempBase2 + TempSize2 < TemporaryRamBase + TemporaryRamSize) {
+ Private->HoleData[2].Base = TempBase2 + TempSize2;
+ Private->HoleData[2].Size = (UINTN) (TemporaryRamBase + TemporaryRamSize - TempBase2 - TempSize2);
+ }
+
+ //
+ // Copy Hole Range data.
+ //
+ for (Index = 0; Index < HOLE_MAX_NUMBER; Index ++) {
+ if (Private->HoleData[Index].Size > 0) {
+ if (HoleMemBase > Private->HoleData[Index].Base) {
+ Private->HoleData[Index].OffsetPositive = TRUE;
+ Private->HoleData[Index].Offset = (UINTN) (HoleMemBase - Private->HoleData[Index].Base);
+ } else {
+ Private->HoleData[Index].OffsetPositive = FALSE;
+ Private->HoleData[Index].Offset = (UINTN) (Private->HoleData[Index].Base - HoleMemBase);
+ }
+ CopyMem ((VOID *) (UINTN) HoleMemBase, (VOID *) (UINTN) Private->HoleData[Index].Base, Private->HoleData[Index].Size);
+ HoleMemBase = HoleMemBase + Private->HoleData[Index].Size;
+ }
+ }
+ }
+
+ //
+ // Switch new stack
+ //
+ SwitchStack (
+ (SWITCH_STACK_ENTRY_POINT)(UINTN)PeiCoreEntry,
+ (VOID *) SecCoreData,
+ (VOID *) Private,
+ (VOID *) (UINTN) TopOfNewStack
+ );
+ }
//
// Code should not come here
diff --git a/MdeModulePkg/Core/Pei/PeiMain.h b/MdeModulePkg/Core/Pei/PeiMain.h
index 6a9feb03c..9656f0718 100644
--- a/MdeModulePkg/Core/Pei/PeiMain.h
+++ b/MdeModulePkg/Core/Pei/PeiMain.h
@@ -28,6 +28,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Ppi/LoadFile.h>
#include <Ppi/Security2.h>
#include <Ppi/TemporaryRamSupport.h>
+#include <Ppi/TemporaryRamDone.h>
#include <Library/DebugLib.h>
#include <Library/PeiCoreEntryPoint.h>
#include <Library/BaseLib.h>
@@ -132,6 +133,14 @@ typedef struct {
UINTN SectionIndex;
} CACHE_SECTION_DATA;
+#define HOLE_MAX_NUMBER 0x3
+typedef struct {
+ EFI_PHYSICAL_ADDRESS Base;
+ UINTN Size;
+ UINTN Offset;
+ BOOLEAN OffsetPositive;
+} HOLE_MEMORY_DATA;
+
///
/// Forward declaration for PEI_CORE_INSTANCE
///
@@ -225,6 +234,11 @@ struct _PEI_CORE_INSTANCE {
// This field points to the shadowed image read function
//
PE_COFF_LOADER_READ_FILE ShadowedImageRead;
+ //
+ // Temp Memory Range is not covered by PeiTempMem and Stack.
+ // Those Memory Range will be migrated into phisical memory.
+ //
+ HOLE_MEMORY_DATA HoleData[HOLE_MAX_NUMBER];
};
///
diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf b/MdeModulePkg/Core/Pei/PeiMain.inf
index 26d1c49d5..27e754283 100644
--- a/MdeModulePkg/Core/Pei/PeiMain.inf
+++ b/MdeModulePkg/Core/Pei/PeiMain.inf
@@ -84,7 +84,8 @@
gEfiPeiFirmwareVolumeInfo2PpiGuid ## NOTIFY ## SOMETIMES_PRODUCES (Produce FvInfo2Ppi if the encapsulated FvImage is found)
gEfiPeiLoadFilePpiGuid ## PRODUCES ## SOMETIMES_CONSUMES (The default load PeImage logic will be used when this PPI doesn't exist)
gEfiPeiSecurity2PpiGuid ## NOTIFY
- gEfiTemporaryRamSupportPpiGuid ## CONSUMES
+ gEfiTemporaryRamSupportPpiGuid ## SOMETIMES_CONSUMES
+ gEfiTemporaryRamDonePpiGuid ## SOMETIMES_CONSUMES
[FixedPcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxFvSupported ## CONSUMES
diff --git a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
index bf000229a..6429ad3a2 100644
--- a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
+++ b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
@@ -120,7 +120,7 @@ ShadowPeiCore (
from SEC to PEI. After switching stack in the PEI core, it will restart
with the old core data.
- @param SecCoreData Points to a data structure containing information about the PEI core's operating
+ @param SecCoreDataPtr Points to a data structure containing information about the PEI core's operating
environment, such as the size and location of temporary RAM, the stack location and
the BFV location.
@param PpiList Points to a list of one or more PPI descriptors to be installed initially by the PEI core.
@@ -137,23 +137,27 @@ ShadowPeiCore (
VOID
EFIAPI
PeiCore (
- IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreDataPtr,
IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList,
IN VOID *Data
)
{
PEI_CORE_INSTANCE PrivateData;
+ EFI_SEC_PEI_HAND_OFF *SecCoreData;
+ EFI_SEC_PEI_HAND_OFF NewSecCoreData;
EFI_STATUS Status;
PEI_CORE_TEMP_POINTERS TempPtr;
PEI_CORE_INSTANCE *OldCoreData;
EFI_PEI_CPU_IO_PPI *CpuIo;
EFI_PEI_PCI_CFG2_PPI *PciCfg;
EFI_HOB_HANDOFF_INFO_TABLE *HandoffInformationTable;
-
+ EFI_PEI_TEMPORARY_RAM_DONE_PPI *TemporaryRamDonePpi;
+
//
// Retrieve context passed into PEI Core
//
- OldCoreData = (PEI_CORE_INSTANCE *)Data;
+ OldCoreData = (PEI_CORE_INSTANCE *) Data;
+ SecCoreData = (EFI_SEC_PEI_HAND_OFF *) SecCoreDataPtr;
//
// Perform PEI Core phase specific actions.
@@ -250,9 +254,11 @@ PeiCore (
//
// Memory is available to the PEI Core and the PEI Core has been shadowed to memory.
//
-
+ CopyMem (&NewSecCoreData, SecCoreDataPtr, sizeof (NewSecCoreData));
+ SecCoreData = &NewSecCoreData;
+
CopyMem (&PrivateData, OldCoreData, sizeof (PrivateData));
-
+
CpuIo = (VOID*)PrivateData.ServiceTableShadow.CpuIo;
PciCfg = (VOID*)PrivateData.ServiceTableShadow.PciCfg;
@@ -329,6 +335,22 @@ PeiCore (
}
} else {
//
+ // Try to locate Temporary RAM Done Ppi.
+ //
+ Status = PeiServicesLocatePpi (
+ &gEfiTemporaryRamDonePpiGuid,
+ 0,
+ NULL,
+ (VOID**)&TemporaryRamDonePpi
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Disable the use of Temporary RAM after the transition from Temporary RAM to Permanent RAM is complete.
+ //
+ TemporaryRamDonePpi->TemporaryRamDone ();
+ }
+
+ //
// Alert any listeners that there is permanent memory available
//
PERF_START (NULL,"DisMem", NULL, 0);
diff --git a/MdeModulePkg/Core/Pei/Ppi/Ppi.c b/MdeModulePkg/Core/Pei/Ppi/Ppi.c
index 6664b5b89..9fe95acb8 100644
--- a/MdeModulePkg/Core/Pei/Ppi/Ppi.c
+++ b/MdeModulePkg/Core/Pei/Ppi/Ppi.c
@@ -1,7 +1,7 @@
/** @file
EFI PEI Core PPI services
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -38,7 +38,72 @@ InitializePpiServices (
/**
- Migrate the Hob list from the temporary memory stack to PEI installed memory.
+ Migrate Single PPI Pointer from the temporary memory to PEI installed memory.
+
+ @param PpiPointer Pointer to Ppi
+ @param TempBottom Base of old temporary memory
+ @param TempTop Top of old temporary memory
+ @param Offset Offset of new memory to old temporary memory.
+ @param OffsetPositive Positive flag of Offset value.
+
+**/
+VOID
+ConverSinglePpiPointer (
+ IN PEI_PPI_LIST_POINTERS *PpiPointer,
+ IN UINTN TempBottom,
+ IN UINTN TempTop,
+ IN UINTN Offset,
+ IN BOOLEAN OffsetPositive
+ )
+{
+ if (((UINTN)PpiPointer->Raw < TempTop) &&
+ ((UINTN)PpiPointer->Raw >= TempBottom)) {
+ //
+ // Convert the pointer to the PPI descriptor from the old TempRam
+ // to the relocated physical memory.
+ //
+ if (OffsetPositive) {
+ PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw + Offset);
+ } else {
+ PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw - Offset);
+ }
+
+ //
+ // Only when the PEIM descriptor is in the old TempRam should it be necessary
+ // to try to convert the pointers in the PEIM descriptor
+ //
+
+ if (((UINTN)PpiPointer->Ppi->Guid < TempTop) &&
+ ((UINTN)PpiPointer->Ppi->Guid >= TempBottom)) {
+ //
+ // Convert the pointer to the GUID in the PPI or NOTIFY descriptor
+ // from the old TempRam to the relocated physical memory.
+ //
+ if (OffsetPositive) {
+ PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid + Offset);
+ } else {
+ PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid - Offset);
+ }
+ }
+
+ //
+ // Convert the pointer to the PPI interface structure in the PPI descriptor
+ // from the old TempRam to the relocated physical memory.
+ //
+ if ((UINTN)PpiPointer->Ppi->Ppi < TempTop &&
+ (UINTN)PpiPointer->Ppi->Ppi >= TempBottom) {
+ if (OffsetPositive) {
+ PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi + Offset);
+ } else {
+ PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi - Offset);
+ }
+ }
+ }
+}
+
+/**
+
+ Migrate PPI Pointers from the temporary memory stack to PEI installed memory.
@param SecCoreData Points to a data structure containing SEC to PEI handoff data, such as the size
and location of temporary RAM, the stack location and the BFV location.
@@ -52,114 +117,47 @@ ConvertPpiPointers (
)
{
UINT8 Index;
- PEI_PPI_LIST_POINTERS *PpiPointer;
- UINTN OldHeapTop;
- UINTN OldHeapBottom;
- UINTN OldStackTop;
- UINTN OldStackBottom;
-
- OldHeapBottom = (UINTN)SecCoreData->PeiTemporaryRamBase;
- OldHeapTop = (UINTN)SecCoreData->PeiTemporaryRamBase + SecCoreData->PeiTemporaryRamSize;
- OldStackBottom = (UINTN)SecCoreData->StackBase;
- OldStackTop = (UINTN)SecCoreData->StackBase + SecCoreData->StackSize;
+ UINT8 IndexHole;
for (Index = 0; Index < FixedPcdGet32 (PcdPeiCoreMaxPpiSupported); Index++) {
- if (Index < PrivateData->PpiData.PpiListEnd ||
- Index > PrivateData->PpiData.NotifyListEnd) {
- PpiPointer = &PrivateData->PpiData.PpiListPtrs[Index];
-
- if (((UINTN)PpiPointer->Raw < OldHeapTop) &&
- ((UINTN)PpiPointer->Raw >= OldHeapBottom)) {
- //
- // Convert the pointer to the PPI descriptor from the old HOB heap
- // to the relocated HOB heap.
- //
- if (PrivateData->HeapOffsetPositive) {
- PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw + PrivateData->HeapOffset);
- } else {
- PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw - PrivateData->HeapOffset);
- }
-
- //
- // Only when the PEIM descriptor is in the old HOB should it be necessary
- // to try to convert the pointers in the PEIM descriptor
- //
-
- if (((UINTN)PpiPointer->Ppi->Guid < OldHeapTop) &&
- ((UINTN)PpiPointer->Ppi->Guid >= OldHeapBottom)) {
- //
- // Convert the pointer to the GUID in the PPI or NOTIFY descriptor
- // from the old HOB heap to the relocated HOB heap.
- //
- if (PrivateData->HeapOffsetPositive) {
- PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid + PrivateData->HeapOffset);
- } else {
- PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid - PrivateData->HeapOffset);
- }
- }
-
- //
- // Assume that no code is located in the temporary memory, so the pointer to
- // the notification function in the NOTIFY descriptor needs not be converted.
- //
- if (Index < PrivateData->PpiData.PpiListEnd &&
- (UINTN)PpiPointer->Ppi->Ppi < OldHeapTop &&
- (UINTN)PpiPointer->Ppi->Ppi >= OldHeapBottom) {
- //
- // Convert the pointer to the PPI interface structure in the PPI descriptor
- // from the old HOB heap to the relocated HOB heap.
- //
- if (PrivateData->HeapOffsetPositive) {
- PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi + PrivateData->HeapOffset);
- } else {
- PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi - PrivateData->HeapOffset);
- }
- }
- } else if (((UINTN)PpiPointer->Raw < OldStackTop) && ((UINTN)PpiPointer->Raw >= OldStackBottom)) {
- //
- // Convert the pointer to the PPI descriptor from the temporary stack
- // to the permanent PEI stack.
- //
- if (PrivateData->StackOffsetPositive) {
- PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw + PrivateData->StackOffset);
- } else {
- PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw - PrivateData->StackOffset);
- }
-
- //
- // Try to convert the pointers in the PEIM descriptor
- //
-
- if (((UINTN)PpiPointer->Ppi->Guid < OldStackTop) &&
- ((UINTN)PpiPointer->Ppi->Guid >= OldStackBottom)) {
- //
- // Convert the pointer to the GUID in the PPI or NOTIFY descriptor
- // from the the temporary stack to the permanent PEI stack.
- //
- if (PrivateData->StackOffsetPositive) {
- PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid + PrivateData->StackOffset);
- } else {
- PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid - PrivateData->StackOffset);
- }
- }
-
- //
- // Assume that no code is located in the temporary memory, so the pointer to
- // the notification function in the NOTIFY descriptor needs not be converted.
- //
- if (Index < PrivateData->PpiData.PpiListEnd &&
- (UINTN)PpiPointer->Ppi->Ppi < OldStackTop &&
- (UINTN)PpiPointer->Ppi->Ppi >= OldStackBottom) {
- //
- // Convert the pointer to the PPI interface structure in the PPI descriptor
- // from the the temporary stack to the permanent PEI stack.
- //
- if (PrivateData->StackOffsetPositive) {
- PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi + PrivateData->StackOffset);
- } else {
- PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi - PrivateData->StackOffset);
- }
+ if (Index < PrivateData->PpiData.PpiListEnd || Index > PrivateData->PpiData.NotifyListEnd) {
+ //
+ // Convert PPI pointer in old Heap
+ //
+ ConverSinglePpiPointer (
+ &PrivateData->PpiData.PpiListPtrs[Index],
+ (UINTN)SecCoreData->PeiTemporaryRamBase,
+ (UINTN)SecCoreData->PeiTemporaryRamBase + SecCoreData->PeiTemporaryRamSize,
+ PrivateData->HeapOffset,
+ PrivateData->HeapOffsetPositive
+ );
+
+ //
+ // Convert PPI pointer in old Stack
+ //
+ ConverSinglePpiPointer (
+ &PrivateData->PpiData.PpiListPtrs[Index],
+ (UINTN)SecCoreData->StackBase,
+ (UINTN)SecCoreData->StackBase + SecCoreData->StackSize,
+ PrivateData->StackOffset,
+ PrivateData->StackOffsetPositive
+ );
+
+ //
+ // Convert PPI pointer in old TempRam Hole
+ //
+ for (IndexHole = 0; IndexHole < HOLE_MAX_NUMBER; IndexHole ++) {
+ if (PrivateData->HoleData[IndexHole].Size == 0) {
+ continue;
}
+
+ ConverSinglePpiPointer (
+ &PrivateData->PpiData.PpiListPtrs[Index],
+ (UINTN)PrivateData->HoleData[IndexHole].Base,
+ (UINTN)PrivateData->HoleData[IndexHole].Base + PrivateData->HoleData[IndexHole].Size,
+ PrivateData->HoleData[IndexHole].Offset,
+ PrivateData->HoleData[IndexHole].OffsetPositive
+ );
}
}
}
diff --git a/MdeModulePkg/Core/PiSmmCore/Notify.c b/MdeModulePkg/Core/PiSmmCore/Notify.c
index eb5059dd7..5ec0aa71a 100644
--- a/MdeModulePkg/Core/PiSmmCore/Notify.c
+++ b/MdeModulePkg/Core/PiSmmCore/Notify.c
@@ -1,7 +1,7 @@
/** @file
Support functions for UEFI protocol notification infrastructure.
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -94,6 +94,8 @@ SmmRemoveInterfaceFromProtocol (
@retval EFI_INVALID_PARAMETER Invalid parameter
@retval EFI_SUCCESS Successfully returned the registration record
that has been added
+ @retval EFI_OUT_OF_RESOURCES Not enough memory resource to finish the request
+ @retval EFI_NOT_FOUND If the registration is not found when Function == NULL
**/
EFI_STATUS
@@ -109,10 +111,40 @@ SmmRegisterProtocolNotify (
LIST_ENTRY *Link;
EFI_STATUS Status;
- if ((Protocol == NULL) || (Function == NULL) || (Registration == NULL)) {
+ if (Protocol == NULL || Registration == NULL) {
return EFI_INVALID_PARAMETER;
}
+ if (Function == NULL) {
+ //
+ // Get the protocol entry per Protocol
+ //
+ ProtEntry = SmmFindProtocolEntry ((EFI_GUID *) Protocol, FALSE);
+ if (ProtEntry != NULL) {
+ ProtNotify = (PROTOCOL_NOTIFY * )*Registration;
+ for (Link = ProtEntry->Notify.ForwardLink;
+ Link != &ProtEntry->Notify;
+ Link = Link->ForwardLink) {
+ //
+ // Compare the notification record
+ //
+ if (ProtNotify == (CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE))){
+ //
+ // If Registration is an existing registration, then unhook it
+ //
+ ProtNotify->Signature = 0;
+ RemoveEntryList (&ProtNotify->Link);
+ FreePool (ProtNotify);
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ //
+ // If the registration is not found
+ //
+ return EFI_NOT_FOUND;
+ }
+
ProtNotify = NULL;
//
diff --git a/MdeModulePkg/Include/Guid/PcdDataBaseSignatureGuid.h b/MdeModulePkg/Include/Guid/PcdDataBaseSignatureGuid.h
new file mode 100644
index 000000000..22c0d95f6
--- /dev/null
+++ b/MdeModulePkg/Include/Guid/PcdDataBaseSignatureGuid.h
@@ -0,0 +1,147 @@
+/** @file
+ Guid for Pcd DataBase Signature.
+
+Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that 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 _PCD_DATABASE_SIGNATURE_GUID_H_
+#define _PCD_DATABASE_SIGNATURE_GUID_H_
+
+#define PCD_DATA_BASE_SIGNATURE_GUID \
+{ 0x3c7d193c, 0x682c, 0x4c14, { 0xa6, 0x8f, 0x55, 0x2d, 0xea, 0x4f, 0x43, 0x7e } }
+
+extern EFI_GUID gPcdDataBaseSignatureGuid;
+
+//
+// Common definitions
+//
+typedef UINT8 SKU_ID;
+
+#define PCD_TYPE_SHIFT 28
+
+#define PCD_TYPE_DATA (0x0U << PCD_TYPE_SHIFT)
+#define PCD_TYPE_HII (0x8U << PCD_TYPE_SHIFT)
+#define PCD_TYPE_VPD (0x4U << PCD_TYPE_SHIFT)
+#define PCD_TYPE_SKU_ENABLED (0x2U << PCD_TYPE_SHIFT)
+#define PCD_TYPE_STRING (0x1U << PCD_TYPE_SHIFT)
+
+#define PCD_TYPE_ALL_SET (PCD_TYPE_DATA | PCD_TYPE_HII | PCD_TYPE_VPD | PCD_TYPE_SKU_ENABLED | PCD_TYPE_STRING)
+
+#define PCD_DATUM_TYPE_SHIFT 24
+
+#define PCD_DATUM_TYPE_POINTER (0x0U << PCD_DATUM_TYPE_SHIFT)
+#define PCD_DATUM_TYPE_UINT8 (0x1U << PCD_DATUM_TYPE_SHIFT)
+#define PCD_DATUM_TYPE_UINT16 (0x2U << PCD_DATUM_TYPE_SHIFT)
+#define PCD_DATUM_TYPE_UINT32 (0x4U << PCD_DATUM_TYPE_SHIFT)
+#define PCD_DATUM_TYPE_UINT64 (0x8U << PCD_DATUM_TYPE_SHIFT)
+
+#define PCD_DATUM_TYPE_ALL_SET (PCD_DATUM_TYPE_POINTER | \
+ PCD_DATUM_TYPE_UINT8 | \
+ PCD_DATUM_TYPE_UINT16 | \
+ PCD_DATUM_TYPE_UINT32 | \
+ PCD_DATUM_TYPE_UINT64)
+
+#define PCD_DATUM_TYPE_SHIFT2 20
+
+#define PCD_DATUM_TYPE_UINT8_BOOLEAN (0x1U << PCD_DATUM_TYPE_SHIFT2)
+
+#define PCD_DATABASE_OFFSET_MASK (~(PCD_TYPE_ALL_SET | PCD_DATUM_TYPE_ALL_SET | PCD_DATUM_TYPE_UINT8_BOOLEAN))
+
+typedef struct {
+ UINT32 ExTokenNumber;
+ UINT16 TokenNumber; // Token Number for Dynamic-Ex PCD.
+ UINT16 ExGuidIndex; // Index of GuidTable in units of GUID.
+} DYNAMICEX_MAPPING;
+
+typedef struct {
+ UINT32 SkuDataStartOffset; // Offset(with TYPE info) from the PCD_DB.
+ UINT32 SkuIdTableOffset; // Offset from the PCD_DB.
+} SKU_HEAD;
+
+typedef struct {
+ UINT32 StringIndex; // Offset in String Table in units of UINT8.
+ UINT32 DefaultValueOffset; // Offset of the Default Value.
+ UINT16 GuidTableIndex; // Offset in Guid Table in units of GUID.
+ UINT16 Offset; // Offset in Variable.
+} VARIABLE_HEAD;
+
+typedef struct {
+ UINT32 Offset;
+} VPD_HEAD;
+
+typedef UINT32 STRING_HEAD;
+
+typedef UINT16 SIZE_INFO;
+
+typedef struct {
+ UINT32 TokenSpaceCNameIndex; // Offset in String Table in units of UINT8.
+ UINT32 PcdCNameIndex; // Offset in String Table in units of UINT8.
+} PCD_NAME_INDEX;
+
+typedef UINT32 TABLE_OFFSET;
+
+typedef struct {
+ GUID Signature; // PcdDataBaseGuid.
+ UINT32 BuildVersion;
+ UINT32 Length;
+ UINT32 UninitDataBaseSize; // Total size for PCD those default value with 0.
+ TABLE_OFFSET LocalTokenNumberTableOffset;
+ TABLE_OFFSET ExMapTableOffset;
+ TABLE_OFFSET GuidTableOffset;
+ TABLE_OFFSET StringTableOffset;
+ TABLE_OFFSET SizeTableOffset;
+ TABLE_OFFSET SkuIdTableOffset;
+ TABLE_OFFSET PcdNameTableOffset;
+ UINT16 LocalTokenCount; // LOCAL_TOKEN_NUMBER for all.
+ UINT16 ExTokenCount; // EX_TOKEN_NUMBER for DynamicEx.
+ UINT16 GuidTableCount; // The Number of Guid in GuidTable.
+ SKU_ID SystemSkuId; // Current SkuId value.
+ UINT8 Pad; // Pad bytes to satisfy the alignment.
+
+ //
+ // Default initialized external PCD database binary structure
+ //
+ // Padding is needed to keep necessary alignment
+ //
+ //UINT64 ValueUint64[];
+ //UINT32 ValueUint32[];
+ //VPD_HEAD VpdHead[]; // VPD Offset
+ //DYNAMICEX_MAPPING ExMapTable[]; // DynamicEx PCD mapped to LocalIndex in LocalTokenNumberTable. It can be accessed by the ExMapTableOffset.
+ //UINT32 LocalTokenNumberTable[]; // Offset | DataType | PCD Type. It can be accessed by LocalTokenNumberTableOffset.
+ //GUID GuidTable[]; // GUID for DynamicEx and HII PCD variable Guid. It can be accessed by the GuidTableOffset.
+ //STRING_HEAD StringHead[]; // String PCD
+ //PCD_NAME_INDEX PcdNameTable[]; // PCD name index info. It can be accessed by the PcdNameTableOffset.
+ //VARIABLE_HEAD VariableHead[]; // HII PCD
+ //SKU_HEAD SkuHead[]; // Store SKU info for each PCD with SKU enable.
+ //UINT8 StringTable[]; // String for String PCD value and HII PCD Variable Name. It can be accessed by StringTableOffset.
+ //SIZE_INFO SizeTable[]; // MaxSize and CurSize for String PCD. It can be accessed by SizeTableOffset.
+ //UINT16 ValueUint16[];
+ //UINT8 ValueUint8[];
+ //BOOLEAN ValueBoolean[];
+ //UINT8 SkuIdTable[]; // SkuIds system supports.
+ //UINT8 SkuIndexTable[]; // SkuIds for each PCD with SKU enable.
+
+} PCD_DATABASE_INIT;
+
+//
+// PEI and DXE Pcd driver use the same PCD database
+//
+typedef PCD_DATABASE_INIT PEI_PCD_DATABASE;
+typedef PCD_DATABASE_INIT DXE_PCD_DATABASE;
+
+
+typedef struct {
+ PEI_PCD_DATABASE *PeiDb;
+ DXE_PCD_DATABASE *DxeDb;
+} PCD_DATABASE;
+
+
+#endif
diff --git a/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h b/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h
index 6be32b232..16384f831 100644
--- a/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h
+++ b/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h
@@ -1,7 +1,8 @@
/** @file
- CPU Exception library provides the CPU exception handler.
+ CPU Exception library provides the default CPU interrupt/exception handler.
+ It also provides capability to register user interrupt/exception handler.
- Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -12,17 +13,84 @@
**/
-#ifndef __CPU_EXCEPTION_LIB_H__
-#define __CPU_EXCEPTION_LIB_H__
+#ifndef __CPU_EXCEPTION_HANDLER_LIB_H__
+#define __CPU_EXCEPTION_HANDLER_LIB_H__
+
+#include <Ppi/VectorHandoffInfo.h>
+#include <Protocol/Cpu.h>
/**
- Setup CPU exception handlers.
-
+ Initializes all CPU exceptions entries and provides the default exception handlers.
+
+ Caller should try to get an array of interrupt and/or exception vectors that are in use and need to
+ persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.
+ If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL.
+ If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.
+
+ @param[in] VectorInfo Pointer to reserved vector list.
+
+ @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized
+ with default exception handlers.
+ @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
+ @retval EFI_UNSUPPORTED This function is not supported.
+
**/
-VOID
+EFI_STATUS
+EFIAPI
+InitializeCpuExceptionHandlers (
+ IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
+ );
+
+/**
+ Initializes all CPU interrupt/exceptions entries and provides the default interrupt/exception handlers.
+
+ Caller should try to get an array of interrupt and/or exception vectors that are in use and need to
+ persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.
+ If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL.
+ If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.
+
+ @param[in] VectorInfo Pointer to reserved vector list.
+
+ @retval EFI_SUCCESS All CPU interrupt/exception entries have been successfully initialized
+ with default interrupt/exception handlers.
+ @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
+ @retval EFI_UNSUPPORTED This function is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeCpuInterruptHandlers (
+ IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
+ );
+
+/**
+ Registers a function to be called from the processor interrupt handler.
+
+ This function registers and enables the handler specified by InterruptHandler for a processor
+ interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
+ handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
+ The installed handler is called once for each processor interrupt or exception.
+ NOTE: This function should be invoked after InitializeCpuExceptionHandlers() or
+ InitializeCpuInterruptHandlers() invoked, otherwise EFI_UNSUPPORTED returned.
+
+ @param[in] InterruptType Defines which interrupt or exception to hook.
+ @param[in] InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
+ when a processor interrupt occurs. If this parameter is NULL, then the handler
+ will be uninstalled.
+
+ @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
+ @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
+ previously installed.
+ @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
+ previously installed.
+ @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported,
+ or this function is not supported.
+*/
+EFI_STATUS
EFIAPI
-SetupCpuExceptionHandlers (
- VOID
+RegisterCpuInterruptHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
);
#endif
diff --git a/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.c b/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.c
index 3dd9da8b8..ded14a335 100644
--- a/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.c
+++ b/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.c
@@ -1,7 +1,7 @@
/** @file
CPU Exception Handler library implementition with empty functions.
- Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -11,17 +11,89 @@
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
+#include <PiPei.h>
+#include <Library/CpuExceptionHandlerLib.h>
+/**
+ Initializes all CPU exceptions entries and provides the default exception handlers.
+
+ Caller should try to get an array of interrupt and/or exception vectors that are in use and need to
+ persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.
+ If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL.
+ If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.
+
+ @param[in] VectorInfo Pointer to reserved vector list.
+
+ @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized
+ with default exception handlers.
+ @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
+ @retval EFI_UNSUPPORTED This function is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeCpuExceptionHandlers (
+ IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
+ )
+{
+ return EFI_SUCCESS;
+}
/**
- Setup CPU exception handlers.
-
+ Initializes all CPU interrupt/exceptions entries and provides the default interrupt/exception handlers.
+
+ Caller should try to get an array of interrupt and/or exception vectors that are in use and need to
+ persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.
+ If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL.
+ If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.
+
+ @param[in] VectorInfo Pointer to reserved vector list.
+
+ @retval EFI_SUCCESS All CPU interrupt/exception entries have been successfully initialized
+ with default interrupt/exception handlers.
+ @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
+ @retval EFI_UNSUPPORTED This function is not supported.
+
**/
-VOID
+EFI_STATUS
+EFIAPI
+InitializeCpuInterruptHandlers (
+ IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ Registers a function to be called from the processor interrupt handler.
+
+ This function registers and enables the handler specified by InterruptHandler for a processor
+ interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
+ handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
+ The installed handler is called once for each processor interrupt or exception.
+ NOTE: This function should be invoked after InitializeCpuExceptionHandlers() or
+ InitializeCpuInterruptHandlers() invoked, otherwise EFI_UNSUPPORTED returned.
+
+ @param[in] InterruptType Defines which interrupt or exception to hook.
+ @param[in] InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
+ when a processor interrupt occurs. If this parameter is NULL, then the handler
+ will be uninstalled.
+
+ @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
+ @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
+ previously installed.
+ @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
+ previously installed.
+ @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported,
+ or this function is not supported.
+*/
+EFI_STATUS
EFIAPI
-SetupCpuExceptionHandlers (
- VOID
+RegisterCpuInterruptHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
)
-{
+{
+ return EFI_SUCCESS;
}
diff --git a/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf b/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
index 47e55feee..0ec02ac41 100644
--- a/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
+++ b/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
@@ -1,7 +1,7 @@
## @file
# Null instance of CPU Exception Handler Library with empty functions.
#
-# Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
@@ -16,7 +16,7 @@
INF_VERSION = 0x00010005
BASE_NAME = CpuExceptionHandlerLibNull
FILE_GUID = 3175E6B9-4B01-496a-9A2B-64AF02D87E34
- MODULE_TYPE = BASE
+ MODULE_TYPE = PEIM
VERSION_STRING = 1.0
LIBRARY_CLASS = CpuExceptionHandlerLib
diff --git a/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c b/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c
index cfda3962b..467b82280 100644
--- a/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c
+++ b/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c
@@ -2250,7 +2250,7 @@ NetLibGetMacAddress (
// Try to get SNP mode from MNP
//
Status = Mnp->GetModeData (Mnp, NULL, &SnpModeData);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {
MnpSb->DestroyChild (MnpSb, MnpChildHandle);
return Status;
}
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index fc9f9ccd9..b627eb101 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -111,6 +111,10 @@
# Include/Guid/PcdDataBaseHobGuid.h
gPcdDataBaseHobGuid = { 0xEA296D92, 0x0B69, 0x423C, { 0x8C, 0x28, 0x33, 0xB4, 0xE0, 0xA9, 0x12, 0x68 }}
+ ## Guid for PCD DataBase signature.
+ # Include/Guid/PcdDataBaseSignatureGuid.h
+ gPcdDataBaseSignatureGuid = { 0x3c7d193c, 0x682c, 0x4c14, { 0xa6, 0x8f, 0x55, 0x2d, 0xea, 0x4f, 0x43, 0x7e }}
+
## Guid for EDKII implementation GUIDed opcodes
# Include/Guid/MdeModuleHii.h
gEfiIfrTianoGuid = { 0xf0b1735, 0x87a0, 0x4193, {0xb2, 0x66, 0x53, 0x8c, 0x38, 0xaf, 0x48, 0xce }}
diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
index 04d4893a9..4777f9d2e 100644
--- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
+++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
@@ -4,7 +4,7 @@
# This is a standalone Boot Script Executor. Standalone means it does not
# depends on any PEI or DXE service.
#
-# Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials are
# licensed and made available under the terms and conditions of the BSD License
@@ -75,6 +75,9 @@
gPerformanceProtocolGuid
gEfiEventExitBootServicesGuid
+[Protocols]
+ gEfiDxeSmmReadyToLockProtocolGuid
+
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode
diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/IA32/SetIdtEntry.c b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/IA32/SetIdtEntry.c
index 04eba0d75..63b06ba5d 100644
--- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/IA32/SetIdtEntry.c
+++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/IA32/SetIdtEntry.c
@@ -3,7 +3,7 @@
Set a IDT entry for interrupt vector 3 for debug purpose for IA32 platform
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -30,6 +30,7 @@ SetIdtEntry (
IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
IA32_DESCRIPTOR *IdtDescriptor;
UINTN S3DebugBuffer;
+ EFI_STATUS Status;
//
// Restore IDT for debug
@@ -40,7 +41,8 @@ SetIdtEntry (
//
// Setup the default CPU exception handlers
//
- SetupCpuExceptionHandlers ();
+ Status = InitializeCpuExceptionHandlers (NULL);
+ ASSERT_EFI_ERROR (Status);
DEBUG_CODE (
//
diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c
index c5eec24e0..651a9dea5 100644
--- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c
+++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c
@@ -1,10 +1,10 @@
/** @file
This is the code for Boot Script Executer module.
- This driver is dispatched by Dxe core and the driver will reload itself to ACPI NVS memory
+ This driver is dispatched by Dxe core and the driver will reload itself to ACPI reserved memory
in the entry point. The functionality is to interpret and restore the S3 boot script
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -22,6 +22,8 @@ EFI_GUID mBootScriptExecutorImageGuid = {
0x9a8d3433, 0x9fe8, 0x42b6, { 0x87, 0xb, 0x1e, 0x31, 0xc8, 0x4e, 0xbe, 0x3b }
};
+BOOLEAN mPage1GSupport = FALSE;
+
/**
Entry function of Boot script exector. This function will be executed in
S3 boot path.
@@ -68,6 +70,16 @@ S3BootScriptExecutorEntryFunction (
// for that parameter.
//
Status = S3BootScriptExecute ();
+
+ //
+ // If invalid script table or opcode in S3 boot script table.
+ //
+ ASSERT_EFI_ERROR (Status);
+
+ if (EFI_ERROR (Status)) {
+ CpuDeadLoop ();
+ return Status;
+ }
AsmWbinvd ();
@@ -195,6 +207,121 @@ S3BootScriptExecutorEntryFunction (
CpuDeadLoop();
return EFI_UNSUPPORTED;
}
+
+/**
+ This is the Event notification function to reload BootScriptExecutor image
+ to RESERVED mem and save it to LockBox.
+
+ @param Event Pointer to this event
+ @param Context Event hanlder private data
+ **/
+VOID
+EFIAPI
+ReadyToLockEventNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ VOID *Interface;
+ UINT8 *Buffer;
+ UINTN BufferSize;
+ EFI_HANDLE NewImageHandle;
+ UINTN Pages;
+ EFI_PHYSICAL_ADDRESS FfsBuffer;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+
+ Status = gBS->LocateProtocol (&gEfiDxeSmmReadyToLockProtocolGuid, NULL, &Interface);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ //
+ // A workaround: Here we install a dummy handle
+ //
+ NewImageHandle = NULL;
+ Status = gBS->InstallProtocolInterface (
+ &NewImageHandle,
+ &gEfiCallerIdGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Reload BootScriptExecutor image itself to RESERVED mem
+ //
+ Status = GetSectionFromAnyFv (
+ &gEfiCallerIdGuid,
+ EFI_SECTION_PE32,
+ 0,
+ (VOID **) &Buffer,
+ &BufferSize
+ );
+ ASSERT_EFI_ERROR (Status);
+ ImageContext.Handle = Buffer;
+ ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
+ //
+ // Get information about the image being loaded
+ //
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);
+ ASSERT_EFI_ERROR (Status);
+ Pages = EFI_SIZE_TO_PAGES(BufferSize + ImageContext.SectionAlignment);
+ FfsBuffer = 0xFFFFFFFF;
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiReservedMemoryType,
+ Pages,
+ &FfsBuffer
+ );
+ ASSERT_EFI_ERROR (Status);
+ ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer;
+ //
+ // Align buffer on section boundry
+ //
+ ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
+ ImageContext.ImageAddress &= ~(ImageContext.SectionAlignment - 1);
+ //
+ // Load the image to our new buffer
+ //
+ Status = PeCoffLoaderLoadImage (&ImageContext);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Relocate the image in our new buffer
+ //
+ Status = PeCoffLoaderRelocateImage (&ImageContext);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Free the buffer allocated by ReadSection since the image has been relocated in the new buffer
+ //
+ gBS->FreePool (Buffer);
+
+ //
+ // Flush the instruction cache so the image data is written before we execute it
+ //
+ InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
+ Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint)) (NewImageHandle, gST);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Additional step for BootScript integrity
+ // Save BootScriptExecutor image
+ //
+ Status = SaveLockBox (
+ &mBootScriptExecutorImageGuid,
+ (VOID *)(UINTN)ImageContext.ImageAddress,
+ (UINTN)ImageContext.ImageSize
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = SetLockBoxAttributes (&mBootScriptExecutorImageGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
+ ASSERT_EFI_ERROR (Status);
+
+ gBS->CloseEvent (Event);
+}
+
/**
Entrypoint of Boot script exector driver, this function will be executed in
normal boot phase and invoked by DXE dispatch.
@@ -212,16 +339,16 @@ BootScriptExecutorEntryPoint (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
- UINT8 *Buffer;
UINTN BufferSize;
UINTN Pages;
- EFI_PHYSICAL_ADDRESS FfsBuffer;
- PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
BOOT_SCRIPT_EXECUTOR_VARIABLE *EfiBootScriptExecutorVariable;
EFI_PHYSICAL_ADDRESS BootScriptExecutorBuffer;
EFI_STATUS Status;
VOID *DevicePath;
- EFI_HANDLE NewImageHandle;
+ EFI_EVENT ReadyToLockEvent;
+ VOID *Registration;
+ UINT32 RegEax;
+ UINT32 RegEdx;
//
// Test if the gEfiCallerIdGuid of this image is already installed. if not, the entry
@@ -230,94 +357,32 @@ BootScriptExecutorEntryPoint (
//
Status = gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, &DevicePath);
if (EFI_ERROR (Status)) {
-
- //
- // This is the first-time loaded by DXE core. reload itself to RESERVED mem
- //
- //
- // A workaround: Here we install a dummy handle
- //
- NewImageHandle = NULL;
- Status = gBS->InstallProtocolInterface (
- &NewImageHandle,
- &gEfiCallerIdGuid,
- EFI_NATIVE_INTERFACE,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
-
- Status = GetSectionFromAnyFv (
- &gEfiCallerIdGuid,
- EFI_SECTION_PE32,
- 0,
- (VOID **) &Buffer,
- &BufferSize
- );
- ASSERT_EFI_ERROR (Status);
- ImageContext.Handle = Buffer;
- ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
- //
- // Get information about the image being loaded
- //
- Status = PeCoffLoaderGetImageInfo (&ImageContext);
- ASSERT_EFI_ERROR (Status);
- Pages = EFI_SIZE_TO_PAGES(BufferSize + ImageContext.SectionAlignment);
- FfsBuffer = 0xFFFFFFFF;
- Status = gBS->AllocatePages (
- AllocateMaxAddress,
- EfiReservedMemoryType,
- Pages,
- &FfsBuffer
- );
- ASSERT_EFI_ERROR (Status);
- ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer;
- //
- // Align buffer on section boundry
- //
- ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
- ImageContext.ImageAddress &= ~(ImageContext.SectionAlignment - 1);
//
- // Load the image to our new buffer
+ // Create ReadyToLock event to reload BootScriptExecutor image
+ // to RESERVED mem and save it to LockBox.
//
- Status = PeCoffLoaderLoadImage (&ImageContext);
- ASSERT_EFI_ERROR (Status);
-
- //
- // Relocate the image in our new buffer
- //
- Status = PeCoffLoaderRelocateImage (&ImageContext);
- ASSERT_EFI_ERROR (Status);
-
- //
- // Free the buffer allocated by ReadSection since the image has been relocated in the new buffer
- //
- gBS->FreePool (Buffer);
-
- //
- // Flush the instruction cache so the image data is written before we execute it
- //
- InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
- Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint)) (NewImageHandle, SystemTable);
- ASSERT_EFI_ERROR (Status);
-
- //
- // Additional step for BootScript integrity
- // Save BootScriptExecutor image
- //
- Status = SaveLockBox (
- &mBootScriptExecutorImageGuid,
- (VOID *)(UINTN)ImageContext.ImageAddress,
- (UINTN)ImageContext.ImageSize
- );
- ASSERT_EFI_ERROR (Status);
-
- Status = SetLockBoxAttributes (&mBootScriptExecutorImageGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
- ASSERT_EFI_ERROR (Status);
-
+ ReadyToLockEvent = EfiCreateProtocolNotifyEvent (
+ &gEfiDxeSmmReadyToLockProtocolGuid,
+ TPL_NOTIFY,
+ ReadyToLockEventNotify,
+ NULL,
+ &Registration
+ );
+ ASSERT (ReadyToLockEvent != NULL);
} else {
//
// the entry point is invoked after reloading. following code only run in RESERVED mem
//
+ if (PcdGetBool(PcdUse1GPageTable)) {
+ AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= 0x80000001) {
+ AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
+ if ((RegEdx & BIT26) != 0) {
+ mPage1GSupport = TRUE;
+ }
+ }
+ }
+
BufferSize = sizeof (BOOT_SCRIPT_EXECUTOR_VARIABLE);
BootScriptExecutorBuffer = 0xFFFFFFFF;
@@ -353,11 +418,8 @@ BootScriptExecutorEntryPoint (
Status = SetLockBoxAttributes (&gEfiBootScriptExecutorContextGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
ASSERT_EFI_ERROR (Status);
-
}
return EFI_SUCCESS;
}
-
-
diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.h b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.h
index 707ab8ca6..a3522905a 100644
--- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.h
+++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.h
@@ -1,10 +1,10 @@
/** @file
The header file for Boot Script Executer module.
- This driver is dispatched by Dxe core and the driver will reload itself to ACPI NVS memory
+ This driver is dispatched by Dxe core and the driver will reload itself to ACPI reserved memory
in the entry point. The functionality is to interpret and restore the S3 boot script
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -39,7 +39,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Guid/AcpiS3Context.h>
#include <Guid/BootScriptExecutorVariable.h>
-#include <Guid/EventGroup.h>
+#include <Protocol/DxeSmmReadyToLock.h>
#include <IndustryStandard/Acpi.h>
/**
a ASM function to transfer control to OS.
@@ -83,5 +83,6 @@ SetIdtEntry (
extern UINT32 AsmFixAddress16;
extern UINT32 AsmJmpAddr32;
+extern BOOLEAN mPage1GSupport;
#endif //_BOOT_SCRIPT_EXECUTOR_H_
diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/SetIdtEntry.c b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/SetIdtEntry.c
index a8944e600..e42e6d4fe 100644
--- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/SetIdtEntry.c
+++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/SetIdtEntry.c
@@ -21,7 +21,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define IA32_PG_PS BIT7
UINT64 mPhyMask;
-BOOLEAN mPage1GSupport;
VOID *mOriginalHandler;
UINTN mS3NvsPageTableAddress;
@@ -47,23 +46,18 @@ HookPageFaultHandler (
)
{
UINT32 RegEax;
- UINT32 RegEdx;
+ UINT8 PhysicalAddressBits;
UINTN PageFaultHandlerHookAddress;
- AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
- mPhyMask = LShiftU64 (1, (UINT8)RegEax) - 1;
- mPhyMask &= (1ull << 48) - SIZE_4KB;
-
- mPage1GSupport = FALSE;
- if (PcdGetBool(PcdUse1GPageTable)) {
- AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
- if (RegEax >= 0x80000001) {
- AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
- if ((RegEdx & BIT26) != 0) {
- mPage1GSupport = TRUE;
- }
- }
+ AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= 0x80000008) {
+ AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
+ PhysicalAddressBits = (UINT8) RegEax;
+ } else {
+ PhysicalAddressBits = 36;
}
+ mPhyMask = LShiftU64 (1, PhysicalAddressBits) - 1;
+ mPhyMask &= (1ull << 48) - SIZE_4KB;
//
// Set Page Fault entry to catch >4G access
@@ -99,6 +93,7 @@ SetIdtEntry (
IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
IA32_DESCRIPTOR *IdtDescriptor;
UINTN S3DebugBuffer;
+ EFI_STATUS Status;
//
// Restore IDT for debug
@@ -109,7 +104,8 @@ SetIdtEntry (
//
// Setup the default CPU exception handlers
//
- SetupCpuExceptionHandlers ();
+ Status = InitializeCpuExceptionHandlers (NULL);
+ ASSERT_EFI_ERROR (Status);
DEBUG_CODE (
//
diff --git a/MdeModulePkg/Universal/CapsulePei/X64/X64Entry.c b/MdeModulePkg/Universal/CapsulePei/X64/X64Entry.c
index 56913e6b0..88cfc8fe9 100644
--- a/MdeModulePkg/Universal/CapsulePei/X64/X64Entry.c
+++ b/MdeModulePkg/Universal/CapsulePei/X64/X64Entry.c
@@ -1,7 +1,7 @@
/** @file
The X64 entrypoint is used to process capsule in long mode.
-Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -58,7 +58,8 @@ _ModuleEntryPoint (
//
// Setup the default CPU exception handlers
//
- SetupCpuExceptionHandlers ();
+ Status = InitializeCpuExceptionHandlers (NULL);
+ ASSERT_EFI_ERROR (Status);
//
// Initialize Debug Agent to support source level debug
diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c
index 9f6c96315..dbc5685b0 100644
--- a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c
+++ b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c
@@ -853,6 +853,54 @@ UpdateOptionSkipLines (
}
/**
+ Check whether this Menu Option could be print.
+
+ Check Prompt string, option string or text two string not NULL.
+
+ This is an internal function.
+
+ @param MenuOption The MenuOption to be checked.
+
+ @retval TRUE This Menu Option is printable.
+ @retval FALSE This Menu Option could not be printable.
+
+**/
+BOOLEAN
+PrintableMenu (
+ UI_MENU_OPTION *MenuOption
+ )
+{
+ EFI_STATUS Status;
+ EFI_STRING OptionString;
+
+ OptionString = NULL;
+
+ if (MenuOption->Description[0] != '\0') {
+ return TRUE;
+ }
+
+ Status = ProcessOptions (MenuOption, FALSE, &OptionString, FALSE);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ if (OptionString != NULL && OptionString[0] != '\0') {
+ FreePool (OptionString);
+ return TRUE;
+ }
+
+ if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TEXT_OP) && (((EFI_IFR_TEXT*)MenuOption->ThisTag->OpCode)->TextTwo != 0)) {
+ OptionString = GetToken (((EFI_IFR_TEXT*)MenuOption->ThisTag->OpCode)->TextTwo, gFormData->HiiHandle);
+ ASSERT (OptionString != NULL);
+ if (OptionString[0] != '\0'){
+ FreePool (OptionString);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
Check whether this Menu Option could be highlighted.
This is an internal function.
@@ -869,7 +917,7 @@ IsSelectable (
)
{
if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) ||
- MenuOption->GrayOut || MenuOption->ReadOnly) {
+ MenuOption->GrayOut || MenuOption->ReadOnly || !PrintableMenu (MenuOption)) {
return FALSE;
} else {
return TRUE;
@@ -884,19 +932,24 @@ IsSelectable (
@param GoUp The navigation direction. TRUE: up, FALSE: down.
@param CurrentPosition Current position.
@param GapToTop Gap position to top or bottom.
+ @param FindInForm Whether find menu in current form or beyond.
@return The row distance from current MenuOption to next selectable MenuOption.
@retval -1 Reach the begin of the menu, still can't find the selectable menu.
- @retval Value Find the selectable menu, maybe the truly selectable, maybe the l
- last menu showing at current form.
+ @retval Value Find the selectable menu, maybe the truly selectable, maybe the
+ first menu showing beyond current form or last menu showing in
+ current form.
+ The value is the line number between the new selected menu and the
+ current select menu, not include the new selected menu.
**/
INTN
MoveToNextStatement (
IN BOOLEAN GoUp,
IN OUT LIST_ENTRY **CurrentPosition,
- IN UINTN GapToTop
+ IN UINTN GapToTop,
+ IN BOOLEAN FindInForm
)
{
INTN Distance;
@@ -906,6 +959,11 @@ MoveToNextStatement (
Distance = 0;
Pos = *CurrentPosition;
+
+ if (Pos == &gMenuOption) {
+ return -1;
+ }
+
PreMenuOption = MENU_OPTION_FROM_LINK (Pos);
while (TRUE) {
@@ -917,28 +975,24 @@ MoveToNextStatement (
if (NextMenuOption->Row == 0) {
UpdateOptionSkipLines (NextMenuOption);
}
-
- if (GoUp && (PreMenuOption != NextMenuOption)) {
- //
- // In this case, still can't find the selectable menu,
- // return the last one in the showing form.
- //
- if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {
- NextMenuOption = PreMenuOption;
- break;
- }
- //
- // Current Position doesn't need to be caculated when go up.
- // Caculate distanct at first when go up
- //
- Distance += NextMenuOption->Skip;
+ if (IsSelectable (NextMenuOption)) {
+ break;
}
- if (IsSelectable (NextMenuOption)) {
+ //
+ // In this case, still can't find the selectable menu,
+ // return the first one beyond the showing form.
+ //
+ if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {
+ if (FindInForm) {
+ NextMenuOption = PreMenuOption;
+ }
break;
}
+ Distance += NextMenuOption->Skip;
+
//
// Arrive at begin of the menu list.
//
@@ -947,21 +1001,8 @@ MoveToNextStatement (
break;
}
- if (!GoUp) {
- //
- // In this case, still can't find the selectable menu,
- // return the last one in the showing form.
- //
- if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {
- NextMenuOption = PreMenuOption;
- break;
- }
-
- Distance += NextMenuOption->Skip;
- }
-
- PreMenuOption = NextMenuOption;
Pos = (GoUp ? Pos->BackLink : Pos->ForwardLink);
+ PreMenuOption = NextMenuOption;
}
*CurrentPosition = &NextMenuOption->Link;
@@ -1355,6 +1396,58 @@ GetQuestionIdInfo (
return QuestionHeader->QuestionId;
}
+
+/**
+ Find the top of screen menu base on the current menu.
+
+ @param CurPos Current input menu.
+ @param Rows Totol screen rows.
+ @param SkipValue SkipValue for this new form.
+
+ @retval TopOfScreen Top of screen menu for the new form.
+
+**/
+LIST_ENTRY *
+FindTopOfScreenMenu (
+ IN LIST_ENTRY *CurPos,
+ IN UINTN Rows,
+ OUT UINTN *SkipValue
+ )
+{
+ LIST_ENTRY *Link;
+ LIST_ENTRY *TopOfScreen;
+ UI_MENU_OPTION *PreviousMenuOption;
+
+ Link = CurPos;
+ PreviousMenuOption = NULL;
+
+ while (Link->BackLink != &gMenuOption) {
+ Link = Link->BackLink;
+ PreviousMenuOption = MENU_OPTION_FROM_LINK (Link);
+ if (PreviousMenuOption->Row == 0) {
+ UpdateOptionSkipLines (PreviousMenuOption);
+ }
+ if (Rows <= PreviousMenuOption->Skip) {
+ break;
+ }
+ Rows = Rows - PreviousMenuOption->Skip;
+ }
+
+ if (Link->BackLink == &gMenuOption) {
+ TopOfScreen = gMenuOption.ForwardLink;
+ if (PreviousMenuOption != NULL && Rows < PreviousMenuOption->Skip) {
+ *SkipValue = PreviousMenuOption->Skip - Rows;
+ } else {
+ *SkipValue = 0;
+ }
+ } else {
+ TopOfScreen = Link;
+ *SkipValue = PreviousMenuOption->Skip - Rows;
+ }
+
+ return TopOfScreen;
+}
+
/**
Find the first menu which will be show at the top.
@@ -1369,16 +1462,14 @@ FindTopMenu (
IN FORM_DISPLAY_ENGINE_FORM *FormData,
OUT LIST_ENTRY **TopOfScreen,
OUT LIST_ENTRY **HighlightMenu,
- OUT INTN *SkipValue
+ OUT UINTN *SkipValue
)
{
- LIST_ENTRY *Link;
LIST_ENTRY *NewPos;
UINTN TopRow;
UINTN BottomRow;
- UINTN Index;
UI_MENU_OPTION *SavedMenuOption;
- UINTN EndRow;
+ UINTN TmpValue;
TopRow = gStatementDimensions.TopRow + SCROLL_ARROW_HEIGHT;
BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT;
@@ -1390,7 +1481,7 @@ FindTopMenu (
*TopOfScreen = gMenuOption.ForwardLink;
*HighlightMenu = gMenuOption.ForwardLink;
if (!IsListEmpty (&gMenuOption)) {
- MoveToNextStatement (FALSE, HighlightMenu, BottomRow - TopRow);
+ MoveToNextStatement (FALSE, HighlightMenu, BottomRow - TopRow, TRUE);
}
*SkipValue = 0;
return;
@@ -1431,53 +1522,17 @@ FindTopMenu (
//
// Still show the highlight menu before exit from display engine.
//
- EndRow = gHighligthMenuInfo.DisplayRow + SavedMenuOption->Skip;
- } else {
- EndRow = BottomRow;
- }
-
- //
- // Base on the selected menu will show at the bottome of next page,
- // select the menu show at the top of the next page.
- //
- Link = NewPos;
- for (Index = TopRow + SavedMenuOption->Skip; Index <= EndRow; ) {
- Link = Link->BackLink;
- //
- // Already find the first menu in this form, means highlight menu
- // will show in first page of this form.
- //
- if (Link == &gMenuOption) {
- *TopOfScreen = gMenuOption.ForwardLink;
- *SkipValue = 0;
- return;
- }
- SavedMenuOption = MENU_OPTION_FROM_LINK (Link);
- UpdateOptionSkipLines (SavedMenuOption);
- Index += SavedMenuOption->Skip;
+ BottomRow = gHighligthMenuInfo.DisplayRow + SavedMenuOption->Skip;
}
- //
- // Found the menu which will show at the top of the page.
- //
- if (Link == NewPos) {
- //
- // The menu can show more than one pages, just show the menu at the top of the page.
- //
- *SkipValue = 0;
- *TopOfScreen = Link;
+ if (SavedMenuOption->Skip >= BottomRow - TopRow) {
+ TmpValue = 0;
+ *TopOfScreen = NewPos;
} else {
- //
- // Check whether need to skip some line for menu shows at the top of the page.
- //
- *SkipValue = Index - EndRow;
- if (*SkipValue > 0 && *SkipValue < (INTN) SavedMenuOption->Skip) {
- *TopOfScreen = Link;
- } else {
- *SkipValue = 0;
- *TopOfScreen = Link->ForwardLink;
- }
+ *TopOfScreen = FindTopOfScreenMenu(NewPos, BottomRow - TopRow - SavedMenuOption->Skip, &TmpValue);
}
+
+ *SkipValue = TmpValue;
}
/**
@@ -1855,6 +1910,12 @@ DisplayOneMenu (
if (StrLen (&StringPtr[Index]) != 0) {
if (Temp3 == 0) {
Row++;
+ //
+ // If the rows for text two is greater than or equal to the skip value, increase the skip value
+ //
+ if ((Row - MenuOption->Row) >= MenuOption->Skip) {
+ MenuOption->Skip++;
+ }
}
}
@@ -1901,7 +1962,7 @@ UiDisplayMenu (
IN FORM_DISPLAY_ENGINE_FORM *FormData
)
{
- INTN SkipValue;
+ UINTN SkipValue;
INTN Difference;
UINTN DistanceValue;
UINTN Row;
@@ -1910,7 +1971,6 @@ UiDisplayMenu (
UINTN Temp2;
UINTN TopRow;
UINTN BottomRow;
- UINTN OriginalRow;
UINTN Index;
UINT16 Width;
CHAR16 *StringPtr;
@@ -1945,7 +2005,6 @@ UiDisplayMenu (
UINTN HelpHeaderLine;
UINTN HelpBottomLine;
BOOLEAN MultiHelpPage;
- UINT16 GlyphWidth;
UINT16 EachLineWidth;
UINT16 HeaderLineWidth;
UINT16 BottomLineWidth;
@@ -2165,10 +2224,6 @@ UiDisplayMenu (
}
MenuOption = NULL;
-
- if (IsListEmpty (&gMenuOption)) {
- ControlFlag = CfReadKey;
- }
}
break;
@@ -2188,6 +2243,14 @@ UiDisplayMenu (
break;
}
+ if (IsListEmpty (&gMenuOption)) {
+ //
+ // No menu option, just update the hotkey filed.
+ //
+ RefreshKeyHelp(gFormData, NULL, FALSE);
+ break;
+ }
+
if (MenuOption != NULL && TopOfScreen == &MenuOption->Link) {
Temp = SkipValue;
} else {
@@ -2202,79 +2265,15 @@ UiDisplayMenu (
if (NewPos != NULL && (MenuOption == NULL || NewPos != &MenuOption->Link)) {
if (MenuOption != NULL) {
//
- // Remove highlight on last Menu Option
+ // Remove the old highlight menu.
//
- gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);
- ProcessOptions (MenuOption, FALSE, &OptionString, TRUE);
- gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
- if (OptionString != NULL) {
- if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP) ||
- (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)
- ) {
- ProcessStringForDateTime(MenuOption, OptionString, FALSE);
- }
-
- Width = (UINT16) gOptionBlockWidth - 1;
- OriginalRow = MenuOption->Row;
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow)) {
- PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&OptionString[Index]) != 0) {
- if (Temp == 0) {
- MenuOption->Row++;
- }
- }
-
- FreePool (OutputString);
- if (Temp != 0) {
- Temp--;
- }
- }
-
- MenuOption->Row = OriginalRow;
-
- FreePool (OptionString);
- } else {
- if (NewLine) {
- if (MenuOption->GrayOut) {
- gST->ConOut->SetAttribute (gST->ConOut, GetGrayedTextColor ());
- } else if (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) {
- gST->ConOut->SetAttribute (gST->ConOut, GetSubTitleTextColor ());
- }
-
- OriginalRow = MenuOption->Row;
- Width = GetWidth (MenuOption, NULL);
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow)) {
- PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&MenuOption->Description[Index]) != 0) {
- if (Temp == 0) {
- MenuOption->Row++;
- }
- }
-
- FreePool (OutputString);
- if (Temp != 0) {
- Temp--;
- }
- }
-
- MenuOption->Row = OriginalRow;
- gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
- }
- }
+ Status = DisplayOneMenu (MenuOption,
+ MenuOption->Col - gStatementDimensions.LeftColumn,
+ gStatementDimensions.LeftColumn,
+ Temp,
+ BottomRow,
+ FALSE
+ );
}
//
@@ -2289,79 +2288,13 @@ UiDisplayMenu (
break;
}
- //
- // Set reverse attribute
- //
- gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ());
- gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);
-
- ProcessOptions (MenuOption, FALSE, &OptionString, TRUE);
- if (OptionString != NULL) {
- if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
- ProcessStringForDateTime(MenuOption, OptionString, FALSE);
- }
- Width = (UINT16) gOptionBlockWidth - 1;
-
- OriginalRow = MenuOption->Row;
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp2 == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow) ) {
- PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&OptionString[Index]) != 0) {
- if (Temp2 == 0) {
- MenuOption->Row++;
- }
- }
-
- FreePool (OutputString);
- if (Temp2 != 0) {
- Temp2--;
- }
- }
-
- MenuOption->Row = OriginalRow;
-
- FreePool (OptionString);
- } else {
- if (NewLine) {
- OriginalRow = MenuOption->Row;
-
- Width = GetWidth (MenuOption, NULL);
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp2 == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow) ) {
- PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&MenuOption->Description[Index]) != 0) {
- if (Temp2 == 0) {
- MenuOption->Row++;
- }
- }
-
- FreePool (OutputString);
- if (Temp2 != 0) {
- Temp2--;
- }
- }
-
- MenuOption->Row = OriginalRow;
-
- }
- }
-
- //
- // Clear reverse attribute
- //
- gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
+ Status = DisplayOneMenu (MenuOption,
+ MenuOption->Col - gStatementDimensions.LeftColumn,
+ gStatementDimensions.LeftColumn,
+ Temp2,
+ BottomRow,
+ TRUE
+ );
}
break;
@@ -2371,16 +2304,27 @@ UiDisplayMenu (
break;
}
+ //
+ // NewLine means only update highlight menu (remove old highlight and highlith
+ // the new one), not need to full repain the form.
+ //
if (Repaint || NewLine) {
- //
- // Don't print anything if it is a NULL help token
- //
- ASSERT(MenuOption != NULL);
- HelpInfo = ((EFI_IFR_STATEMENT_HEADER *) ((CHAR8 *)MenuOption->ThisTag->OpCode + sizeof (EFI_IFR_OP_HEADER)))->Help;
- if (HelpInfo == 0 || !IsSelectable (MenuOption)) {
+ if (IsListEmpty (&gMenuOption)) {
+ //
+ // Don't print anything if no mwnu option.
+ //
StringPtr = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
} else {
- StringPtr = GetToken (HelpInfo, gFormData->HiiHandle);
+ //
+ // Don't print anything if it is a NULL help token
+ //
+ ASSERT(MenuOption != NULL);
+ HelpInfo = ((EFI_IFR_STATEMENT_HEADER *) ((CHAR8 *)MenuOption->ThisTag->OpCode + sizeof (EFI_IFR_OP_HEADER)))->Help;
+ if (HelpInfo == 0 || !IsSelectable (MenuOption)) {
+ StringPtr = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
+ } else {
+ StringPtr = GetToken (HelpInfo, gFormData->HiiHandle);
+ }
}
RowCount = BottomRow - TopRow + 1;
@@ -2706,9 +2650,9 @@ UiDisplayMenu (
break;
case CfScreenOperation:
- if (ScreenOperation != UiReset) {
+ if ((ScreenOperation != UiReset) && (ScreenOperation != UiHotKey)) {
//
- // If the screen has no menu items, and the user didn't select UiReset
+ // If the screen has no menu items, and the user didn't select UiReset or UiHotKey
// ignore the selection and go back to reading keys.
//
if (IsListEmpty (&gMenuOption)) {
@@ -2827,6 +2771,7 @@ UiDisplayMenu (
case CfUiUp:
ControlFlag = CfRepaint;
+ NewLine = TRUE;
SavedListEntry = NewPos;
@@ -2835,191 +2780,99 @@ UiDisplayMenu (
// Adjust Date/Time position before we advance forward.
//
AdjustDateAndTimePosition (TRUE, &NewPos);
- if (NewPos->BackLink != &gMenuOption) {
- MenuOption = MENU_OPTION_FROM_LINK (NewPos);
- ASSERT (MenuOption != NULL);
- NewLine = TRUE;
- NewPos = NewPos->BackLink;
- PreviousMenuOption = MENU_OPTION_FROM_LINK (NewPos);
- if (PreviousMenuOption->Row == 0) {
- UpdateOptionSkipLines (PreviousMenuOption);
- }
- DistanceValue = PreviousMenuOption->Skip;
- Difference = 0;
- if (MenuOption->Row >= DistanceValue + TopRow) {
- Difference = MoveToNextStatement (TRUE, &NewPos, MenuOption->Row - TopRow - DistanceValue);
- }
- NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
-
- if (Difference < 0) {
+ MenuOption = MENU_OPTION_FROM_LINK (NewPos);
+ ASSERT (MenuOption != NULL);
+
+ NewPos = NewPos->BackLink;
+ //
+ // Find next selectable menu or the first menu beyond current form.
+ //
+ Difference = MoveToNextStatement (TRUE, &NewPos, MenuOption->Row - TopRow, FALSE);
+ if (Difference < 0) {
+ //
+ // We hit the begining MenuOption that can be focused
+ // so we simply scroll to the top.
+ //
+ Repaint = TRUE;
+ if (TopOfScreen != gMenuOption.ForwardLink || SkipValue != 0) {
+ TopOfScreen = gMenuOption.ForwardLink;
+ NewPos = SavedListEntry;
+ SkipValue = 0;
+ } else {
//
- // We hit the begining MenuOption that can be focused
- // so we simply scroll to the top.
+ // Scroll up to the last page when we have arrived at top page.
//
- if (TopOfScreen != gMenuOption.ForwardLink) {
- TopOfScreen = gMenuOption.ForwardLink;
- Repaint = TRUE;
- } else {
- //
- // Scroll up to the last page when we have arrived at top page.
- //
- NewPos = &gMenuOption;
- TopOfScreen = &gMenuOption;
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
- ScreenOperation = UiPageUp;
- ControlFlag = CfScreenOperation;
- break;
- }
- } else if (MenuOption->Row < TopRow + DistanceValue + Difference) {
+ TopOfScreen = FindTopOfScreenMenu (gMenuOption.BackLink, BottomRow - TopRow, &SkipValue);
+ NewPos = gMenuOption.BackLink;
+ MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow, TRUE);
+ }
+ } else {
+ NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
+
+ if (MenuOption->Row < TopRow + Difference + NextMenuOption->Skip) {
//
// Previous focus MenuOption is above the TopOfScreen, so we need to scroll
//
TopOfScreen = NewPos;
Repaint = TRUE;
- SkipValue = 0;
- } else if (!IsSelectable (NextMenuOption)) {
- //
- // Continue to go up until scroll to next page or the selectable option is found.
- //
- ScreenOperation = UiUp;
- ControlFlag = CfScreenOperation;
+ SkipValue = 0;
}
//
- // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
+ // Check whether new highlight menu is selectable, if not, keep highlight on the old one.
//
- AdjustDateAndTimePosition (TRUE, &TopOfScreen);
- AdjustDateAndTimePosition (TRUE, &NewPos);
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
- UpdateStatusBar (INPUT_ERROR, FALSE);
- } else {
- if (NewPos->ForwardLink == &gMenuOption) {
- NewLine = FALSE;
- Repaint = FALSE;
- break;
+ // BottomRow - TopRow + 1 means the total rows current forms supported.
+ // Difference + NextMenuOption->Skip + 1 means the distance between last highlight menu
+ // and new top menu. New top menu will all shows in next form, but last highlight menu
+ // may only shows 1 line. + 1 at right part means at least need to keep 1 line for the
+ // last highlight menu.
+ //
+ if (!IsSelectable(NextMenuOption) && IsSelectable(MenuOption) &&
+ (BottomRow - TopRow + 1 >= Difference + NextMenuOption->Skip + 1)) {
+ NewPos = SavedListEntry;
}
- //
- // Scroll up to the last page.
- //
- NewPos = &gMenuOption;
- TopOfScreen = &gMenuOption;
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
- ScreenOperation = UiPageUp;
- ControlFlag = CfScreenOperation;
- SkipValue = 0;
}
- break;
- case CfUiPageUp:
- //
- // SkipValue means lines is skipped when show the top menu option.
- //
- ControlFlag = CfRepaint;
+ UpdateStatusBar (INPUT_ERROR, FALSE);
- ASSERT(NewPos != NULL);
//
- // Already at the first menu option, Check the skip value.
+ // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
//
- if (NewPos->BackLink == &gMenuOption) {
- if (SkipValue == 0) {
- NewLine = FALSE;
- Repaint = FALSE;
- } else {
- NewLine = TRUE;
- Repaint = TRUE;
- SkipValue = 0;
- }
- break;
- }
-
- NewLine = TRUE;
- Repaint = TRUE;
+ AdjustDateAndTimePosition (TRUE, &TopOfScreen);
+ AdjustDateAndTimePosition (TRUE, &NewPos);
+ break;
+ case CfUiPageUp:
//
- // SkipValue > (BottomRow - TopRow + 1) means current menu has more than one
- // form of options to be show, so just update the SkipValue to show the next
- // parts of options.
+ // SkipValue means lines is skipped when show the top menu option.
//
- if (SkipValue > (INTN) (BottomRow - TopRow + 1)) {
- SkipValue -= BottomRow - TopRow + 1;
- break;
- }
+ ControlFlag = CfRepaint;
+ NewLine = TRUE;
+ Repaint = TRUE;
Link = TopOfScreen;
//
// First minus the menu of the top screen, it's value is SkipValue.
//
- Index = (BottomRow + 1) - SkipValue;
- while ((Index > TopRow) && (Link->BackLink != &gMenuOption)) {
- Link = Link->BackLink;
- PreviousMenuOption = MENU_OPTION_FROM_LINK (Link);
- if (PreviousMenuOption->Row == 0) {
- UpdateOptionSkipLines (PreviousMenuOption);
- }
- if (Index < PreviousMenuOption->Skip) {
- break;
- }
- Index = Index - PreviousMenuOption->Skip;
- }
-
- if ((Link->BackLink == &gMenuOption) && (Index >= TopRow)) {
- if (TopOfScreen == &gMenuOption) {
- TopOfScreen = gMenuOption.ForwardLink;
- NewPos = gMenuOption.BackLink;
- MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow);
- if (Index < PreviousMenuOption->Skip) {
- Repaint = TRUE;
- SkipValue = PreviousMenuOption->Skip - (Index - TopRow);
- } else {
- Repaint = FALSE;
- SkipValue = 0;
- }
- } else if (TopOfScreen != Link) {
- TopOfScreen = Link;
- NewPos = Link;
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
- SkipValue = 0;
- } else {
- //
- // Finally we know that NewPos is the last MenuOption can be focused.
- //
- if (SkipValue == 0) {
- Repaint = FALSE;
- }
- NewPos = Link;
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
- SkipValue = 0;
- }
- } else {
- if (Index > TopRow) {
- //
- // At here, only case "Index < PreviousMenuOption->Skip" can reach here.
- //
- SkipValue = PreviousMenuOption->Skip - (Index - TopRow);
- } else if (Index == TopRow) {
- SkipValue = 0;
- } else {
- SkipValue = TopRow - Index;
- }
-
- //
- // Move to the option in Next page.
+ if (SkipValue >= BottomRow - TopRow + 1) {
//
- if (TopOfScreen == &gMenuOption) {
- NewPos = gMenuOption.BackLink;
- MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow);
- } else {
- NewPos = Link;
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
- }
-
- //
- // There are more MenuOption needing scrolling up.
+ // SkipValue > (BottomRow - TopRow + 1) means current menu has more than one
+ // form of options to be show, so just update the SkipValue to show the next
+ // parts of options.
//
- TopOfScreen = Link;
- MenuOption = NULL;
+ SkipValue -= BottomRow - TopRow + 1;
+ NewPos = TopOfScreen;
+ break;
+ } else {
+ Index = (BottomRow + 1) - SkipValue - TopRow;
}
+
+ TopOfScreen = FindTopOfScreenMenu(TopOfScreen, Index, &SkipValue);
+ NewPos = TopOfScreen;
+ MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow, FALSE);
+
+ UpdateStatusBar (INPUT_ERROR, FALSE);
//
// If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
@@ -3033,24 +2886,10 @@ UiDisplayMenu (
//
// SkipValue means lines is skipped when show the top menu option.
//
- ControlFlag = CfRepaint;
-
- ASSERT (NewPos != NULL);
- if (NewPos->ForwardLink == &gMenuOption) {
- MenuOption = MENU_OPTION_FROM_LINK (NewPos);
- if (SkipValue + BottomRow - TopRow + 1 < MenuOption->Skip) {
- SkipValue += BottomRow - TopRow + 1;
- NewLine = TRUE;
- Repaint = TRUE;
- break;
- }
- NewLine = FALSE;
- Repaint = FALSE;
- break;
- }
+ ControlFlag = CfRepaint;
+ NewLine = TRUE;
+ Repaint = TRUE;
- NewLine = TRUE;
- Repaint = TRUE;
Link = TopOfScreen;
NextMenuOption = MENU_OPTION_FROM_LINK (Link);
Index = TopRow + NextMenuOption->Skip - SkipValue;
@@ -3065,10 +2904,10 @@ UiDisplayMenu (
if ((Link->ForwardLink == &gMenuOption) && (Index <= BottomRow + 1)) {
//
- // Finally we know that NewPos is the last MenuOption can be focused.
+ // Highlight on the last menu which can be highlight.
//
Repaint = FALSE;
- MoveToNextStatement (TRUE, &Link, Index - TopRow);
+ MoveToNextStatement (TRUE, &Link, Index - TopRow, TRUE);
} else {
//
// Calculate the skip line for top of screen menu.
@@ -3081,13 +2920,12 @@ UiDisplayMenu (
} else {
SkipValue = NextMenuOption->Skip - (Index - (BottomRow + 1));
}
-
TopOfScreen = Link;
MenuOption = NULL;
//
// Move to the Next selectable menu.
//
- MoveToNextStatement (FALSE, &Link, BottomRow - TopRow);
+ MoveToNextStatement (FALSE, &Link, BottomRow - TopRow, TRUE);
}
//
@@ -3095,6 +2933,8 @@ UiDisplayMenu (
//
NewPos = Link;
+ UpdateStatusBar (INPUT_ERROR, FALSE);
+
//
// If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
// Don't do this when we are already in the last page.
@@ -3109,7 +2949,15 @@ UiDisplayMenu (
// NewPos points to the menu which is highlighted now.
//
ControlFlag = CfRepaint;
+ NewLine = TRUE;
+
+ if (NewPos == TopOfScreen) {
+ Temp2 = SkipValue;
+ } else {
+ Temp2 = 0;
+ }
+ SavedListEntry = NewPos;
//
// Since the behavior of hitting the down arrow on a Date/Time op-code is intended
// to be one that progresses to the next set of op-codes, we need to advance to the last
@@ -3118,182 +2966,134 @@ UiDisplayMenu (
// op-code is the last entry in the menu, we need to rewind back to the first op-code of
// the Date/Time op-code.
//
- SavedListEntry = NewPos;
AdjustDateAndTimePosition (FALSE, &NewPos);
- if (NewPos->ForwardLink != &gMenuOption) {
- if (NewPos == TopOfScreen) {
- Temp2 = SkipValue;
+ MenuOption = MENU_OPTION_FROM_LINK (NewPos);
+ NewPos = NewPos->ForwardLink;
+ //
+ // Find the next selectable menu.
+ //
+ if (MenuOption->Row + MenuOption->Skip - Temp2 > BottomRow + 1) {
+ if (gMenuOption.ForwardLink == NewPos || &gMenuOption == NewPos) {
+ Difference = -1;
} else {
- Temp2 = 0;
+ Difference = 0;
}
+ } else {
+ Difference = MoveToNextStatement (FALSE, &NewPos, BottomRow + 1 - (MenuOption->Row + MenuOption->Skip - Temp2), FALSE);
+ }
+ if (Difference < 0) {
+ //
+ // Scroll to the first page.
+ //
+ if (TopOfScreen != gMenuOption.ForwardLink || SkipValue != 0) {
+ TopOfScreen = gMenuOption.ForwardLink;
+ Repaint = TRUE;
+ MenuOption = NULL;
+ } else {
+ MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
+ }
+ NewPos = gMenuOption.ForwardLink;
+ MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow, TRUE);
- MenuOption = MENU_OPTION_FROM_LINK (NewPos);
- NewLine = TRUE;
- NewPos = NewPos->ForwardLink;
+ SkipValue = 0;
+ //
+ // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.
+ //
+ AdjustDateAndTimePosition (TRUE, &TopOfScreen);
+ AdjustDateAndTimePosition (TRUE, &NewPos);
+ break;
+ }
+
+ //
+ // Get next selected menu info.
+ //
+ AdjustDateAndTimePosition (FALSE, &NewPos);
+ NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
+ if (NextMenuOption->Row == 0) {
+ UpdateOptionSkipLines (NextMenuOption);
+ }
- Difference = 0;
+ //
+ // Calculate new highlight menu end row.
+ //
+ Temp = (MenuOption->Row + MenuOption->Skip - Temp2) + Difference + NextMenuOption->Skip - 1;
+ if (Temp > BottomRow) {
//
- // Current menu not at the bottom of the form.
+ // Get the top screen menu info.
//
- if (BottomRow >= MenuOption->Row + MenuOption->Skip - Temp2) {
- //
- // Find the next selectable menu.
- //
- Difference = MoveToNextStatement (FALSE, &NewPos, BottomRow - MenuOption->Row - MenuOption->Skip + Temp2);
+ AdjustDateAndTimePosition (FALSE, &TopOfScreen);
+ SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
+
+ //
+ // Current Top screen menu occupy (SavedMenuOption->Skip - SkipValue) rows.
+ // Full shows the new selected menu need to skip (Temp - BottomRow - 1) rows.
+ //
+ if ((Temp - BottomRow) >= (SavedMenuOption->Skip - SkipValue)) {
//
- // We hit the end of MenuOption that can be focused
- // so we simply scroll to the first page.
+ // Skip the top op-code
//
- if (Difference < 0) {
- //
- // Scroll to the first page.
- //
- if (TopOfScreen != gMenuOption.ForwardLink) {
- TopOfScreen = gMenuOption.ForwardLink;
- Repaint = TRUE;
- MenuOption = NULL;
- } else {
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
- }
- NewPos = gMenuOption.ForwardLink;
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
+ TopOfScreen = TopOfScreen->ForwardLink;
+ DistanceValue = (Temp - BottomRow) - (SavedMenuOption->Skip - SkipValue);
- SkipValue = 0;
- //
- // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.
- //
- AdjustDateAndTimePosition (TRUE, &TopOfScreen);
- AdjustDateAndTimePosition (TRUE, &NewPos);
- break;
- }
- }
- NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
- if (NextMenuOption->Row == 0) {
- UpdateOptionSkipLines (NextMenuOption);
- }
- DistanceValue = Difference + NextMenuOption->Skip - Temp2;
-
- Temp = MenuOption->Row + MenuOption->Skip + DistanceValue - 1;
- if ((MenuOption->Row + MenuOption->Skip - Temp2 == BottomRow + 1) &&
- (NextMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP ||
- NextMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)
- ) {
- Temp ++;
- }
+ SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
- //
- // If we are going to scroll, update TopOfScreen
- //
- if (Temp > BottomRow) {
- do {
+ //
+ // If we have a remainder, skip that many more op-codes until we drain the remainder
+ // Special case is the selected highlight menu has more than one form of menus.
+ //
+ while (DistanceValue >= SavedMenuOption->Skip && TopOfScreen != NewPos) {
//
- // Is the current top of screen a zero-advance op-code?
- // If so, keep moving forward till we hit a >0 advance op-code
+ // Since the Difference is greater than or equal to this op-code's skip value, skip it
//
+ DistanceValue = DistanceValue - (INTN) SavedMenuOption->Skip;
+ TopOfScreen = TopOfScreen->ForwardLink;
SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
-
- //
- // If bottom op-code is more than one line or top op-code is more than one line
- //
- if ((DistanceValue > 1) || (SavedMenuOption->Skip > 1)) {
- //
- // Is the bottom op-code greater than or equal in size to the top op-code?
- //
- if ((Temp - BottomRow) >= (SavedMenuOption->Skip - SkipValue)) {
- //
- // Skip the top op-code
- //
- TopOfScreen = TopOfScreen->ForwardLink;
- Difference = (Temp - BottomRow) - (SavedMenuOption->Skip - SkipValue);
-
- SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
-
- //
- // If we have a remainder, skip that many more op-codes until we drain the remainder
- //
- while (Difference >= (INTN) SavedMenuOption->Skip) {
- //
- // Since the Difference is greater than or equal to this op-code's skip value, skip it
- //
- Difference = Difference - (INTN) SavedMenuOption->Skip;
- TopOfScreen = TopOfScreen->ForwardLink;
- SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
- }
- //
- // Since we will act on this op-code in the next routine, and increment the
- // SkipValue, set the skips to one less than what is required.
- //
- SkipValue = Difference - 1;
- } else {
- //
- // Since we will act on this op-code in the next routine, and increment the
- // SkipValue, set the skips to one less than what is required.
- //
- SkipValue += (Temp - BottomRow) - 1;
- }
- } else {
- if ((SkipValue + 1) == (INTN) SavedMenuOption->Skip) {
- TopOfScreen = TopOfScreen->ForwardLink;
- break;
- }
- }
- //
- // If the op-code at the top of the screen is more than one line, let's not skip it yet
- // Let's set a skip flag to smoothly scroll the top of the screen.
- //
- if (SavedMenuOption->Skip > 1) {
- if (SavedMenuOption == NextMenuOption) {
- SkipValue = 0;
- } else {
- SkipValue++;
- }
- } else if (SavedMenuOption->Skip == 1) {
- SkipValue = 0;
- } else {
- SkipValue = 0;
- TopOfScreen = TopOfScreen->ForwardLink;
- }
- } while (SavedMenuOption->Skip == 0);
-
- Repaint = TRUE;
- } else if (!IsSelectable (NextMenuOption)) {
+ }
//
- // Continue to go down until scroll to next page or the selectable option is found.
+ // Since we will act on this op-code in the next routine, and increment the
+ // SkipValue, set the skips to one less than what is required.
//
- ScreenOperation = UiDown;
- ControlFlag = CfScreenOperation;
- }
-
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
-
- UpdateStatusBar (INPUT_ERROR, FALSE);
-
- } else {
- //
- // Scroll to the first page.
- //
- if (TopOfScreen != gMenuOption.ForwardLink || SkipValue != 0) {
- TopOfScreen = gMenuOption.ForwardLink;
- Repaint = TRUE;
- MenuOption = NULL;
+ if (TopOfScreen != NewPos) {
+ SkipValue = DistanceValue;
+ } else {
+ SkipValue = 0;
+ }
} else {
//
- // Need to remove the current highlight menu.
- // MenuOption saved the last highlight menu info.
+ // Since we will act on this op-code in the next routine, and increment the
+ // SkipValue, set the skips to one less than what is required.
//
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
+ SkipValue += Temp - BottomRow;
}
-
- SkipValue = 0;
- NewLine = TRUE;
+ Repaint = TRUE;
+ } else if (!IsSelectable (NextMenuOption)) {
//
- // Get the next highlight menu.
+ // Continue to go down until scroll to next page or the selectable option is found.
//
- NewPos = gMenuOption.ForwardLink;
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
+ ScreenOperation = UiDown;
+ ControlFlag = CfScreenOperation;
+ break;
}
+ MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
+
+ //
+ // Check whether new highlight menu is selectable, if not, keep highlight on the old one.
+ //
+ // BottomRow - TopRow + 1 means the total rows current forms supported.
+ // Difference + NextMenuOption->Skip + 1 means the distance between last highlight menu
+ // and new top menu. New top menu will all shows in next form, but last highlight menu
+ // may only shows 1 line. + 1 at right part means at least need to keep 1 line for the
+ // last highlight menu.
+ //
+ if (!IsSelectable (NextMenuOption) && IsSelectable (MenuOption) &&
+ (BottomRow - TopRow + 1 >= Difference + NextMenuOption->Skip + 1)) {
+ NewPos = SavedListEntry;
+ }
+
+ UpdateStatusBar (INPUT_ERROR, FALSE);
+
//
// If we are at the end of the list and sitting on a Date/Time op, rewind to the head.
//
diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c b/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c
index cf9f6836b..8da563ba7 100644
--- a/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c
+++ b/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c
@@ -55,6 +55,56 @@ NewStrCat (
}
/**
+ Get UINT64 type value.
+
+ @param Value Input Hii value.
+
+ @retval UINT64 Return the UINT64 type value.
+
+**/
+UINT64
+HiiValueToUINT64 (
+ IN EFI_HII_VALUE *Value
+ )
+{
+ UINT64 RetVal;
+
+ RetVal = 0;
+
+ switch (Value->Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ RetVal = Value->Value.u8;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ RetVal = Value->Value.u16;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ RetVal = Value->Value.u32;
+ break;
+
+ case EFI_IFR_TYPE_BOOLEAN:
+ RetVal = Value->Value.b;
+ break;
+
+ case EFI_IFR_TYPE_DATE:
+ RetVal = *(UINT64*) &Value->Value.date;
+ break;
+
+ case EFI_IFR_TYPE_TIME:
+ RetVal = (*(UINT64*) &Value->Value.time) & 0xffffff;
+ break;
+
+ default:
+ RetVal = Value->Value.u64;
+ break;
+ }
+
+ return RetVal;
+}
+
+/**
Compare two Hii value.
@param Value1 Expression value to compare on left-hand.
@@ -153,7 +203,7 @@ CompareHiiValue (
//
// Take remain types(integer, boolean, date/time) as integer
//
- Temp64 = (INT64) (Value1->Value.u64 - Value2->Value.u64);
+ Temp64 = HiiValueToUINT64(Value1) - HiiValueToUINT64(Value2);
if (Temp64 > 0) {
*Result = 1;
} else if (Temp64 < 0) {
@@ -1178,8 +1228,24 @@ ProcessOptions (
Link = GetFirstNode (&Question->OptionListHead);
Option = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
- CopyMem (&gUserInput->InputValue.Value, &Option->OptionOpCode->Value, sizeof (EFI_IFR_TYPE_VALUE));
gUserInput->InputValue.Type = Option->OptionOpCode->Type;
+ switch (gUserInput->InputValue.Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ gUserInput->InputValue.Value.u8 = Option->OptionOpCode->Value.u8;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ CopyMem (&gUserInput->InputValue.Value.u16, &Option->OptionOpCode->Value.u16, sizeof (UINT16));
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ CopyMem (&gUserInput->InputValue.Value.u32, &Option->OptionOpCode->Value.u32, sizeof (UINT32));
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ CopyMem (&gUserInput->InputValue.Value.u64, &Option->OptionOpCode->Value.u64, sizeof (UINT64));
+ break;
+ default:
+ ASSERT (FALSE);
+ break;
+ }
gUserInput->SelectedStatement = Question;
FreePool (*OptionString);
diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c b/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c
index 2ed02cdaa..fb69b9ca1 100644
--- a/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c
+++ b/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c
@@ -355,6 +355,9 @@ OutputConfigBody (
}
Length = TmpPtr - String;
+ if (Length == 0) {
+ return EFI_NOT_FOUND;
+ }
Result = AllocateCopyPool (Length * sizeof (CHAR16), String);
if (Result == NULL) {
return EFI_OUT_OF_RESOURCES;
@@ -1281,6 +1284,13 @@ IsThisVarstore (
GuidStr = NULL;
TempStr = NULL;
+ //
+ // If ConfigHdr has name field and varstore not has name, return FALSE.
+ //
+ if (Name == NULL && StrStr (ConfigHdr, L"NAME=&") == NULL) {
+ return FALSE;
+ }
+
GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *)VarstoreGuid, 1, &GuidStr);
if (Name != NULL) {
GenerateSubStr (L"NAME=", StrLen (Name) * sizeof (CHAR16), (VOID *) Name, 2, &NameStr);
@@ -1318,6 +1328,130 @@ Done:
}
/**
+ This function parses Form Package to get the efi varstore info according to the request ConfigHdr.
+
+ @param DataBaseRecord The DataBaseRecord instance contains the found Hii handle and package.
+ @param ConfigHdr Request string ConfigHdr. If it is NULL,
+ the first found varstore will be as ConfigHdr.
+ @retval TRUE This hii package is the reqeust one.
+ @retval FALSE This hii package is not the reqeust one.
+**/
+BOOLEAN
+IsThisPackageList (
+ IN HII_DATABASE_RECORD *DataBaseRecord,
+ IN EFI_STRING ConfigHdr
+ )
+{
+ EFI_STATUS Status;
+ UINTN IfrOffset;
+ UINTN PackageOffset;
+ EFI_IFR_OP_HEADER *IfrOpHdr;
+ CHAR16 *VarStoreName;
+ UINT8 *HiiFormPackage;
+ UINTN PackageSize;
+ EFI_IFR_VARSTORE_EFI *IfrEfiVarStore;
+ EFI_HII_PACKAGE_HEADER *PackageHeader;
+ EFI_IFR_VARSTORE *IfrVarStore;
+ EFI_IFR_VARSTORE_NAME_VALUE *IfrNameValueVarStore;
+ BOOLEAN FindVarstore;
+
+ HiiFormPackage = NULL;
+ VarStoreName = NULL;
+ Status = EFI_SUCCESS;
+ FindVarstore = FALSE;
+
+ Status = GetFormPackageData(DataBaseRecord, &HiiFormPackage, &PackageSize);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ IfrOffset = sizeof (EFI_HII_PACKAGE_HEADER);
+ PackageOffset = IfrOffset;
+ PackageHeader = (EFI_HII_PACKAGE_HEADER *) HiiFormPackage;
+
+ while (IfrOffset < PackageSize) {
+ //
+ // More than one form packages exist.
+ //
+ if (PackageOffset >= PackageHeader->Length) {
+ //
+ // Process the new form package.
+ //
+ PackageOffset = sizeof (EFI_HII_PACKAGE_HEADER);
+ IfrOffset += PackageOffset;
+ PackageHeader = (EFI_HII_PACKAGE_HEADER *) (HiiFormPackage + IfrOffset);
+ }
+
+ IfrOpHdr = (EFI_IFR_OP_HEADER *) (HiiFormPackage + IfrOffset);
+ IfrOffset += IfrOpHdr->Length;
+ PackageOffset += IfrOpHdr->Length;
+
+ switch (IfrOpHdr->OpCode) {
+
+ case EFI_IFR_VARSTORE_OP:
+ IfrVarStore = (EFI_IFR_VARSTORE *) IfrOpHdr;
+
+ VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)IfrVarStore->Name) * sizeof (CHAR16));
+ if (VarStoreName == NULL) {
+ goto Done;
+ }
+ AsciiStrToUnicodeStr ((CHAR8 *)IfrVarStore->Name, VarStoreName);
+
+ if (IsThisVarstore((VOID *)&IfrVarStore->Guid, VarStoreName, ConfigHdr)) {
+ FindVarstore = TRUE;
+ goto Done;
+ }
+ break;
+
+ case EFI_IFR_VARSTORE_EFI_OP:
+ IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *) IfrOpHdr;
+ VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name) * sizeof (CHAR16));
+ if (VarStoreName == NULL) {
+ goto Done;
+ }
+ AsciiStrToUnicodeStr ((CHAR8 *)IfrEfiVarStore->Name, VarStoreName);
+
+ if (IsThisVarstore (&IfrEfiVarStore->Guid, VarStoreName, ConfigHdr)) {
+ FindVarstore = TRUE;
+ goto Done;
+ }
+ break;
+
+ case EFI_IFR_VARSTORE_NAME_VALUE_OP:
+ IfrNameValueVarStore = (EFI_IFR_VARSTORE_NAME_VALUE *) IfrOpHdr;
+
+ if (IsThisVarstore (&IfrNameValueVarStore->Guid, NULL, ConfigHdr)) {
+ FindVarstore = TRUE;
+ goto Done;
+ }
+ break;
+
+ case EFI_IFR_FORM_OP:
+ case EFI_IFR_FORM_MAP_OP:
+ //
+ // No matched varstore is found and directly return.
+ //
+ goto Done;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+Done:
+ if (HiiFormPackage != NULL) {
+ FreePool (HiiFormPackage);
+ }
+
+ if (VarStoreName != NULL) {
+ FreePool (VarStoreName);
+ }
+
+ return FindVarstore;
+}
+
+/**
Check whether the this op code is required.
@param RequestBlockArray The array includes all the request info or NULL.
@@ -2128,14 +2262,26 @@ ParseIfrData (
//
// End Opcode is for Var question.
//
- if (BlockData != NULL && BlockData->Scope > 0) {
- BlockData->Scope--;
+ if (BlockData != NULL) {
+ if (BlockData->Scope > 0) {
+ BlockData->Scope--;
+ }
+ if (BlockData->Scope == 0) {
+ BlockData = NULL;
+ }
}
+
break;
default:
- if (BlockData != NULL && BlockData->Scope > 0) {
- BlockData->Scope = (UINT8) (BlockData->Scope + IfrOpHdr->Scope);
+ if (BlockData != NULL) {
+ if (BlockData->Scope > 0) {
+ BlockData->Scope = (UINT8) (BlockData->Scope + IfrOpHdr->Scope);
+ }
+
+ if (BlockData->Scope == 0) {
+ BlockData = NULL;
+ }
}
break;
}
@@ -3200,10 +3346,11 @@ GetConfigRespFromEfiVarStore (
UINT8 *VarStore;
UINTN BufferSize;
- Status = EFI_SUCCESS;
- BufferSize = 0;
- VarStore = NULL;
- VarStoreName = NULL;
+ Status = EFI_SUCCESS;
+ BufferSize = 0;
+ VarStore = NULL;
+ VarStoreName = NULL;
+ *AccessProgress = Request;
VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)EfiVarStoreInfo->Name) * sizeof (CHAR16));
if (VarStoreName == NULL) {
@@ -3537,6 +3684,7 @@ HiiConfigRoutingExtractConfig (
BOOLEAN IsEfiVarStore;
EFI_IFR_VARSTORE_EFI *EfiVarStoreInfo;
EFI_STRING ErrorPtr;
+ UINTN DevicePathSize;
if (This == NULL || Progress == NULL || Results == NULL) {
return EFI_INVALID_PARAMETER;
@@ -3622,11 +3770,8 @@ HiiConfigRoutingExtractConfig (
Database = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
if ((DevicePathPkg = Database->PackageList->DevicePathPkg) != NULL) {
CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);
- if (CompareMem (
- DevicePath,
- CurrentDevicePath,
- GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) CurrentDevicePath)
- ) == 0) {
+ DevicePathSize = GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) CurrentDevicePath);
+ if ((CompareMem (DevicePath,CurrentDevicePath,DevicePathSize) == 0) && IsThisPackageList(Database, ConfigRequest)) {
DriverHandle = Database->DriverHandle;
HiiHandle = Database->Handle;
break;
@@ -4060,6 +4205,7 @@ HiiConfigRoutingRouteConfig (
EFI_STRING AccessProgress;
EFI_IFR_VARSTORE_EFI *EfiVarStoreInfo;
BOOLEAN IsEfiVarstore;
+ UINTN DevicePathSize;
if (This == NULL || Progress == NULL) {
return EFI_INVALID_PARAMETER;
@@ -4131,11 +4277,8 @@ HiiConfigRoutingRouteConfig (
if ((DevicePathPkg = Database->PackageList->DevicePathPkg) != NULL) {
CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);
- if (CompareMem (
- DevicePath,
- CurrentDevicePath,
- GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) CurrentDevicePath)
- ) == 0) {
+ DevicePathSize = GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) CurrentDevicePath);
+ if ((CompareMem (DevicePath,CurrentDevicePath,DevicePathSize) == 0) && IsThisPackageList(Database, ConfigResp)) {
DriverHandle = Database->DriverHandle;
break;
}
diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/Image.c b/MdeModulePkg/Universal/HiiDatabaseDxe/Image.c
index ccd197557..efa5bbb71 100644
--- a/MdeModulePkg/Universal/HiiDatabaseDxe/Image.c
+++ b/MdeModulePkg/Universal/HiiDatabaseDxe/Image.c
@@ -2,7 +2,7 @@
Implementation for EFI_HII_IMAGE_PROTOCOL.
-Copyright (c) 2007 - 2008, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -81,7 +81,6 @@ GetImageIdOrAddress (
case EFI_HII_IIBT_EXT1:
Length8 = *(ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK) + sizeof (UINT8));
ImageBlock += Length8;
- ImageIdCurrent++;
break;
case EFI_HII_IIBT_EXT2:
CopyMem (
@@ -90,7 +89,6 @@ GetImageIdOrAddress (
sizeof (UINT16)
);
ImageBlock += Length16;
- ImageIdCurrent++;
break;
case EFI_HII_IIBT_EXT4:
CopyMem (
@@ -99,7 +97,6 @@ GetImageIdOrAddress (
sizeof (UINT32)
);
ImageBlock += Length32;
- ImageIdCurrent++;
break;
case EFI_HII_IIBT_IMAGE_1BIT:
diff --git a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiDriver.c b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiDriver.c
index f668fe3d9..f4663d9f5 100644
--- a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiDriver.c
+++ b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiDriver.c
@@ -1,7 +1,7 @@
/** @file
The entry point of IScsi driver.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -24,6 +24,44 @@ EFI_DRIVER_BINDING_PROTOCOL gIScsiDriverBinding = {
};
/**
+ Tests to see if this driver supports the RemainingDevicePath.
+
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
+ parameter is ignored by device drivers, and is optional for bus
+ drivers. For bus drivers, if this parameter is not NULL, then
+ the bus driver must determine if the bus controller specified
+ by ControllerHandle and the child controller specified
+ by RemainingDevicePath are both supported by this
+ bus driver.
+
+ @retval EFI_SUCCESS The RemainingDevicePath is supported or NULL.
+ @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
+ RemainingDevicePath is not supported by the driver specified by This.
+**/
+EFI_STATUS
+IScsiIsDevicePathSupported (
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;
+
+ CurrentDevicePath = RemainingDevicePath;
+ if (CurrentDevicePath != NULL) {
+ while (!IsDevicePathEnd (CurrentDevicePath)) {
+ if ((CurrentDevicePath->Type == MESSAGING_DEVICE_PATH) && (CurrentDevicePath->SubType == MSG_ISCSI_DP)) {
+ return EFI_SUCCESS;
+ }
+
+ CurrentDevicePath = NextDevicePathNode (CurrentDevicePath);
+ }
+
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
Tests to see if this driver supports a given controller. If a child device is provided,
it further tests to see if this driver supports creating a handle for the specified child device.
@@ -56,7 +94,6 @@ IScsiDriverBindingSupported (
)
{
EFI_STATUS Status;
- EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;
Status = gBS->OpenProtocol (
ControllerHandle,
@@ -82,17 +119,23 @@ IScsiDriverBindingSupported (
return EFI_UNSUPPORTED;
}
- CurrentDevicePath = RemainingDevicePath;
- if (CurrentDevicePath != NULL) {
- while (!IsDevicePathEnd (CurrentDevicePath)) {
- if ((CurrentDevicePath->Type == MESSAGING_DEVICE_PATH) && (CurrentDevicePath->SubType == MSG_ISCSI_DP)) {
- return EFI_SUCCESS;
- }
+ Status = IScsiIsDevicePathSupported (RemainingDevicePath);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
- CurrentDevicePath = NextDevicePathNode (CurrentDevicePath);
+ if (IScsiDhcpIsConfigured (ControllerHandle)) {
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiDhcp4ServiceBindingProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
}
-
- return EFI_UNSUPPORTED;
}
return EFI_SUCCESS;
@@ -170,7 +213,7 @@ IScsiDriverBindingStart (
goto ON_ERROR;
}
- //
+ //
// Always install private protocol no matter what happens later. We need to
// keep the relationship between ControllerHandle and ChildHandle.
//
diff --git a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.c b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.c
index 5341e5a01..2e43b415e 100644
--- a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.c
+++ b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.c
@@ -1,7 +1,7 @@
/** @file
Miscellaneous routines for iSCSI driver.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -617,6 +617,59 @@ IScsiCleanDriverData (
}
/**
+ Check wheather the Controller is configured to use DHCP protocol.
+
+ @param[in] Controller The handle of the controller.
+
+ @retval TRUE The handle of the controller need the Dhcp protocol.
+ @retval FALSE The handle of the controller does not need the Dhcp protocol.
+
+**/
+BOOLEAN
+IScsiDhcpIsConfigured (
+ IN EFI_HANDLE Controller
+ )
+{
+ EFI_STATUS Status;
+ EFI_MAC_ADDRESS MacAddress;
+ UINTN HwAddressSize;
+ UINT16 VlanId;
+ CHAR16 MacString[70];
+ ISCSI_SESSION_CONFIG_NVDATA *ConfigDataTmp;
+
+ //
+ // Get the mac string, it's the name of various variable
+ //
+ Status = NetLibGetMacAddress (Controller, &MacAddress, &HwAddressSize);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ VlanId = NetLibGetVlanId (Controller);
+ IScsiMacAddrToStr (&MacAddress, (UINT32) HwAddressSize, VlanId, MacString);
+
+ //
+ // Get the normal configuration.
+ //
+ Status = GetVariable2 (
+ MacString,
+ &gEfiIScsiInitiatorNameProtocolGuid,
+ (VOID**)&ConfigDataTmp,
+ NULL
+ );
+ if (ConfigDataTmp == NULL || EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ if (ConfigDataTmp->Enabled && ConfigDataTmp->InitiatorInfoFromDhcp) {
+ FreePool (ConfigDataTmp);
+ return TRUE;
+ }
+
+ FreePool (ConfigDataTmp);
+ return FALSE;
+}
+
+/**
Get the various configuration data of this iSCSI instance.
@param[in] Private The iSCSI driver data.
diff --git a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.h b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.h
index 512c67c38..b310c9c57 100644
--- a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.h
+++ b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.h
@@ -1,7 +1,7 @@
/** @file
Miscellaneous definitions for iSCSI driver.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -222,6 +222,20 @@ IScsiCleanDriverData (
);
/**
+ Check wheather the Controller is configured to use DHCP protocol.
+
+ @param[in] Controller The handle of the controller.
+
+ @retval TRUE The handle of the controller need the Dhcp protocol.
+ @retval FALSE The handle of the controller does not need the Dhcp protocol.
+
+**/
+BOOLEAN
+IScsiDhcpIsConfigured (
+ IN EFI_HANDLE Controller
+ );
+
+/**
Get the various configuration data of this iSCSI instance.
@param[in] Private The iSCSI driver data.
diff --git a/MdeModulePkg/Universal/PCD/Dxe/Pcd.c b/MdeModulePkg/Universal/PCD/Dxe/Pcd.c
index 3cd805a88..8a3e8cd50 100644
--- a/MdeModulePkg/Universal/PCD/Dxe/Pcd.c
+++ b/MdeModulePkg/Universal/PCD/Dxe/Pcd.c
@@ -3,7 +3,7 @@
produce the implementation of native PCD protocol and EFI_PCD_PROTOCOL defined in
PI 1.2 Vol3.
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -16,13 +16,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "Service.h"
-//
-// Just pre-allocate a memory buffer that is big enough to
-// host all distinct TokenSpace guid in both
-// PEI ExMap and DXE ExMap.
-//
-EFI_GUID *TmpTokenSpaceBuffer[PEI_EXMAPPING_TABLE_SIZE + DXE_EXMAPPING_TABLE_SIZE] = { 0 };
-
///
/// PCD database lock.
///
@@ -96,6 +89,25 @@ EFI_PCD_PROTOCOL mEfiPcdInstance = {
DxePcdGetNextTokenSpace
};
+///
+/// Instance of GET_PCD_INFO_PROTOCOL protocol is EDKII native implementation.
+/// This protocol instance support dynamic and dynamicEx type PCDs.
+///
+GET_PCD_INFO_PROTOCOL mGetPcdInfoInstance = {
+ DxeGetPcdInfoGetInfo,
+ DxeGetPcdInfoGetInfoEx,
+ DxeGetPcdInfoGetSku
+};
+
+///
+/// Instance of EFI_GET_PCD_INFO_PROTOCOL which is defined in PI 1.2.1 Vol 3.
+/// This PPI instance only support dyanmicEx type PCD.
+///
+EFI_GET_PCD_INFO_PROTOCOL mEfiGetPcdInfoInstance = {
+ DxeGetPcdInfoGetInfoEx,
+ DxeGetPcdInfoGetSku
+};
+
EFI_HANDLE mPcdHandle = NULL;
/**
@@ -136,11 +148,90 @@ PcdDxeInit (
&gEfiPcdProtocolGuid, &mEfiPcdInstance,
NULL
);
-
ASSERT_EFI_ERROR (Status);
+ //
+ // Only install PcdInfo PROTOCOL when PCD info content is present.
+ //
+ if (mPcdDatabase.DxeDb->PcdNameTableOffset != 0) {
+ //
+ // Install GET_PCD_INFO_PROTOCOL to handle dynamic type PCD
+ // Install EFI_GET_PCD_INFO_PROTOCOL to handle dynamicEx type PCD
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mPcdHandle,
+ &gGetPcdInfoProtocolGuid, &mGetPcdInfoInstance,
+ &gEfiGetPcdInfoProtocolGuid, &mEfiGetPcdInfoInstance,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
return Status;
+}
+
+/**
+ Retrieve additional information associated with a PCD token in the default token space.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully.
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+EFIAPI
+DxeGetPcdInfoGetInfo (
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ )
+{
+ return DxeGetPcdInfo (NULL, TokenNumber, PcdInfo);
+}
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully.
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+EFIAPI
+DxeGetPcdInfoGetInfoEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ )
+{
+ return DxeGetPcdInfo (Guid, TokenNumber, PcdInfo);
+}
+
+/**
+ Retrieve the currently set SKU Id.
+ @return The currently set SKU Id. If the platform has not set at a SKU Id, then the
+ default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU
+ Id is returned.
+**/
+UINTN
+EFIAPI
+DxeGetPcdInfoGetSku (
+ VOID
+ )
+{
+ return mPcdDatabase.PeiDb->SystemSkuId;
}
/**
@@ -170,7 +261,7 @@ DxePcdSetSku (
IN UINTN SkuId
)
{
- mPcdDatabase->PeiDb.Init.SystemSkuId = (SKU_ID) SkuId;
+ mPcdDatabase.PeiDb->SystemSkuId = (SKU_ID) SkuId;
return;
}
@@ -336,18 +427,18 @@ DxePcdGetSize (
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
- ASSERT (TokenNumber + 1 < PCD_TOTAL_TOKEN_NUMBER + 1);
+ ASSERT (TokenNumber + 1 < mPcdTotalTokenCount + 1);
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
- IsPeiDb = (BOOLEAN) (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
+ IsPeiDb = (BOOLEAN) (TokenNumber + 1 < mPeiLocalTokenCount + 1);
TokenNumber = IsPeiDb ? TokenNumber :
- (TokenNumber - PEI_LOCAL_TOKEN_NUMBER);
+ (TokenNumber - mPeiLocalTokenCount);
- LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable
- : mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
+ LocalTokenNumberTable = IsPeiDb ? (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset)
+ : (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);
Size = (LocalTokenNumberTable[TokenNumber] & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;
@@ -971,10 +1062,8 @@ DxeUnRegisterCallBackOnSet (
@param[in, out] TokenNumber
A pointer to the PCD token number to use to find the subsequent token number.
- @retval EFI_SUCCESS The PCD service retrieved the next valid token number. Or the input token number
- is already the last valid token number in the PCD database.
- In the later case, *TokenNumber is updated with the value of 0.
- @retval EFI_NOT_FOUND If this input token number and token namespace does not exist on the platform.
+ @retval EFI_SUCCESS The PCD service has retrieved the next valid token number.
+ @retval EFI_NOT_FOUND The PCD service could not find data from the requested token number.
**/
EFI_STATUS
@@ -989,8 +1078,8 @@ DxePcdGetNextToken (
BOOLEAN DxeExMapTableEmpty;
Status = EFI_NOT_FOUND;
- PeiExMapTableEmpty = PEI_EXMAP_TABLE_EMPTY;
- DxeExMapTableEmpty = DXE_EXMAP_TABLE_EMPTY;
+ PeiExMapTableEmpty = mPeiExMapTableEmpty;
+ DxeExMapTableEmpty = mDxeExMapTableEmpty;
//
// Scan the local token space
@@ -999,27 +1088,32 @@ DxePcdGetNextToken (
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
- if (((*TokenNumber + 1 > PEI_NEX_TOKEN_NUMBER + 1) && (*TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1)) ||
- ((*TokenNumber + 1 > (PEI_LOCAL_TOKEN_NUMBER + DXE_NEX_TOKEN_NUMBER + 1)))) {
- return EFI_NOT_FOUND;
+ if (((*TokenNumber + 1 > mPeiNexTokenCount + 1) && (*TokenNumber + 1 <= mPeiLocalTokenCount + 1)) ||
+ ((*TokenNumber + 1 > (mPeiLocalTokenCount + mDxeNexTokenCount + 1)))) {
+ return EFI_NOT_FOUND;
}
(*TokenNumber)++;
- if ((*TokenNumber + 1 > PEI_NEX_TOKEN_NUMBER + 1) &&
- (*TokenNumber <= PEI_LOCAL_TOKEN_NUMBER)) {
+ if ((*TokenNumber + 1 > mPeiNexTokenCount + 1) &&
+ (*TokenNumber + 1 <= mPeiLocalTokenCount + 1)) {
//
// The first Non-Ex type Token Number for DXE PCD
- // database is PEI_LOCAL_TOKEN_NUMBER
+ // database is mPeiLocalTokenCount + 1
//
- *TokenNumber = PEI_LOCAL_TOKEN_NUMBER;
- } else if (*TokenNumber + 1 > DXE_NEX_TOKEN_NUMBER + PEI_LOCAL_TOKEN_NUMBER + 1) {
+ if (mDxeNexTokenCount > 0) {
+ *TokenNumber = mPeiLocalTokenCount + 1;
+ } else {
+ *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
+ return EFI_NOT_FOUND;
+ }
+ } else if (*TokenNumber + 1 > mDxeNexTokenCount + mPeiLocalTokenCount + 1) {
*TokenNumber = PCD_INVALID_TOKEN_NUMBER;
+ return EFI_NOT_FOUND;
}
return EFI_SUCCESS;
}
if (PeiExMapTableEmpty && DxeExMapTableEmpty) {
- *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
return EFI_NOT_FOUND;
}
@@ -1027,10 +1121,10 @@ DxePcdGetNextToken (
Status = ExGetNextTokeNumber (
Guid,
TokenNumber,
- mPcdDatabase->PeiDb.Init.GuidTable,
- sizeof(mPcdDatabase->PeiDb.Init.GuidTable),
- mPcdDatabase->PeiDb.Init.ExMapTable,
- sizeof(mPcdDatabase->PeiDb.Init.ExMapTable)
+ (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset),
+ mPeiGuidTableSize,
+ (DYNAMICEX_MAPPING *)((UINT8 *) mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->ExMapTableOffset),
+ mPeiExMapppingTableSize
);
}
@@ -1042,10 +1136,10 @@ DxePcdGetNextToken (
Status = ExGetNextTokeNumber (
Guid,
TokenNumber,
- mPcdDatabase->DxeDb.Init.GuidTable,
- sizeof(mPcdDatabase->DxeDb.Init.GuidTable),
- mPcdDatabase->DxeDb.Init.ExMapTable,
- sizeof(mPcdDatabase->DxeDb.Init.ExMapTable)
+ (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset),
+ mDxeGuidTableSize,
+ (DYNAMICEX_MAPPING *)((UINT8 *) mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->ExMapTableOffset),
+ mDxeExMapppingTableSize
);
}
@@ -1055,7 +1149,7 @@ DxePcdGetNextToken (
/**
Get all token space guid table which is different with given token space guid.
- @param ExMapTableSize The size of guid table
+ @param ExMapTableSize The size of ExMapTable in item
@param ExMapTable Token space guid table that want to be scaned.
@param GuidTable Guid table
@@ -1072,8 +1166,9 @@ GetDistinctTokenSpace (
EFI_GUID **DistinctTokenSpace;
UINTN OldGuidIndex;
UINTN TsIdx;
+ UINTN TempTsIdx;
UINTN Idx;
-
+ BOOLEAN Match;
DistinctTokenSpace = AllocateZeroPool (*ExMapTableSize * sizeof (EFI_GUID *));
ASSERT (DistinctTokenSpace != NULL);
@@ -1082,8 +1177,18 @@ GetDistinctTokenSpace (
OldGuidIndex = ExMapTable[0].ExGuidIndex;
DistinctTokenSpace[TsIdx] = &GuidTable[OldGuidIndex];
for (Idx = 1; Idx < *ExMapTableSize; Idx++) {
- if (ExMapTable[Idx].ExGuidIndex != OldGuidIndex) {
- OldGuidIndex = ExMapTable[Idx].ExGuidIndex;
+ Match = FALSE;
+ OldGuidIndex = ExMapTable[Idx].ExGuidIndex;
+ for (TempTsIdx = 0; TempTsIdx <= TsIdx; TempTsIdx++) {
+ if (&GuidTable[OldGuidIndex] == DistinctTokenSpace[TempTsIdx]) {
+ //
+ // Have recorded this GUID.
+ //
+ Match = TRUE;
+ break;
+ }
+ }
+ if (!Match) {
DistinctTokenSpace[++TsIdx] = &GuidTable[OldGuidIndex];
}
}
@@ -1099,16 +1204,20 @@ GetDistinctTokenSpace (
}
/**
- Get next token space in PCD database according to given token space guid.
-
- @param Guid Given token space guid. If NULL, then Guid will be set to
- the first PCD token space in PCD database, If not NULL, then
- Guid will be set to next PCD token space.
-
- @retval EFI_UNSUPPORTED
- @retval EFI_NOT_FOUND If PCD database has no token space table or can not find given
- token space in PCD database.
- @retval EFI_SUCCESS Success to get next token space guid.
+ Retrieves the next valid PCD token namespace for a given namespace.
+
+ Gets the next valid token namespace for a given namespace. This is useful to traverse the valid
+ token namespaces on a platform.
+
+ @param[in, out] Guid An indirect pointer to EFI_GUID. On input it designates a known token
+ namespace from which the search will start. On output, it designates the next valid
+ token namespace on the platform. If *Guid is NULL, then the GUID of the first token
+ space of the current platform is returned. If the search cannot locate the next valid
+ token namespace, an error is returned and the value of *Guid is undefined.
+
+ @retval EFI_SUCCESS The PCD service retrieved the value requested.
+ @retval EFI_NOT_FOUND The PCD service could not find the next valid token namespace.
+
**/
EFI_STATUS
EFIAPI
@@ -1129,35 +1238,31 @@ DxePcdGetNextTokenSpace (
ASSERT (Guid != NULL);
- PeiExMapTableEmpty = PEI_EXMAP_TABLE_EMPTY;
- DxeExMapTableEmpty = DXE_EXMAP_TABLE_EMPTY;
+ PeiExMapTableEmpty = mPeiExMapTableEmpty;
+ DxeExMapTableEmpty = mDxeExMapTableEmpty;
if (PeiExMapTableEmpty && DxeExMapTableEmpty) {
- if (*Guid != NULL) {
- return EFI_NOT_FOUND;
- } else {
- return EFI_SUCCESS;
- }
+ return EFI_NOT_FOUND;
}
-
if (TmpTokenSpaceBuffer[0] == NULL) {
PeiTokenSpaceTableSize = 0;
if (!PeiExMapTableEmpty) {
- PeiTokenSpaceTableSize = PEI_EXMAPPING_TABLE_SIZE;
+ PeiTokenSpaceTableSize = mPeiExMapppingTableSize / sizeof(DYNAMICEX_MAPPING);
PeiTokenSpaceTable = GetDistinctTokenSpace (&PeiTokenSpaceTableSize,
- mPcdDatabase->PeiDb.Init.ExMapTable,
- mPcdDatabase->PeiDb.Init.GuidTable
+ (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->ExMapTableOffset),
+ (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset)
);
CopyMem (TmpTokenSpaceBuffer, PeiTokenSpaceTable, sizeof (EFI_GUID*) * PeiTokenSpaceTableSize);
+ FreePool (PeiTokenSpaceTable);
}
if (!DxeExMapTableEmpty) {
- DxeTokenSpaceTableSize = DXE_EXMAPPING_TABLE_SIZE;
+ DxeTokenSpaceTableSize = mDxeExMapppingTableSize / sizeof(DYNAMICEX_MAPPING);
DxeTokenSpaceTable = GetDistinctTokenSpace (&DxeTokenSpaceTableSize,
- mPcdDatabase->DxeDb.Init.ExMapTable,
- mPcdDatabase->DxeDb.Init.GuidTable
+ (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->ExMapTableOffset),
+ (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset)
);
//
@@ -1175,6 +1280,9 @@ DxePcdGetNextTokenSpace (
TmpTokenSpaceBuffer[Idx3++] = DxeTokenSpaceTable[Idx2];
}
}
+
+ TmpTokenSpaceBufferCount = Idx3;
+ FreePool (DxeTokenSpaceTable);
}
}
@@ -1183,11 +1291,19 @@ DxePcdGetNextTokenSpace (
return EFI_SUCCESS;
}
- for (Idx = 0; Idx < (PEI_EXMAPPING_TABLE_SIZE + DXE_EXMAPPING_TABLE_SIZE); Idx++) {
- if(CompareGuid (*Guid, TmpTokenSpaceBuffer[Idx])) {
- Idx++;
- *Guid = TmpTokenSpaceBuffer[Idx];
- return EFI_SUCCESS;
+ for (Idx = 0; Idx < TmpTokenSpaceBufferCount; Idx++) {
+ if (CompareGuid (*Guid, TmpTokenSpaceBuffer[Idx])) {
+ if (Idx == TmpTokenSpaceBufferCount - 1) {
+ //
+ // It has been the last token namespace.
+ //
+ *Guid = NULL;
+ return EFI_NOT_FOUND;
+ } else {
+ Idx++;
+ *Guid = TmpTokenSpaceBuffer[Idx];
+ return EFI_SUCCESS;
+ }
}
}
diff --git a/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf b/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
index 112c91e06..2b8d83c12 100644
--- a/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+++ b/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
@@ -1,18 +1,19 @@
## @file
-# PCD DXE driver manage database contains all dynamic PCD entries initialized in
-# PEI phase, DXE phase and produce the implementation of PCD protocol.
+# PCD DXE driver manage database contains all dynamic PCD entries and produce the implementation of PCD protocol.
#
+# This version PCD DXE depends on the external PCD database binary file, not built in PCD data base.
# There are two PCD Protocols as follows:
# 1) PCD_PROTOCOL
# It is EDKII implementation which support Dynamic/DynamicEx type Pcds.
-# 2) EFI_PCD_PROTOCOL_PPI
+# 2) EFI_PCD_PROTOCOL
# It is defined by PI specification 1.2, Vol 3 which only support dynamicEx
# type Pcd.
#
-# For dynamicEx type PCD, it is compatible between PCD_PPI and EFI_PEI_PCD_PPI.
+# For dynamicEx type PCD, it is compatible between PCD_PROTOCOL and EFI_PCD_PROTOCOL.
# PCD DXE driver will produce above two protocols at same time.
#
-# PCD database structure is generated at autogen.h/autogen.c in build time.
+# PCD database is generated as the separate binary image at build time. The binary image
+# will be intergrated into Firmware volume together with PCD driver.
#
# ////////////////////////////////////////////////////////////////////////////////
# // //
@@ -63,7 +64,7 @@
# b) Variable Storage:
# - The PCD value is stored in variable area.
# - As default storage type, this type PCD could be used for PEI/DXE driver
-# communication. But beside it, this type PCD could alsp be used to store
+# communication. But beside it, this type PCD could also be used to store
# the value associate with a HII setting via variable interface.
# - In PEI phase, the PCD value could only be got but can not be set due
# to variable area is readonly.
@@ -94,12 +95,12 @@
# PCD information used in PEI phase or use in both PEI/DXE phase. And DXE PCD
# database contains all PCDs used in PEI/DXE phase in memory.
#
-# Build tool will generate PCD database into some C structure and variable for
+# Build tool will generate PCD database into the separate binary file for
# PEI/DXE PCD driver according to dynamic PCD section in platform DSC file.
#
# 3.1 PcdPeim and PcdDxe
# PEI PCD database is maintained by PcdPeim driver run from flash. PcdPeim driver
-# build guid hob in temporary memory and copy auto-generated C structure
+# build guid hob in temporary memory and copy the binary data base from flash
# to temporary memory for PEI PCD database.
# DXE PCD database is maintained by PcdDxe driver.At entry point of PcdDxe driver,
# a new PCD database is allocated in boot-time memory which including all
@@ -185,8 +186,10 @@
# Based on local token number, PCD driver could fast determine PCD type, value
# type and get PCD entry from PCD database.
#
-# 3.3 PCD Database C structure.
-# PCD Database C structure is generated by build tools in PCD driver's autogen.h/
+# 3.3 PCD Database binary file
+# PCD Database binary file will be created at build time as the standalone binary image.
+# To understand the binary image layout, PCD Database C structure is still generated
+# as comments by build tools in PCD driver's autogen.h/
# autogen.c file. In generated C structure, following information is stored:
# - ExMapTable: This table is used translate a binary dynamicex type PCD's
# "tokenguid + token" to local token number.
@@ -195,7 +198,7 @@
# token number" as array index to get PCD entry's offset fastly.
# - SizeTable: This table stores the size information for all PCD entry.
# - GuidTable: This table stores guid value for DynamicEx's token space,
-# HII type PCD's variable.
+# HII type PCD's variable GUID.
# - SkuIdTable: TBD
# - SystemSkuId: TBD
# - PCD value structure:
@@ -275,8 +278,8 @@
# GuidTable array is used to store all related GUID value in PCD database:
# - Variable GUID for HII type PCD
# - Token space GUID for dynamicex type PCD
-#
-# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+#
+# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
@@ -293,7 +296,7 @@
BASE_NAME = PcdDxe
FILE_GUID = 80CF7257-87AB-47f9-A3FE-D50B76D89541
MODULE_TYPE = DXE_DRIVER
- VERSION_STRING = 1.0
+ VERSION_STRING = 4.0
PCD_IS_DRIVER = DXE_PCD_DRIVER
ENTRY_POINT = PcdDxeInit
@@ -323,16 +326,20 @@
DebugLib
BaseLib
PcdLib
+ DxeServicesLib
[Guids]
- gPcdDataBaseHobGuid ## CONSUMES ## Hob: GUID_EXTENSION
+ gPcdDataBaseHobGuid ## SOMETIMES_CONSUMES ## HOB
+ gPcdDataBaseSignatureGuid ## CONSUMES ## UNDEFINED # PCD database signature GUID.
[Protocols]
gPcdProtocolGuid ## PRODUCES
gEfiPcdProtocolGuid ## PRODUCES
-
+ gGetPcdInfoProtocolGuid ## SOMETIMES_PRODUCES
+ gEfiGetPcdInfoProtocolGuid ## SOMETIMES_PRODUCES
+
[Pcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress ## SOMETIMES_CONSUMES
[Depex]
TRUE
diff --git a/MdeModulePkg/Universal/PCD/Dxe/Service.c b/MdeModulePkg/Universal/PCD/Dxe/Service.c
index 6eaadd6cc..b082f0a6d 100644
--- a/MdeModulePkg/Universal/PCD/Dxe/Service.c
+++ b/MdeModulePkg/Universal/PCD/Dxe/Service.c
@@ -13,10 +13,336 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Service.h"
+#include <Library/DxeServicesLib.h>
-PCD_DATABASE *mPcdDatabase;
+PCD_DATABASE mPcdDatabase;
+
+UINT32 mPcdTotalTokenCount;
+UINT32 mPeiLocalTokenCount;
+UINT32 mDxeLocalTokenCount;
+UINT32 mPeiNexTokenCount;
+UINT32 mDxeNexTokenCount;
+UINT32 mPeiExMapppingTableSize;
+UINT32 mDxeExMapppingTableSize;
+UINT32 mPeiGuidTableSize;
+UINT32 mDxeGuidTableSize;
+
+BOOLEAN mPeiExMapTableEmpty;
+BOOLEAN mDxeExMapTableEmpty;
+BOOLEAN mPeiDatabaseEmpty;
LIST_ENTRY *mCallbackFnTable;
+EFI_GUID **TmpTokenSpaceBuffer;
+UINTN TmpTokenSpaceBufferCount;
+
+/**
+ Get Local Token Number by Token Number.
+
+ @param[in] IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
+ If FALSE, the pcd entry is initialized in DXE phase.
+ @param[in] TokenNumber The PCD token number.
+
+ @return Local Token Number.
+**/
+UINT32
+GetLocalTokenNumber (
+ IN BOOLEAN IsPeiDb,
+ IN UINTN TokenNumber
+ )
+{
+ UINT32 *LocalTokenNumberTable;
+ UINT32 LocalTokenNumber;
+ UINTN Size;
+ UINTN MaxSize;
+
+ //
+ // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
+ // We have to decrement TokenNumber by 1 to make it usable
+ // as the array index.
+ //
+ TokenNumber--;
+
+ LocalTokenNumberTable = IsPeiDb ? (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset) :
+ (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);
+ TokenNumber = IsPeiDb ? TokenNumber : TokenNumber - mPeiLocalTokenCount;
+
+ LocalTokenNumber = LocalTokenNumberTable[TokenNumber];
+
+ Size = (LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;
+
+ if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
+ if (Size == 0) {
+ GetPtrTypeSize (TokenNumber, &MaxSize);
+ } else {
+ MaxSize = Size;
+ }
+ LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb);
+ }
+
+ return LocalTokenNumber;
+}
+
+/**
+ Get PCD type by Local Token Number.
+
+ @param[in] LocalTokenNumber The PCD local token number.
+
+ @return PCD type.
+**/
+EFI_PCD_TYPE
+GetPcdType (
+ IN UINT32 LocalTokenNumber
+ )
+{
+ switch (LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) {
+ case PCD_DATUM_TYPE_POINTER:
+ return EFI_PCD_TYPE_PTR;
+ case PCD_DATUM_TYPE_UINT8:
+ if ((LocalTokenNumber & PCD_DATUM_TYPE_UINT8_BOOLEAN) == PCD_DATUM_TYPE_UINT8_BOOLEAN) {
+ return EFI_PCD_TYPE_BOOL;
+ } else {
+ return EFI_PCD_TYPE_8;
+ }
+ case PCD_DATUM_TYPE_UINT16:
+ return EFI_PCD_TYPE_16;
+ case PCD_DATUM_TYPE_UINT32:
+ return EFI_PCD_TYPE_32;
+ case PCD_DATUM_TYPE_UINT64:
+ return EFI_PCD_TYPE_64;
+ default:
+ ASSERT (FALSE);
+ return EFI_PCD_TYPE_8;
+ }
+}
+
+/**
+ Get PCD name.
+
+ @param[in] OnlyTokenSpaceName If TRUE, only need to get the TokenSpaceCName.
+ If FALSE, need to get the full PCD name.
+ @param[in] IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
+ If FALSE, the pcd entry is initialized in DXE phase.
+ @param[in] TokenNumber The PCD token number.
+
+ @return The TokenSpaceCName or full PCD name.
+**/
+CHAR8 *
+GetPcdName (
+ IN BOOLEAN OnlyTokenSpaceName,
+ IN BOOLEAN IsPeiDb,
+ IN UINTN TokenNumber
+ )
+{
+ PCD_DATABASE_INIT *Database;
+ UINT8 *StringTable;
+ PCD_NAME_INDEX *PcdNameIndex;
+ CHAR8 *TokenSpaceName;
+ CHAR8 *PcdName;
+ CHAR8 *Name;
+
+ //
+ // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
+ // We have to decrement TokenNumber by 1 to make it usable
+ // as the array index.
+ //
+ TokenNumber--;
+
+ Database = IsPeiDb ? mPcdDatabase.PeiDb: mPcdDatabase.DxeDb;
+ TokenNumber = IsPeiDb ? TokenNumber : TokenNumber - mPeiLocalTokenCount;
+
+ StringTable = (UINT8 *) Database + Database->StringTableOffset;
+
+ //
+ // Get the PCD name index.
+ //
+ PcdNameIndex = (PCD_NAME_INDEX *)((UINT8 *) Database + Database->PcdNameTableOffset) + TokenNumber;
+ TokenSpaceName = (CHAR8 *)&StringTable[PcdNameIndex->TokenSpaceCNameIndex];
+ PcdName = (CHAR8 *)&StringTable[PcdNameIndex->PcdCNameIndex];
+
+ if (OnlyTokenSpaceName) {
+ //
+ // Only need to get the TokenSpaceCName.
+ //
+ Name = AllocateCopyPool (AsciiStrSize (TokenSpaceName), TokenSpaceName);
+ } else {
+ //
+ // Need to get the full PCD name.
+ //
+ Name = AllocateZeroPool (AsciiStrSize (TokenSpaceName) + AsciiStrSize (PcdName));
+ ASSERT (Name != NULL);
+ //
+ // Catenate TokenSpaceCName and PcdCName with a '.' to form the full PCD name.
+ //
+ AsciiStrCat (Name, TokenSpaceName);
+ Name[AsciiStrSize (TokenSpaceName) - sizeof (CHAR8)] = '.';
+ AsciiStrCat (Name, PcdName);
+ }
+
+ return Name;
+}
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
+ If FALSE, the pcd entry is initialized in DXE phase.
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+ExGetPcdInfo (
+ IN BOOLEAN IsPeiDb,
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ )
+{
+ PCD_DATABASE_INIT *Database;
+ UINTN GuidTableIdx;
+ EFI_GUID *MatchGuid;
+ EFI_GUID *GuidTable;
+ DYNAMICEX_MAPPING *ExMapTable;
+ UINTN Index;
+ UINT32 LocalTokenNumber;
+
+ Database = IsPeiDb ? mPcdDatabase.PeiDb: mPcdDatabase.DxeDb;
+
+ GuidTable = (EFI_GUID *)((UINT8 *)Database + Database->GuidTableOffset);
+ MatchGuid = ScanGuid (GuidTable, Database->GuidTableCount * sizeof(EFI_GUID), Guid);
+
+ if (MatchGuid == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ GuidTableIdx = MatchGuid - GuidTable;
+
+ ExMapTable = (DYNAMICEX_MAPPING *)((UINT8 *)Database + Database->ExMapTableOffset);
+
+ //
+ // Find the PCD by GuidTableIdx and ExTokenNumber in ExMapTable.
+ //
+ for (Index = 0; Index < Database->ExTokenCount; Index++) {
+ if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {
+ if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {
+ //
+ // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,
+ // PcdSize to 0 and PcdName to the null-terminated ASCII string
+ // associated with the token's namespace Guid.
+ //
+ PcdInfo->PcdType = EFI_PCD_TYPE_8;
+ PcdInfo->PcdSize = 0;
+ //
+ // Here use one representative in the token space to get the TokenSpaceCName.
+ //
+ PcdInfo->PcdName = GetPcdName (TRUE, IsPeiDb, ExMapTable[Index].TokenNumber);
+ return EFI_SUCCESS;
+ } else if (ExMapTable[Index].ExTokenNumber == TokenNumber) {
+ PcdInfo->PcdSize = DxePcdGetSize (ExMapTable[Index].TokenNumber);
+ LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, ExMapTable[Index].TokenNumber);
+ PcdInfo->PcdType = GetPcdType (LocalTokenNumber);
+ PcdInfo->PcdName = GetPcdName (FALSE, IsPeiDb, ExMapTable[Index].TokenNumber);
+ return EFI_SUCCESS;
+ }
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully.
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+DxeGetPcdInfo (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN PeiExMapTableEmpty;
+ BOOLEAN DxeExMapTableEmpty;
+ UINT32 LocalTokenNumber;
+ BOOLEAN IsPeiDb;
+
+ ASSERT (PcdInfo != NULL);
+
+ Status = EFI_NOT_FOUND;
+ PeiExMapTableEmpty = mPeiExMapTableEmpty;
+ DxeExMapTableEmpty = mDxeExMapTableEmpty;
+
+ if (Guid == NULL) {
+ if (((TokenNumber + 1 > mPeiNexTokenCount + 1) && (TokenNumber + 1 <= mPeiLocalTokenCount + 1)) ||
+ ((TokenNumber + 1 > (mPeiLocalTokenCount + mDxeNexTokenCount + 1)))) {
+ return EFI_NOT_FOUND;
+ } else if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {
+ //
+ // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,
+ // PcdSize to 0 and PcdName to NULL for default Token Space.
+ //
+ PcdInfo->PcdType = EFI_PCD_TYPE_8;
+ PcdInfo->PcdSize = 0;
+ PcdInfo->PcdName = NULL;
+ } else {
+ PcdInfo->PcdSize = DxePcdGetSize (TokenNumber);
+ IsPeiDb = FALSE;
+ if ((TokenNumber + 1 <= mPeiNexTokenCount + 1)) {
+ IsPeiDb = TRUE;
+ }
+ LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber);
+ PcdInfo->PcdType = GetPcdType (LocalTokenNumber);
+ PcdInfo->PcdName = GetPcdName (FALSE, IsPeiDb, TokenNumber);
+ }
+ return EFI_SUCCESS;
+ }
+
+ if (PeiExMapTableEmpty && DxeExMapTableEmpty) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (!PeiExMapTableEmpty) {
+ Status = ExGetPcdInfo (
+ TRUE,
+ Guid,
+ TokenNumber,
+ PcdInfo
+ );
+ }
+
+ if (Status == EFI_SUCCESS) {
+ return Status;
+ }
+
+ if (!DxeExMapTableEmpty) {
+ Status = ExGetPcdInfo (
+ FALSE,
+ Guid,
+ TokenNumber,
+ PcdInfo
+ );
+ }
+
+ return Status;
+}
/**
Get the PCD entry pointer in PCD database.
@@ -38,7 +364,6 @@ GetWorker (
IN UINTN GetSize
)
{
- UINT32 *LocalTokenNumberTable;
EFI_GUID *GuidTable;
UINT8 *StringTable;
EFI_GUID *Guid;
@@ -49,7 +374,6 @@ GetWorker (
VPD_HEAD *VpdHead;
UINT8 *PcdDb;
VOID *RetPtr;
- UINTN MaxSize;
UINTN TmpTokenNumber;
UINTN DataSize;
EFI_STATUS Status;
@@ -64,6 +388,8 @@ GetWorker (
EfiAcquireLock (&mPcdDatabaseLock);
RetPtr = NULL;
+
+ ASSERT (TokenNumber > 0);
//
// TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
// We have to decrement TokenNumber by 1 to make it usable
@@ -72,115 +398,81 @@ GetWorker (
TokenNumber--;
TmpTokenNumber = TokenNumber;
-
+
//
- // PCD_TOTAL_TOKEN_NUMBER is a auto-generated constant.
- // It could be zero. EBC compiler is very choosy. It may
- // report warning. So we add 1 in each size of the
+ // EBC compiler is very choosy. It may report warning about comparison
+ // between UINTN and 0 . So we add 1 in each size of the
// comparison.
//
- ASSERT (TokenNumber + 1 < PCD_TOTAL_TOKEN_NUMBER + 1);
+ ASSERT (TokenNumber + 1 < mPcdTotalTokenCount + 1);
ASSERT ((GetSize == DxePcdGetSize (TokenNumber + 1)) || (GetSize == 0));
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
- IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1) ? TRUE : FALSE);
+ IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < mPeiLocalTokenCount + 1) ? TRUE : FALSE);
- LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable :
- mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
+ LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber + 1);
- TokenNumber = IsPeiDb ? TokenNumber :
- TokenNumber - PEI_LOCAL_TOKEN_NUMBER;
-
- LocalTokenNumber = LocalTokenNumberTable[TokenNumber];
-
- if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
- if (GetSize == 0) {
- GetPtrTypeSize (TmpTokenNumber, &MaxSize);
- } else {
- MaxSize = GetSize;
- }
- LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb);
- }
-
- PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb);
+ PcdDb = IsPeiDb ? ((UINT8 *) mPcdDatabase.PeiDb) : ((UINT8 *) mPcdDatabase.DxeDb);
if (IsPeiDb) {
- StringTable = (UINT8 *) (&mPcdDatabase->PeiDb.Init.StringTable[0]);
+ StringTable = (UINT8 *) ((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->StringTableOffset);
} else {
- StringTable = (UINT8 *) (&mPcdDatabase->DxeDb.Init.StringTable[0]);
+ StringTable = (UINT8 *) ((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->StringTableOffset);
}
-
-
+
+
Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
-
+
switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
case PCD_TYPE_VPD:
VpdHead = (VPD_HEAD *) ((UINT8 *) PcdDb + Offset);
RetPtr = (VOID *) (UINTN) (PcdGet32 (PcdVpdBaseAddress) + VpdHead->Offset);
+
break;
-
+
case PCD_TYPE_HII|PCD_TYPE_STRING:
case PCD_TYPE_HII:
if (IsPeiDb) {
- GuidTable = (EFI_GUID *) (&mPcdDatabase->PeiDb.Init.GuidTable[0]);
+ GuidTable = (EFI_GUID *) ((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset);
} else {
- GuidTable = (EFI_GUID *) (&mPcdDatabase->DxeDb.Init.GuidTable[0]);
+ GuidTable = (EFI_GUID *) ((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset);
}
-
+
VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);
Guid = GuidTable + VariableHead->GuidTableIndex;
Name = (UINT16*)(StringTable + VariableHead->StringIndex);
-
+
if ((LocalTokenNumber & PCD_TYPE_ALL_SET) == (PCD_TYPE_HII|PCD_TYPE_STRING)) {
- //
- // If a HII type PCD's datum type is VOID*, the DefaultValueOffset is the index of
- // string array in string table.
- //
+ //
+ // If a HII type PCD's datum type is VOID*, the DefaultValueOffset is the index of
+ // string array in string table.
+ //
StringTableIdx = *(STRING_HEAD*)((UINT8 *) PcdDb + VariableHead->DefaultValueOffset);
VaraiableDefaultBuffer = (VOID *) (StringTable + StringTableIdx);
- Status = GetHiiVariable (Guid, Name, &Data, &DataSize);
- if (Status == EFI_SUCCESS) {
- if (GetSize == 0) {
- //
- // It is a pointer type. So get the MaxSize reserved for
- // this PCD entry.
- //
- GetPtrTypeSize (TmpTokenNumber, &GetSize);
- }
- //
- // If the operation is successful, we copy the data
- // to the default value buffer in the PCD Database.
- // So that we can free the Data allocated in GetHiiVariable.
- //
- CopyMem (VaraiableDefaultBuffer, Data + VariableHead->Offset, GetSize);
- FreePool (Data);
- }
- RetPtr = (VOID *) VaraiableDefaultBuffer;
} else {
VaraiableDefaultBuffer = (UINT8 *) PcdDb + VariableHead->DefaultValueOffset;
-
- Status = GetHiiVariable (Guid, Name, &Data, &DataSize);
- if (Status == EFI_SUCCESS) {
- if (GetSize == 0) {
- //
- // It is a pointer type. So get the MaxSize reserved for
- // this PCD entry.
- //
- GetPtrTypeSize (TmpTokenNumber, &GetSize);
- }
+ }
+ Status = GetHiiVariable (Guid, Name, &Data, &DataSize);
+ if (Status == EFI_SUCCESS) {
+ if (GetSize == 0) {
//
- // If the operation is successful, we copy the data
- // to the default value buffer in the PCD Database.
- // So that we can free the Data allocated in GetHiiVariable.
+ // It is a pointer type. So get the MaxSize reserved for
+ // this PCD entry.
//
- CopyMem (VaraiableDefaultBuffer, Data + VariableHead->Offset, GetSize);
- FreePool (Data);
+ GetPtrTypeSize (TmpTokenNumber, &GetSize);
}
- RetPtr = (VOID *) VaraiableDefaultBuffer;
+ //
+ // If the operation is successful, we copy the data
+ // to the default value buffer in the PCD Database.
+ // So that we can free the Data allocated in GetHiiVariable.
+ //
+ CopyMem (VaraiableDefaultBuffer, Data + VariableHead->Offset, GetSize);
+ FreePool (Data);
}
+ RetPtr = (VOID *) VaraiableDefaultBuffer;
break;
case PCD_TYPE_STRING:
@@ -199,9 +491,9 @@ GetWorker (
}
EfiReleaseLock (&mPcdDatabaseLock);
-
+
return RetPtr;
-
+
}
/**
@@ -359,6 +651,7 @@ ExGetNextTokeNumber (
UINTN Index;
UINTN GuidTableIdx;
BOOLEAN Found;
+ UINTN ExMapTableCount;
//
// Scan token space guid
@@ -373,7 +666,8 @@ ExGetNextTokeNumber (
//
Found = FALSE;
GuidTableIdx = MatchGuid - GuidTable;
- for (Index = 0; Index < SizeOfExMapTable; Index++) {
+ ExMapTableCount = SizeOfExMapTable / sizeof(ExMapTable[0]);
+ for (Index = 0; Index < ExMapTableCount; Index++) {
if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {
Found = TRUE;
break;
@@ -390,36 +684,71 @@ ExGetNextTokeNumber (
return EFI_SUCCESS;
}
- for ( ; Index < SizeOfExMapTable; Index++) {
+ for ( ; Index < ExMapTableCount; Index++) {
if (ExMapTable[Index].ExTokenNumber == *TokenNumber) {
- Index ++;
- if (Index == SizeOfExMapTable) {
- //
- // Exceed the length of ExMap Table
- //
- *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
- return EFI_SUCCESS;
- } else if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {
- //
- // Found the next match
- //
- *TokenNumber = ExMapTable[Index].ExTokenNumber;
- return EFI_SUCCESS;
- } else {
- //
- // Guid has been changed. It is the next Token Space Guid.
- // We should flag no more TokenNumber.
- //
- *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
- return EFI_SUCCESS;
- }
+ break;
+ }
+ }
+
+ while (Index < ExMapTableCount) {
+ Index++;
+ if (Index == ExMapTableCount) {
+ //
+ // Exceed the length of ExMap Table
+ //
+ *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
+ return EFI_NOT_FOUND;
+ } else if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {
+ //
+ // Found the next match
+ //
+ *TokenNumber = ExMapTable[Index].ExTokenNumber;
+ return EFI_SUCCESS;
}
}
}
-
+
return EFI_NOT_FOUND;
}
+/**
+ Find the PCD database.
+
+ @retval The base address of external PCD database binary.
+ @retval NULL Return NULL if not find.
+**/
+DXE_PCD_DATABASE *
+LocateExPcdBinary (
+ VOID
+)
+{
+ DXE_PCD_DATABASE *DxePcdDbBinary;
+ UINTN DxePcdDbSize;
+ EFI_STATUS Status;
+
+ DxePcdDbBinary = NULL;
+ //
+ // Search the External Pcd database from one section of current FFS,
+ // and read it to memory
+ //
+ Status = GetSectionFromFfs (
+ EFI_SECTION_RAW,
+ 0,
+ (VOID **) &DxePcdDbBinary,
+ &DxePcdDbSize
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Check the first bytes (Header Signature Guid) and build version.
+ //
+ if (!CompareGuid ((VOID *)DxePcdDbBinary, &gPcdDataBaseSignatureGuid) ||
+ (DxePcdDbBinary->BuildVersion != PCD_SERVICE_DXE_VERSION)) {
+ ASSERT (FALSE);
+ }
+
+ return DxePcdDbBinary;
+}
/**
Initialize the PCD database in DXE phase.
@@ -436,15 +765,12 @@ BuildPcdDxeDataBase (
PEI_PCD_DATABASE *PeiDatabase;
EFI_HOB_GUID_TYPE *GuidHob;
UINTN Index;
-
- mPcdDatabase = AllocateZeroPool (sizeof(PCD_DATABASE));
- ASSERT (mPcdDatabase != NULL);
+ UINT32 PcdDxeDbLen;
+ VOID *PcdDxeDb;
GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);
if (GuidHob != NULL) {
- //
- // We will copy over the PEI phase's PCD Database.
//
// If no PEIMs use dynamic Pcd Entry, the Pcd Service PEIM
// should not be included at all. So the GuidHob could
@@ -454,28 +780,57 @@ BuildPcdDxeDataBase (
PeiDatabase = (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);
//
- // Copy PCD Entries refereneced in PEI phase to PCD DATABASE
+ // Assign PCD Entries refereneced in PEI phase to PCD DATABASE
//
- CopyMem (&mPcdDatabase->PeiDb, PeiDatabase, sizeof (PEI_PCD_DATABASE));
+ mPcdDatabase.PeiDb = PeiDatabase;
}
//
- // Copy PCD Entries with default value to PCD DATABASE
+ // Assign PCD Entries with default value to PCD DATABASE
+ //
+ mPcdDatabase.DxeDb = LocateExPcdBinary ();
+ ASSERT(mPcdDatabase.DxeDb != NULL);
+ PcdDxeDbLen = mPcdDatabase.DxeDb->Length + mPcdDatabase.DxeDb->UninitDataBaseSize;
+ PcdDxeDb = AllocateZeroPool (PcdDxeDbLen);
+ ASSERT (PcdDxeDb != NULL);
+ CopyMem (PcdDxeDb, mPcdDatabase.DxeDb, mPcdDatabase.DxeDb->Length);
+ FreePool (mPcdDatabase.DxeDb);
+ mPcdDatabase.DxeDb = PcdDxeDb;
+
+ //
+ // Initialized the external PCD database local variables
//
- CopyMem (&mPcdDatabase->DxeDb.Init, &gDXEPcdDbInit, sizeof(DXE_PCD_DATABASE_INIT));
+ mPeiLocalTokenCount = mPcdDatabase.PeiDb->LocalTokenCount;
+ mDxeLocalTokenCount = mPcdDatabase.DxeDb->LocalTokenCount;
+
+ mPeiExMapppingTableSize = mPcdDatabase.PeiDb->ExTokenCount * sizeof (DYNAMICEX_MAPPING);
+ mDxeExMapppingTableSize = mPcdDatabase.DxeDb->ExTokenCount * sizeof (DYNAMICEX_MAPPING);
+ mPeiGuidTableSize = mPcdDatabase.PeiDb->GuidTableCount * sizeof(GUID);
+ mDxeGuidTableSize = mPcdDatabase.DxeDb->GuidTableCount * sizeof (GUID);
+
+ mPcdTotalTokenCount = mPeiLocalTokenCount + mDxeLocalTokenCount;
+ mPeiNexTokenCount = mPeiLocalTokenCount - mPcdDatabase.PeiDb->ExTokenCount;
+ mDxeNexTokenCount = mDxeLocalTokenCount - mPcdDatabase.DxeDb->ExTokenCount;
+
+ mPeiExMapTableEmpty = (mPcdDatabase.PeiDb->ExTokenCount == 0) ? TRUE : FALSE;
+ mDxeExMapTableEmpty = (mPcdDatabase.DxeDb->ExTokenCount == 0) ? TRUE : FALSE;
+ mPeiDatabaseEmpty = (mPeiLocalTokenCount == 0) ? TRUE : FALSE;
+ TmpTokenSpaceBufferCount = mPcdDatabase.PeiDb->ExTokenCount + mPcdDatabase.DxeDb->ExTokenCount;
+ TmpTokenSpaceBuffer = (EFI_GUID **)AllocateZeroPool(TmpTokenSpaceBufferCount * sizeof (EFI_GUID *));
//
// Initialized the Callback Function Table
//
-
- mCallbackFnTable = AllocateZeroPool (PCD_TOTAL_TOKEN_NUMBER * sizeof (LIST_ENTRY));
+ mCallbackFnTable = AllocateZeroPool (mPcdTotalTokenCount * sizeof (LIST_ENTRY));
ASSERT(mCallbackFnTable != NULL);
-
+
+ //
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
- for (Index = 0; Index + 1 < PCD_TOTAL_TOKEN_NUMBER + 1; Index++) {
+ //
+ for (Index = 0; Index + 1 < mPcdTotalTokenCount + 1; Index++) {
InitializeListHead (&mCallbackFnTable[Index]);
}
}
@@ -568,29 +923,39 @@ GetSkuEnabledTokenNumber (
SKU_ID *SkuIdTable;
INTN Index;
UINT8 *Value;
- SKU_ID *PhaseSkuIdTable;
UINT8 *PcdDb;
+ BOOLEAN FoundSku;
ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0);
- PcdDb = IsPeiDb ? (UINT8 *) &mPcdDatabase->PeiDb : (UINT8 *) &mPcdDatabase->DxeDb;
+ PcdDb = IsPeiDb ? (UINT8 *) mPcdDatabase.PeiDb : (UINT8 *) mPcdDatabase.DxeDb;
SkuHead = (SKU_HEAD *) (PcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));
Value = (UINT8 *) (PcdDb + SkuHead->SkuDataStartOffset);
- PhaseSkuIdTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.SkuIdTable :
- mPcdDatabase->DxeDb.Init.SkuIdTable;
-
- SkuIdTable = &PhaseSkuIdTable[SkuHead->SkuIdTableOffset];
-
+ SkuIdTable = (SKU_ID *)(PcdDb + SkuHead->SkuIdTableOffset);
//
// Find the current system's SKU ID entry in SKU ID table.
//
+ FoundSku = FALSE;
for (Index = 0; Index < SkuIdTable[0]; Index++) {
- if (mPcdDatabase->PeiDb.Init.SystemSkuId == SkuIdTable[Index + 1]) {
+ if (mPcdDatabase.PeiDb->SystemSkuId == SkuIdTable[Index + 1]) {
+ FoundSku = TRUE;
break;
}
}
+
+ //
+ // Find the default SKU ID entry in SKU ID table.
+ //
+
+ if(!FoundSku) {
+ for (Index = 0; Index < SkuIdTable[0]; Index++) {
+ if (0 == SkuIdTable[Index + 1]) {
+ break;
+ }
+ }
+ }
ASSERT (Index < SkuIdTable[0]);
switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
@@ -602,13 +967,17 @@ GetSkuEnabledTokenNumber (
Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[Index]);
return (UINT32) ((Value - PcdDb) | PCD_TYPE_HII);
+ case PCD_TYPE_HII|PCD_TYPE_STRING:
+ Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[Index]);
+ return (UINT32) ((Value - PcdDb) | PCD_TYPE_HII | PCD_TYPE_STRING);
+
case PCD_TYPE_STRING:
Value = (UINT8 *) &(((STRING_HEAD *) Value)[Index]);
return (UINT32) ((Value - PcdDb) | PCD_TYPE_STRING);
case PCD_TYPE_DATA:
Value += Size * Index;
- return (UINT32) (Value - PcdDb);
+ return (UINT32) ((Value - PcdDb) | PCD_TYPE_DATA);
default:
ASSERT (FALSE);
@@ -714,7 +1083,6 @@ SetWorker (
IN BOOLEAN PtrType
)
{
- UINT32 *LocalTokenNumberTable;
BOOLEAN IsPeiDb;
UINT32 LocalTokenNumber;
EFI_GUID *GuidTable;
@@ -744,7 +1112,7 @@ SetWorker (
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
//
- ASSERT (TokenNumber + 1 < PCD_TOTAL_TOKEN_NUMBER + 1);
+ ASSERT (TokenNumber + 1 < mPcdTotalTokenCount + 1);
if (PtrType) {
//
@@ -766,8 +1134,8 @@ SetWorker (
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
//
- if ((TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1) ||
- (TokenNumber + 1 >= PEI_LOCAL_TOKEN_NUMBER + 1 || TokenNumber + 1 < (PEI_LOCAL_TOKEN_NUMBER + DXE_NEX_TOKEN_NUMBER + 1))) {
+ if ((TokenNumber + 1 < mPeiNexTokenCount + 1) ||
+ (TokenNumber + 1 >= mPeiLocalTokenCount + 1 && TokenNumber + 1 < (mPeiLocalTokenCount + mDxeNexTokenCount + 1))) {
InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);
}
@@ -781,33 +1149,18 @@ SetWorker (
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
//
- IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1) ? TRUE : FALSE);
+ IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < mPeiLocalTokenCount + 1) ? TRUE : FALSE);
- LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable :
- mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
-
- TokenNumber = IsPeiDb ? TokenNumber
- : TokenNumber - PEI_LOCAL_TOKEN_NUMBER;
-
- LocalTokenNumber = LocalTokenNumberTable[TokenNumber];
-
- if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
- if (PtrType) {
- GetPtrTypeSize (TmpTokenNumber, &MaxSize);
- } else {
- MaxSize = *Size;
- }
- LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb);
- }
+ LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber + 1);
Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
- PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb);
+ PcdDb = IsPeiDb ? ((UINT8 *) mPcdDatabase.PeiDb) : ((UINT8 *) mPcdDatabase.DxeDb);
if (IsPeiDb) {
- StringTable = (UINT8 *) (&mPcdDatabase->PeiDb.Init.StringTable[0]);
+ StringTable = (UINT8 *) ((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->StringTableOffset);
} else {
- StringTable = (UINT8 *) (&mPcdDatabase->DxeDb.Init.StringTable[0]);
+ StringTable = (UINT8 *) ((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->StringTableOffset);
}
@@ -836,20 +1189,20 @@ SetWorker (
break;
}
}
-
+
if (IsPeiDb) {
- GuidTable = (EFI_GUID *) (&mPcdDatabase->PeiDb.Init.GuidTable[0]);
+ GuidTable = (EFI_GUID *) ((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset);
} else {
- GuidTable = (EFI_GUID *) (&mPcdDatabase->DxeDb.Init.GuidTable[0]);
+ GuidTable = (EFI_GUID *) ((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset);
}
-
+
VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);
-
+
Guid = GuidTable + VariableHead->GuidTableIndex;
Name = (UINT16*) (StringTable + VariableHead->StringIndex);
VariableOffset = VariableHead->Offset;
Status = SetHiiVariable (Guid, Name, Data, *Size, VariableOffset);
-
+
if (EFI_NOT_FOUND == Status) {
if ((LocalTokenNumber & PCD_TYPE_ALL_SET) == (PCD_TYPE_HII|PCD_TYPE_STRING)) {
CopyMem (
@@ -954,7 +1307,7 @@ ExSetValueWorker (
}
/**
- Set value for a dynamic PCD entry.
+ Set value for a dynamic-ex PCD entry.
This routine find the local token number according to dynamic-ex PCD's token
space guid and token number firstly, and invoke callback function if this PCD
@@ -1100,16 +1453,16 @@ SetHiiVariable (
}
/**
- Get local token number according to dynamic-ex PCD's {token space guid:token number}
+ Get Token Number according to dynamic-ex PCD's {token space guid:token number}
A dynamic-ex type PCD, developer must provide pair of token space guid: token number
in DEC file. PCD database maintain a mapping table that translate pair of {token
- space guid: token number} to local token number.
+ space guid: token number} to Token Number.
@param Guid Token space guid for dynamic-ex PCD entry.
@param ExTokenNumber Dynamic-ex PCD token number.
- @return local token number for dynamic-ex PCD.
+ @return Token Number for dynamic-ex PCD.
**/
UINTN
@@ -1124,29 +1477,29 @@ GetExPcdTokenNumber (
EFI_GUID *MatchGuid;
UINTN MatchGuidIdx;
- if (!PEI_DATABASE_EMPTY) {
- ExMap = mPcdDatabase->PeiDb.Init.ExMapTable;
- GuidTable = mPcdDatabase->PeiDb.Init.GuidTable;
-
- MatchGuid = ScanGuid (GuidTable, sizeof(mPcdDatabase->PeiDb.Init.GuidTable), Guid);
-
+ if (!mPeiDatabaseEmpty) {
+ ExMap = (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->ExMapTableOffset);
+ GuidTable = (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset);
+
+ MatchGuid = ScanGuid (GuidTable, mPeiGuidTableSize, Guid);
+
if (MatchGuid != NULL) {
MatchGuidIdx = MatchGuid - GuidTable;
-
- for (Index = 0; Index < PEI_EXMAPPING_TABLE_SIZE; Index++) {
+
+ for (Index = 0; Index < mPeiExMapppingTableSize; Index++) {
if ((ExTokenNumber == ExMap[Index].ExTokenNumber) &&
(MatchGuidIdx == ExMap[Index].ExGuidIndex)) {
- return ExMap[Index].LocalTokenNumber;
+ return ExMap[Index].TokenNumber;
}
}
}
}
-
- ExMap = mPcdDatabase->DxeDb.Init.ExMapTable;
- GuidTable = mPcdDatabase->DxeDb.Init.GuidTable;
- MatchGuid = ScanGuid (GuidTable, sizeof(mPcdDatabase->DxeDb.Init.GuidTable), Guid);
+ ExMap = (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->ExMapTableOffset);
+ GuidTable = (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset);
+
+ MatchGuid = ScanGuid (GuidTable, mDxeGuidTableSize, Guid);
//
// We need to ASSERT here. If GUID can't be found in GuidTable, this is a
// error in the BUILD system.
@@ -1154,11 +1507,11 @@ GetExPcdTokenNumber (
ASSERT (MatchGuid != NULL);
MatchGuidIdx = MatchGuid - GuidTable;
-
- for (Index = 0; Index < DXE_EXMAPPING_TABLE_SIZE; Index++) {
+
+ for (Index = 0; Index < mDxeExMapppingTableSize; Index++) {
if ((ExTokenNumber == ExMap[Index].ExTokenNumber) &&
(MatchGuidIdx == ExMap[Index].ExGuidIndex)) {
- return ExMap[Index].LocalTokenNumber;
+ return ExMap[Index].TokenNumber;
}
}
@@ -1171,27 +1524,27 @@ GetExPcdTokenNumber (
Get SKU ID table from PCD database.
@param LocalTokenNumberTableIdx Index of local token number in token number table.
- @param IsPeiPcd If TRUE,
-
+ @param IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
+ If FALSE, the pcd entry is initialized in DXE phase.
@return Pointer to SKU ID array table
**/
SKU_ID *
GetSkuIdArray (
IN UINTN LocalTokenNumberTableIdx,
- IN BOOLEAN IsPeiPcd
+ IN BOOLEAN IsPeiDb
)
{
SKU_HEAD *SkuHead;
UINTN LocalTokenNumber;
UINT8 *Database;
- if (IsPeiPcd) {
- LocalTokenNumber = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];
- Database = (UINT8 *) &mPcdDatabase->PeiDb;
+ if (IsPeiDb) {
+ LocalTokenNumber = *((UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx);
+ Database = (UINT8 *) mPcdDatabase.PeiDb;
} else {
- LocalTokenNumber = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable[LocalTokenNumberTableIdx - PEI_LOCAL_TOKEN_NUMBER];
- Database = (UINT8 *) &mPcdDatabase->DxeDb;
+ LocalTokenNumber = *((UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx);
+ Database = (UINT8 *) mPcdDatabase.DxeDb;
}
ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0);
@@ -1224,9 +1577,9 @@ GetSizeTableIndex (
SKU_ID *SkuIdTable;
if (IsPeiDb) {
- LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;
+ LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset);
} else {
- LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
+ LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);
}
SizeTableIdx = 0;
@@ -1241,11 +1594,12 @@ GetSizeTableIndex (
//
if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {
//
- // We have only one entry for VPD enabled PCD entry:
+ // We have only two entry for VPD enabled PCD entry:
// 1) MAX Size.
- // We consider current size is equal to MAX size.
+ // 2) Current Size
+ // Current size is equal to MAX size.
//
- SizeTableIdx++;
+ SizeTableIdx += 2;
} else {
if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {
//
@@ -1297,16 +1651,16 @@ GetPtrTypeSize (
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
- IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
+ IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < mPeiLocalTokenCount + 1);
if (IsPeiDb) {
- LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;
- SizeTable = mPcdDatabase->PeiDb.Init.SizeTable;
+ LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset);
+ SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->SizeTableOffset);
} else {
- LocalTokenNumberTableIdx -= PEI_LOCAL_TOKEN_NUMBER;
- LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
- SizeTable = mPcdDatabase->DxeDb.Init.SizeTable;
+ LocalTokenNumberTableIdx -= mPeiLocalTokenCount;
+ LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);
+ SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->SizeTableOffset);
}
LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx];
@@ -1322,8 +1676,9 @@ GetPtrTypeSize (
//
if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {
//
- // We have only one entry for VPD enabled PCD entry:
+ // We have only two entry for VPD enabled PCD entry:
// 1) MAX Size.
+ // 2) Current Size
// We consider current size is equal to MAX size.
//
return *MaxSize;
@@ -1343,7 +1698,7 @@ GetPtrTypeSize (
//
SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, IsPeiDb);
for (Index = 0; Index < SkuIdTable[0]; Index++) {
- if (SkuIdTable[1 + Index] == mPcdDatabase->PeiDb.Init.SystemSkuId) {
+ if (SkuIdTable[1 + Index] == mPcdDatabase.PeiDb->SystemSkuId) {
return SizeTable[SizeTableIdx + 1 + Index];
}
}
@@ -1382,15 +1737,15 @@ SetPtrTypeSize (
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
//
- IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
+ IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < mPeiLocalTokenCount + 1);
if (IsPeiDb) {
- LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;
- SizeTable = mPcdDatabase->PeiDb.Init.SizeTable;
+ LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset);
+ SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->SizeTableOffset);
} else {
- LocalTokenNumberTableIdx -= PEI_LOCAL_TOKEN_NUMBER;
- LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
- SizeTable = mPcdDatabase->DxeDb.Init.SizeTable;
+ LocalTokenNumberTableIdx -= mPeiLocalTokenCount;
+ LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);
+ SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->SizeTableOffset);
}
LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx];
@@ -1433,7 +1788,7 @@ SetPtrTypeSize (
//
SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, IsPeiDb);
for (Index = 0; Index < SkuIdTable[0]; Index++) {
- if (SkuIdTable[1 + Index] == mPcdDatabase->PeiDb.Init.SystemSkuId) {
+ if (SkuIdTable[1 + Index] == mPcdDatabase.PeiDb->SystemSkuId) {
SizeTable[SizeTableIdx + 1 + Index] = (SIZE_INFO) *CurrentSize;
return TRUE;
}
diff --git a/MdeModulePkg/Universal/PCD/Dxe/Service.h b/MdeModulePkg/Universal/PCD/Dxe/Service.h
index c15edd3e8..55717dc98 100644
--- a/MdeModulePkg/Universal/PCD/Dxe/Service.h
+++ b/MdeModulePkg/Universal/PCD/Dxe/Service.h
@@ -1,7 +1,7 @@
/** @file
Private functions used by PCD DXE driver.
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -17,8 +17,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <PiDxe.h>
#include <Guid/PcdDataBaseHobGuid.h>
+#include <Guid/PcdDataBaseSignatureGuid.h>
#include <Protocol/Pcd.h>
#include <Protocol/PiPcd.h>
+#include <Protocol/PcdInfo.h>
+#include <Protocol/PiPcdInfo.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiLib.h>
@@ -34,7 +37,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
// Please make sure the PCD Serivce DXE Version is consistent with
// the version of the generated DXE PCD Database by build tool.
//
-#define PCD_SERVICE_DXE_VERSION 2
+#define PCD_SERVICE_DXE_VERSION 4
//
// PCD_DXE_SERVICE_DRIVER_VERSION is defined in Autogen.h.
@@ -43,6 +46,61 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#error "Please make sure the version of PCD DXE Service and the generated PCD DXE Database match."
#endif
+/**
+ Retrieve additional information associated with a PCD token in the default token space.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully.
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+EFIAPI
+DxeGetPcdInfoGetInfo (
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ );
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully.
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+EFIAPI
+DxeGetPcdInfoGetInfoEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ );
+
+/**
+ Retrieve the currently set SKU Id.
+
+ @return The currently set SKU Id. If the platform has not set at a SKU Id, then the
+ default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU
+ Id is returned.
+**/
+UINTN
+EFIAPI
+DxeGetPcdInfoGetSku (
+ VOID
+ );
+
//
// Protocol Interface function declaration.
//
@@ -757,6 +815,27 @@ typedef struct {
//
/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+DxeGetPcdInfo (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ );
+
+/**
Wrapper function for setting non-pointer type value for a PCD entry.
@param TokenNumber Pcd token number autogenerated by build tools.
@@ -995,16 +1074,16 @@ BuildPcdDxeDataBase (
);
/**
- Get local token number according to dynamic-ex PCD's {token space guid:token number}
+ Get Token Number according to dynamic-ex PCD's {token space guid:token number}
A dynamic-ex type PCD, developer must provide pair of token space guid: token number
in DEC file. PCD database maintain a mapping table that translate pair of {token
- space guid: token number} to local token number.
+ space guid: token number} to Token Number.
@param Guid Token space guid for dynamic-ex PCD entry.
@param ExTokenNumber Dynamic-ex PCD token number.
- @return local token number for dynamic-ex PCD.
+ @return Token Number for dynamic-ex PCD.
**/
UINTN
@@ -1079,9 +1158,24 @@ SetPtrTypeSize (
IN OUT UINTN *CurrentSize
);
-extern PCD_DATABASE * mPcdDatabase;
+extern PCD_DATABASE mPcdDatabase;
+
+extern UINT32 mPcdTotalTokenCount;
+extern UINT32 mPeiLocalTokenCount;
+extern UINT32 mDxeLocalTokenCount;
+extern UINT32 mPeiNexTokenCount;
+extern UINT32 mDxeNexTokenCount;
+extern UINT32 mPeiExMapppingTableSize;
+extern UINT32 mDxeExMapppingTableSize;
+extern UINT32 mPeiGuidTableSize;
+extern UINT32 mDxeGuidTableSize;
+
+extern BOOLEAN mPeiExMapTableEmpty;
+extern BOOLEAN mDxeExMapTableEmpty;
+extern BOOLEAN mPeiDatabaseEmpty;
-extern DXE_PCD_DATABASE_INIT gDXEPcdDbInit;
+extern EFI_GUID **TmpTokenSpaceBuffer;
+extern UINTN TmpTokenSpaceBufferCount;
extern EFI_LOCK mPcdDatabaseLock;
diff --git a/MdeModulePkg/Universal/PCD/Pei/Pcd.c b/MdeModulePkg/Universal/PCD/Pei/Pcd.c
index 5ab8e1287..91e94e263 100644
--- a/MdeModulePkg/Universal/PCD/Pei/Pcd.c
+++ b/MdeModulePkg/Universal/PCD/Pei/Pcd.c
@@ -1,7 +1,7 @@
/** @file
All Pcd Ppi services are implemented here.
-Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -83,6 +83,25 @@ EFI_PEI_PCD_PPI mEfiPcdPpiInstance = {
PeiPcdGetNextTokenSpace
};
+///
+/// Instance of GET_PCD_INFO_PPI protocol is EDKII native implementation.
+/// This protocol instance support dynamic and dynamicEx type PCDs.
+///
+GET_PCD_INFO_PPI mGetPcdInfoInstance = {
+ PeiGetPcdInfoGetInfo,
+ PeiGetPcdInfoGetInfoEx,
+ PeiGetPcdInfoGetSku
+};
+
+///
+/// Instance of EFI_GET_PCD_INFO_PPI which is defined in PI 1.2.1 Vol 3.
+/// This PPI instance only support dyanmicEx type PCD.
+///
+EFI_GET_PCD_INFO_PPI mEfiGetPcdInfoInstance = {
+ PeiGetPcdInfoGetInfoEx,
+ PeiGetPcdInfoGetSku
+};
+
EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
{
EFI_PEI_PPI_DESCRIPTOR_PPI,
@@ -96,6 +115,19 @@ EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
}
};
+EFI_PEI_PPI_DESCRIPTOR mPpiList2[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI,
+ &gGetPcdInfoPpiGuid,
+ &mGetPcdInfoInstance
+ },
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiGetPcdInfoPpiGuid,
+ &mEfiGetPcdInfoInstance
+ }
+};
+
/**
Main entry for PCD PEIM driver.
@@ -114,20 +146,96 @@ PcdPeimInit (
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
- EFI_STATUS Status;
-
- BuildPcdDatabase ();
+ EFI_STATUS Status;
+ PEI_PCD_DATABASE *DataBase;
+
+ DataBase = BuildPcdDatabase (FileHandle);
//
// Install PCD_PPI and EFI_PEI_PCD_PPI.
//
Status = PeiServicesInstallPpi (&mPpiList[0]);
ASSERT_EFI_ERROR (Status);
-
+
+ //
+ // Only install PcdInfo PPI when PCD info content is present.
+ //
+ if (DataBase->PcdNameTableOffset != 0) {
+ //
+ // Install GET_PCD_INFO_PPI and EFI_GET_PCD_INFO_PPI.
+ //
+ Status = PeiServicesInstallPpi (&mPpiList2[0]);
+ ASSERT_EFI_ERROR (Status);
+ }
+
return Status;
}
/**
+ Retrieve additional information associated with a PCD token in the default token space.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully.
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+EFIAPI
+PeiGetPcdInfoGetInfo (
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ )
+{
+ return PeiGetPcdInfo (NULL, TokenNumber, PcdInfo);
+}
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully.
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+EFIAPI
+PeiGetPcdInfoGetInfoEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ )
+{
+ return PeiGetPcdInfo (Guid, TokenNumber, PcdInfo);
+}
+
+/**
+ Retrieve the currently set SKU Id.
+
+ @return The currently set SKU Id. If the platform has not set at a SKU Id, then the
+ default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU
+ Id is returned.
+**/
+UINTN
+EFIAPI
+PeiGetPcdInfoGetSku (
+ VOID
+ )
+{
+ return GetPcdDatabase()->SystemSkuId;
+}
+
+/**
Sets the SKU value for subsequent calls to set or get PCD token values.
SetSku() sets the SKU Id to be used for subsequent calls to set or get PCD values.
@@ -155,7 +263,7 @@ PeiPcdSetSku (
)
{
- GetPcdDatabase()->Init.SystemSkuId = (SKU_ID) SkuId;
+ GetPcdDatabase()->SystemSkuId = (SKU_ID) SkuId;
return;
}
@@ -304,8 +412,10 @@ PeiPcdGetSize (
PEI_PCD_DATABASE *PeiPcdDb;
UINTN Size;
UINTN MaxSize;
+ UINT32 LocalTokenCount;
- PeiPcdDb = GetPcdDatabase ();
+ PeiPcdDb = GetPcdDatabase ();
+ LocalTokenCount = PeiPcdDb->LocalTokenCount;
//
// TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
// We have to decrement TokenNumber by 1 to make it usable
@@ -316,9 +426,9 @@ PeiPcdGetSize (
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
- ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
+ ASSERT (TokenNumber + 1 < (LocalTokenCount + 1));
- Size = (PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber] & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;
+ Size = (*((UINT32 *)((UINT8 *)PeiPcdDb + PeiPcdDb->LocalTokenNumberTableOffset) + TokenNumber) & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;
if (Size == 0) {
//
@@ -926,10 +1036,8 @@ PcdUnRegisterCallBackOnSet (
is being made to retrieve tokens from the default token space.
@param[in, out] TokenNumber A pointer to the PCD token number to use to find the subsequent token number.
- @retval EFI_SUCCESS The PCD service has retrieved the next valid token number.
- Or the input token number is already the last valid token number in the PCD database.
- In the later case, *TokenNumber is updated with the value of 0.
- @retval EFI_NOT_FOUND If this input token number and token namespace does not exist on the platform.
+ @retval EFI_SUCCESS The PCD service has retrieved the next valid token number.
+ @retval EFI_NOT_FOUND The PCD service could not find data from the requested token number.
**/
EFI_STATUS
@@ -942,55 +1050,56 @@ PeiPcdGetNextToken (
UINTN GuidTableIdx;
PEI_PCD_DATABASE *PeiPcdDb;
EFI_GUID *MatchGuid;
+ EFI_GUID *GuidTable;
DYNAMICEX_MAPPING *ExMapTable;
UINTN Index;
BOOLEAN Found;
BOOLEAN PeiExMapTableEmpty;
+ UINTN PeiNexTokenNumber;
if (!FeaturePcdGet (PcdPeiFullPcdDatabaseEnable)) {
return EFI_UNSUPPORTED;
}
- PeiExMapTableEmpty = PEI_EXMAP_TABLE_EMPTY;
+ PeiPcdDb = GetPcdDatabase ();
+ PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount;
+ GuidTable = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset);
+ if (PeiPcdDb->ExTokenCount == 0) {
+ PeiExMapTableEmpty = TRUE;
+ } else {
+ PeiExMapTableEmpty = FALSE;
+ }
if (Guid == NULL) {
- if (*TokenNumber > PEI_NEX_TOKEN_NUMBER) {
+ if (*TokenNumber > PeiNexTokenNumber) {
return EFI_NOT_FOUND;
}
(*TokenNumber)++;
- if (*TokenNumber > PEI_NEX_TOKEN_NUMBER) {
+ if (*TokenNumber > PeiNexTokenNumber) {
*TokenNumber = PCD_INVALID_TOKEN_NUMBER;
+ return EFI_NOT_FOUND;
}
return EFI_SUCCESS;
} else {
if (PeiExMapTableEmpty) {
- *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
- return EFI_SUCCESS;
+ return EFI_NOT_FOUND;
}
-
- //
- // Assume PCD Database AutoGen tool is sorting the ExMap based on the following order
- // 1) ExGuid
- // 2) ExTokenNumber
- //
- PeiPcdDb = GetPcdDatabase ();
-
- MatchGuid = ScanGuid (PeiPcdDb->Init.GuidTable, sizeof(PeiPcdDb->Init.GuidTable), Guid);
+
+ MatchGuid = ScanGuid (GuidTable, PeiPcdDb->GuidTableCount * sizeof(EFI_GUID), Guid);
if (MatchGuid == NULL) {
- *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
return EFI_NOT_FOUND;
}
- GuidTableIdx = MatchGuid - PeiPcdDb->Init.GuidTable;
+ GuidTableIdx = MatchGuid - GuidTable;
- ExMapTable = PeiPcdDb->Init.ExMapTable;
+ ExMapTable = (DYNAMICEX_MAPPING *)((UINT8 *)PeiPcdDb + PeiPcdDb->ExMapTableOffset);
Found = FALSE;
//
// Locate the GUID in ExMapTable first.
//
- for (Index = 0; Index < PEI_EXMAPPING_TABLE_SIZE; Index++) {
+ for (Index = 0; Index < PeiPcdDb->ExTokenCount; Index++) {
if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {
Found = TRUE;
break;
@@ -1003,26 +1112,28 @@ PeiPcdGetNextToken (
return EFI_SUCCESS;
}
- for ( ; Index < PEI_EXMAPPING_TABLE_SIZE; Index++) {
+ for ( ; Index < PeiPcdDb->ExTokenCount; Index++) {
if (ExMapTable[Index].ExTokenNumber == *TokenNumber) {
- Index++;
- if (Index == PEI_EXMAPPING_TABLE_SIZE) {
- //
- // Exceed the length of ExMap Table
- //
- *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
- return EFI_SUCCESS;
- }
- if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {
- *TokenNumber = ExMapTable[Index].ExTokenNumber;
- return EFI_SUCCESS;
- } else {
- *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
- return EFI_SUCCESS;
- }
+ break;
+ }
+ }
+
+ while (Index < PeiPcdDb->ExTokenCount) {
+ Index++;
+ if (Index == PeiPcdDb->ExTokenCount) {
+ //
+ // Exceed the length of ExMap Table
+ //
+ *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
+ return EFI_NOT_FOUND;
+ } else if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {
+ //
+ // Found the next match
+ //
+ *TokenNumber = ExMapTable[Index].ExTokenNumber;
+ return EFI_SUCCESS;
}
}
- return EFI_NOT_FOUND;
}
}
@@ -1032,22 +1143,17 @@ PeiPcdGetNextToken (
/**
Retrieves the next valid PCD token namespace for a given namespace.
- @param[in, out] Guid An indirect pointer to EFI_GUID. On input it designates
- a known token namespace from which the search will start. On output,
- it designates the next valid token namespace on the platform. If the input
- token namespace does not exist on the platform, an error is returned and
- the value of *Guid is undefined. If *Guid is NULL, then the GUID of the
- first token space of the current platform is assigned to *Guid the function
- return EFI_SUCCESS. If *Guid is NULL and there is no namespace exist in
- the platform other than the default (NULL) tokennamespace, *Guid is unchanged
- and the function return EFI_SUCCESS. If this input token namespace is the last
- namespace on the platform, *Guid will be assigned to NULL and the function return
- EFI_SUCCESS.
-
- @retval EFI_SUCCESS The PCD service retrieved the next valid token space Guid.
- Or the input token space Guid is already the last valid token space Guid
- in the PCD database. In the later case, *Guid is updated with the value of NULL.
- @retval EFI_NOT_FOUND If the input token namespace does not exist on the platform.
+ Gets the next valid token namespace for a given namespace. This is useful to traverse the valid
+ token namespaces on a platform.
+
+ @param[in, out] Guid An indirect pointer to EFI_GUID. On input it designates a known token
+ namespace from which the search will start. On output, it designates the next valid
+ token namespace on the platform. If *Guid is NULL, then the GUID of the first token
+ space of the current platform is returned. If the search cannot locate the next valid
+ token namespace, an error is returned and the value of *Guid is undefined.
+
+ @retval EFI_SUCCESS The PCD service retrieved the value requested.
+ @retval EFI_NOT_FOUND The PCD service could not find the next valid token namespace.
**/
EFI_STATUS
@@ -1061,8 +1167,10 @@ PeiPcdGetNextTokenSpace (
PEI_PCD_DATABASE *PeiPcdDb;
DYNAMICEX_MAPPING *ExMapTable;
UINTN Index;
+ UINTN Index2;
BOOLEAN Found;
BOOLEAN PeiExMapTableEmpty;
+ EFI_GUID *GuidTable;
if (!FeaturePcdGet (PcdPeiFullPcdDatabaseEnable)) {
return EFI_UNSUPPORTED;
@@ -1070,43 +1178,39 @@ PeiPcdGetNextTokenSpace (
ASSERT (Guid != NULL);
- PeiExMapTableEmpty = PEI_EXMAP_TABLE_EMPTY;
+ PeiPcdDb = GetPcdDatabase ();
+ if (PeiPcdDb->ExTokenCount == 0) {
+ PeiExMapTableEmpty = TRUE;
+ } else {
+ PeiExMapTableEmpty = FALSE;
+ }
+
if (PeiExMapTableEmpty) {
- if (*Guid != NULL) {
- return EFI_NOT_FOUND;
- } else {
- return EFI_SUCCESS;
- }
+ return EFI_NOT_FOUND;
}
- //
- // Assume PCD Database AutoGen tool is sorting the ExMap based on the following order
- // 1) ExGuid
- // 2) ExTokenNumber
- //
- PeiPcdDb = GetPcdDatabase ();
-
- ExMapTable = PeiPcdDb->Init.ExMapTable;
-
+ ExMapTable = (DYNAMICEX_MAPPING *)((UINT8 *)PeiPcdDb + PeiPcdDb->ExMapTableOffset);
+ GuidTable = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset);
+
if (*Guid == NULL) {
//
// return the first Token Space Guid.
//
- *Guid = &PeiPcdDb->Init.GuidTable[ExMapTable[0].ExGuidIndex];
+ *Guid = GuidTable + ExMapTable[0].ExGuidIndex;
return EFI_SUCCESS;
}
- MatchGuid = ScanGuid (PeiPcdDb->Init.GuidTable, sizeof(PeiPcdDb->Init.GuidTable), *Guid);
+ MatchGuid = ScanGuid (GuidTable, PeiPcdDb->GuidTableCount * sizeof(GuidTable[0]), *Guid);
if (MatchGuid == NULL) {
return EFI_NOT_FOUND;
}
- GuidTableIdx = MatchGuid - PeiPcdDb->Init.GuidTable;
+ GuidTableIdx = MatchGuid - GuidTable;
Found = FALSE;
- for (Index = 0; Index < PEI_EXMAPPING_TABLE_SIZE; Index++) {
+ for (Index = 0; Index < PeiPcdDb->ExTokenCount; Index++) {
if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {
Found = TRUE;
break;
@@ -1115,14 +1219,25 @@ PeiPcdGetNextTokenSpace (
if (Found) {
Index++;
- for ( ; Index < PEI_EXMAPPING_TABLE_SIZE; Index++ ) {
- if (ExMapTable[Index].ExGuidIndex != GuidTableIdx ) {
- *Guid = &PeiPcdDb->Init.GuidTable[ExMapTable[Index].ExGuidIndex];
- return EFI_SUCCESS;
+ for ( ; Index < PeiPcdDb->ExTokenCount; Index++ ) {
+ if (ExMapTable[Index].ExGuidIndex != GuidTableIdx) {
+ Found = FALSE;
+ for (Index2 = 0 ; Index2 < Index; Index2++) {
+ if (ExMapTable[Index2].ExGuidIndex == ExMapTable[Index].ExGuidIndex) {
+ //
+ // This token namespace should have been found and output at preceding getting.
+ //
+ Found = TRUE;
+ break;
+ }
+ }
+ if (!Found) {
+ *Guid = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset) + ExMapTable[Index].ExGuidIndex;
+ return EFI_SUCCESS;
+ }
}
}
*Guid = NULL;
- return EFI_SUCCESS;
}
return EFI_NOT_FOUND;
@@ -1132,7 +1247,7 @@ PeiPcdGetNextTokenSpace (
/**
Get PCD value's size for POINTER type PCD.
- The POINTER type PCD's value will be stored into a buffer in specificed size.
+ The POINTER type PCD's value will be stored into a buffer in specified size.
The max size of this PCD's value is described in PCD's definition in DEC file.
@param LocalTokenNumberTableIdx Index of PCD token number in PCD token table
@@ -1157,11 +1272,11 @@ GetPtrTypeSize (
SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database);
- LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];
+ LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx);
ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);
- SizeTable = Database->Init.SizeTable;
+ SizeTable = (SIZE_INFO *)((UINT8 *)Database + Database->SizeTableOffset);
*MaxSize = SizeTable[SizeTableIdx];
//
@@ -1170,8 +1285,9 @@ GetPtrTypeSize (
//
if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {
//
- // We have only one entry for VPD enabled PCD entry:
+ // We have only two entry for VPD enabled PCD entry:
// 1) MAX Size.
+ // 2) Current Size
// We consider current size is equal to MAX size.
//
return *MaxSize;
@@ -1191,7 +1307,7 @@ GetPtrTypeSize (
//
SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, Database);
for (Index = 0; Index < SkuIdTable[0]; Index++) {
- if (SkuIdTable[1 + Index] == Database->Init.SystemSkuId) {
+ if (SkuIdTable[1 + Index] == Database->SystemSkuId) {
return SizeTable[SizeTableIdx + 1 + Index];
}
}
@@ -1203,7 +1319,7 @@ GetPtrTypeSize (
/**
Set PCD value's size for POINTER type PCD.
- The POINTER type PCD's value will be stored into a buffer in specificed size.
+ The POINTER type PCD's value will be stored into a buffer in specified size.
The max size of this PCD's value is described in PCD's definition in DEC file.
@param LocalTokenNumberTableIdx Index of PCD token number in PCD token table
@@ -1230,11 +1346,11 @@ SetPtrTypeSize (
SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database);
- LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];
+ LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx);
ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);
-
- SizeTable = Database->Init.SizeTable;
+
+ SizeTable = (SIZE_INFO *)((UINT8 *)Database + Database->SizeTableOffset);
MaxSize = SizeTable[SizeTableIdx];
//
@@ -1270,7 +1386,7 @@ SetPtrTypeSize (
//
SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, Database);
for (Index = 0; Index < SkuIdTable[0]; Index++) {
- if (SkuIdTable[1 + Index] == Database->Init.SystemSkuId) {
+ if (SkuIdTable[1 + Index] == Database->SystemSkuId) {
SizeTable[SizeTableIdx + 1 + Index] = (SIZE_INFO) *CurrentSize;
return TRUE;
}
diff --git a/MdeModulePkg/Universal/PCD/Pei/Pcd.inf b/MdeModulePkg/Universal/PCD/Pei/Pcd.inf
index 20e442082..357f047ff 100644
--- a/MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+++ b/MdeModulePkg/Universal/PCD/Pei/Pcd.inf
@@ -1,6 +1,7 @@
## @file
# PCD PEIM produces PCD database to manage all dynamic PCD in PEI phase and install Pcd Ppi service.
#
+# This version PCD PEIM depends on the external PCD database binary file, not built in PCD data base.
# There are two PCD PPIs as follows:
# 1) PCD_PPI
# It is EDKII implementation which support Dynamic/DynamicEx Pcds.
@@ -8,6 +9,10 @@
# It is defined by PI specification 1.2, Vol 3 which only support dynamicEx
# type Pcd.
# For dynamicEx type PCD, it is compatible between PCD_PPI and EFI_PEI_PCD_PPI.
+# PCD PEIM driver will produce above two PPIs at same time.
+#
+# PCD database is generated as the separate binary image at build time. The binary image
+# will be intergrated into Firmware volume together with PCD driver.
#
# ////////////////////////////////////////////////////////////////////////////////
# // //
@@ -58,7 +63,7 @@
# b) Variable Storage:
# - The PCD value is stored in variable area.
# - As default storage type, this type PCD could be used for PEI/DXE driver
-# communication. But beside it, this type PCD could alsp be used to store
+# communication. But beside it, this type PCD could also be used to store
# the value associate with a HII setting via variable interface.
# - In PEI phase, the PCD value could only be got but can not be set due
# to variable area is readonly.
@@ -89,12 +94,12 @@
# PCD information used in PEI phase or use in both PEI/DXE phase. And DXE PCD
# database contains all PCDs used in PEI/DXE phase in memory.
#
-# Build tool will generate PCD database into some C structure and variable for
+# Build tool will generate PCD database into the separate binary file for
# PEI/DXE PCD driver according to dynamic PCD section in platform DSC file.
#
# 3.1 PcdPeim and PcdDxe
# PEI PCD database is maintained by PcdPeim driver run from flash. PcdPeim driver
-# build guid hob in temporary memory and copy auto-generated C structure
+# build guid hob in temporary memory and copy the binary data base from flash
# to temporary memory for PEI PCD database.
# DXE PCD database is maintained by PcdDxe driver.At entry point of PcdDxe driver,
# a new PCD database is allocated in boot-time memory which including all
@@ -180,8 +185,10 @@
# Based on local token number, PCD driver could fast determine PCD type, value
# type and get PCD entry from PCD database.
#
-# 3.3 PCD Database C structure.
-# PCD Database C structure is generated by build tools in PCD driver's autogen.h/
+# 3.3 PCD Database binary file
+# PCD Database binary file will be created at build time as the standalone binary image.
+# To understand the binary image layout, PCD Database C structure is still generated
+# as comments by build tools in PCD driver's autogen.h/
# autogen.c file. In generated C structure, following information is stored:
# - ExMapTable: This table is used translate a binary dynamicex type PCD's
# "tokenguid + token" to local token number.
@@ -190,7 +197,7 @@
# token number" as array index to get PCD entry's offset fastly.
# - SizeTable: This table stores the size information for all PCD entry.
# - GuidTable: This table stores guid value for DynamicEx's token space,
-# HII type PCD's variable.
+# HII type PCD's variable GUID.
# - SkuIdTable: TBD
# - SystemSkuId: TBD
# - PCD value structure:
@@ -271,7 +278,7 @@
# - Variable GUID for HII type PCD
# - Token space GUID for dynamicex type PCD
#
-# Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
@@ -288,7 +295,7 @@
BASE_NAME = PcdPeim
FILE_GUID = 9B3ADA4F-AE56-4c24-8DEA-F03B7558AE50
MODULE_TYPE = PEIM
- VERSION_STRING = 1.0
+ VERSION_STRING = 4.0
PCD_IS_DRIVER = PEI_PCD_DRIVER
ENTRY_POINT = PcdPeimInit
@@ -315,22 +322,27 @@
BaseLib
PeimEntryPoint
DebugLib
+ MemoryAllocationLib
[Guids]
- gPcdDataBaseHobGuid ## PRODUCES ## Hob
- gPcdDataBaseHobGuid ## CONSUMES ## Hob
+ ## PRODUCES ## HOB
+ ## SOMETIMES_CONSUMES ## HOB
+ gPcdDataBaseHobGuid
+ gPcdDataBaseSignatureGuid ## CONSUMES ## UNDEFINED # PCD database signature GUID.
[Ppis]
- gEfiPeiReadOnlyVariable2PpiGuid ## CONSUMES
+ gEfiPeiReadOnlyVariable2PpiGuid ## SOMETIMES_CONSUMES
gPcdPpiGuid ## PRODUCES
gEfiPeiPcdPpiGuid ## PRODUCES
-
+ gGetPcdInfoPpiGuid ## SOMETIMES_PRODUCES
+ gEfiGetPcdInfoPpiGuid ## SOMETIMES_PRODUCES
+
[FeaturePcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdPeiFullPcdDatabaseEnable
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPeiFullPcdDatabaseEnable ## CONSUMES
[Pcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress
- gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPcdCallBackNumberPerPcdEntry || gEfiMdeModulePkgTokenSpaceGuid.PcdPeiFullPcdDatabaseEnable
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress ## SOMETIMES_CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPcdCallBackNumberPerPcdEntry || gEfiMdeModulePkgTokenSpaceGuid.PcdPeiFullPcdDatabaseEnable ## SOMETIMES_CONSUMES
[Depex]
TRUE
diff --git a/MdeModulePkg/Universal/PCD/Pei/Service.c b/MdeModulePkg/Universal/PCD/Pei/Service.c
index e5d5f0c20..4fb8b4a68 100644
--- a/MdeModulePkg/Universal/PCD/Pei/Service.c
+++ b/MdeModulePkg/Universal/PCD/Pei/Service.c
@@ -2,7 +2,7 @@
The driver internal functions are implmented here.
They build Pei PCD database, and provide access service to PCD database.
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -16,6 +16,281 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "Service.h"
/**
+ Get Local Token Number by Token Number.
+
+ @param[in] Database PCD database.
+ @param[in] TokenNumber The PCD token number.
+
+ @return Local Token Number.
+**/
+UINT32
+GetLocalTokenNumber (
+ IN PEI_PCD_DATABASE *Database,
+ IN UINTN TokenNumber
+ )
+{
+ UINT32 LocalTokenNumber;
+ UINTN Size;
+ UINTN MaxSize;
+
+ //
+ // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
+ // We have to decrement TokenNumber by 1 to make it usable
+ // as the array index.
+ //
+ TokenNumber--;
+
+ LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + TokenNumber);
+
+ Size = (LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;
+
+ if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
+ if (Size == 0) {
+ GetPtrTypeSize (TokenNumber, &MaxSize, Database);
+ } else {
+ MaxSize = Size;
+ }
+ LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);
+ }
+
+ return LocalTokenNumber;
+}
+
+/**
+ Get PCD type by Local Token Number.
+
+ @param[in] LocalTokenNumber The PCD local token number.
+
+ @return PCD type.
+**/
+EFI_PCD_TYPE
+GetPcdType (
+ IN UINT32 LocalTokenNumber
+ )
+{
+ switch (LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) {
+ case PCD_DATUM_TYPE_POINTER:
+ return EFI_PCD_TYPE_PTR;
+ case PCD_DATUM_TYPE_UINT8:
+ if ((LocalTokenNumber & PCD_DATUM_TYPE_UINT8_BOOLEAN) == PCD_DATUM_TYPE_UINT8_BOOLEAN) {
+ return EFI_PCD_TYPE_BOOL;
+ } else {
+ return EFI_PCD_TYPE_8;
+ }
+ case PCD_DATUM_TYPE_UINT16:
+ return EFI_PCD_TYPE_16;
+ case PCD_DATUM_TYPE_UINT32:
+ return EFI_PCD_TYPE_32;
+ case PCD_DATUM_TYPE_UINT64:
+ return EFI_PCD_TYPE_64;
+ default:
+ ASSERT (FALSE);
+ return EFI_PCD_TYPE_8;
+ }
+}
+
+/**
+ Get PCD name.
+
+ @param[in] OnlyTokenSpaceName If TRUE, only need to get the TokenSpaceCName.
+ If FALSE, need to get the full PCD name.
+ @param[in] Database PCD database.
+ @param[in] TokenNumber The PCD token number.
+
+ @return The TokenSpaceCName or full PCD name.
+**/
+CHAR8 *
+GetPcdName (
+ IN BOOLEAN OnlyTokenSpaceName,
+ IN PEI_PCD_DATABASE *Database,
+ IN UINTN TokenNumber
+ )
+{
+ UINT8 *StringTable;
+ PCD_NAME_INDEX *PcdNameIndex;
+ CHAR8 *TokenSpaceName;
+ CHAR8 *PcdName;
+ CHAR8 *Name;
+
+ //
+ // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
+ // We have to decrement TokenNumber by 1 to make it usable
+ // as the array index.
+ //
+ TokenNumber--;
+
+ StringTable = (UINT8 *) Database + Database->StringTableOffset;
+
+ //
+ // Get the PCD name index.
+ //
+ PcdNameIndex = (PCD_NAME_INDEX *)((UINT8 *) Database + Database->PcdNameTableOffset) + TokenNumber;
+ TokenSpaceName = (CHAR8 *)&StringTable[PcdNameIndex->TokenSpaceCNameIndex];
+ PcdName = (CHAR8 *)&StringTable[PcdNameIndex->PcdCNameIndex];
+
+ if (OnlyTokenSpaceName) {
+ //
+ // Only need to get the TokenSpaceCName.
+ //
+ Name = AllocateCopyPool (AsciiStrSize (TokenSpaceName), TokenSpaceName);
+ } else {
+ //
+ // Need to get the full PCD name.
+ //
+ Name = AllocateZeroPool (AsciiStrSize (TokenSpaceName) + AsciiStrSize (PcdName));
+ ASSERT (Name != NULL);
+ //
+ // Catenate TokenSpaceCName and PcdCName with a '.' to form the full PCD name.
+ //
+ AsciiStrCat (Name, TokenSpaceName);
+ Name[AsciiStrSize (TokenSpaceName) - sizeof (CHAR8)] = '.';
+ AsciiStrCat (Name, PcdName);
+ }
+
+ return Name;
+}
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] Database PCD database.
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+ExGetPcdInfo (
+ IN PEI_PCD_DATABASE *Database,
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ )
+{
+ UINTN GuidTableIdx;
+ EFI_GUID *MatchGuid;
+ EFI_GUID *GuidTable;
+ DYNAMICEX_MAPPING *ExMapTable;
+ UINTN Index;
+ UINT32 LocalTokenNumber;
+
+ GuidTable = (EFI_GUID *)((UINT8 *)Database + Database->GuidTableOffset);
+ MatchGuid = ScanGuid (GuidTable, Database->GuidTableCount * sizeof(EFI_GUID), Guid);
+
+ if (MatchGuid == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ GuidTableIdx = MatchGuid - GuidTable;
+
+ ExMapTable = (DYNAMICEX_MAPPING *)((UINT8 *)Database + Database->ExMapTableOffset);
+
+ //
+ // Find the PCD by GuidTableIdx and ExTokenNumber in ExMapTable.
+ //
+ for (Index = 0; Index < Database->ExTokenCount; Index++) {
+ if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {
+ if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {
+ //
+ // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,
+ // PcdSize to 0 and PcdName to the null-terminated ASCII string
+ // associated with the token's namespace Guid.
+ //
+ PcdInfo->PcdType = EFI_PCD_TYPE_8;
+ PcdInfo->PcdSize = 0;
+ //
+ // Here use one representative in the token space to get the TokenSpaceCName.
+ //
+ PcdInfo->PcdName = GetPcdName (TRUE, Database, ExMapTable[Index].TokenNumber);
+ return EFI_SUCCESS;
+ } else if (ExMapTable[Index].ExTokenNumber == TokenNumber) {
+ PcdInfo->PcdSize = PeiPcdGetSize (ExMapTable[Index].TokenNumber);
+ LocalTokenNumber = GetLocalTokenNumber (Database, ExMapTable[Index].TokenNumber);
+ PcdInfo->PcdType = GetPcdType (LocalTokenNumber);
+ PcdInfo->PcdName = GetPcdName (FALSE, Database, ExMapTable[Index].TokenNumber);
+ return EFI_SUCCESS;
+ }
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully.
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+PeiGetPcdInfo (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ )
+{
+ PEI_PCD_DATABASE *PeiPcdDb;
+ BOOLEAN PeiExMapTableEmpty;
+ UINTN PeiNexTokenNumber;
+ UINT32 LocalTokenNumber;
+
+ ASSERT (PcdInfo != NULL);
+
+ PeiPcdDb = GetPcdDatabase ();
+ PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount;
+
+ if (PeiPcdDb->ExTokenCount == 0) {
+ PeiExMapTableEmpty = TRUE;
+ } else {
+ PeiExMapTableEmpty = FALSE;
+ }
+
+ if (Guid == NULL) {
+ if (TokenNumber > PeiNexTokenNumber) {
+ return EFI_NOT_FOUND;
+ } else if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {
+ //
+ // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,
+ // PcdSize to 0 and PcdName to NULL for default Token Space.
+ //
+ PcdInfo->PcdType = EFI_PCD_TYPE_8;
+ PcdInfo->PcdSize = 0;
+ PcdInfo->PcdName = NULL;
+ } else {
+ PcdInfo->PcdSize = PeiPcdGetSize (TokenNumber);
+ LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber);
+ PcdInfo->PcdType = GetPcdType (LocalTokenNumber);
+ PcdInfo->PcdName = GetPcdName (FALSE, PeiPcdDb, TokenNumber);
+ }
+ return EFI_SUCCESS;
+ } else {
+ if (PeiExMapTableEmpty) {
+ return EFI_NOT_FOUND;
+ }
+ return ExGetPcdInfo (
+ PeiPcdDb,
+ Guid,
+ TokenNumber,
+ PcdInfo
+ );
+ }
+}
+
+/**
The function registers the CallBackOnSet fucntion
according to TokenNumber and EFI_GUID space.
@@ -43,25 +318,30 @@ PeiRegisterCallBackWorker (
PCD_PPI_CALLBACK Compare;
PCD_PPI_CALLBACK Assign;
UINT32 LocalTokenNumber;
+ UINT32 LocalTokenCount;
+ UINTN PeiNexTokenNumber;
UINTN TokenNumber;
UINTN Idx;
+ PEI_PCD_DATABASE *PeiPcdDb;
+
+ PeiPcdDb = GetPcdDatabase();
+ LocalTokenCount = PeiPcdDb->LocalTokenCount;
+ PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount;
if (Guid == NULL) {
TokenNumber = ExTokenNumber;
-
//
// TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
// We have to decrement TokenNumber by 1 to make it usable
// as the array index.
//
TokenNumber--;
- ASSERT (TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1);
+ ASSERT (TokenNumber + 1 < (PeiNexTokenNumber + 1));
} else {
TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);
if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {
return EFI_NOT_FOUND;
}
-
//
// TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
// We have to decrement TokenNumber by 1 to make it usable
@@ -71,11 +351,11 @@ PeiRegisterCallBackWorker (
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
- ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
+ ASSERT ((TokenNumber + 1) < (LocalTokenCount + 1));
}
- LocalTokenNumber = GetPcdDatabase()->Init.LocalTokenNumberTable[TokenNumber];
+ LocalTokenNumber = *((UINT32 *)((UINT8 *)PeiPcdDb + PeiPcdDb->LocalTokenNumberTableOffset) + TokenNumber);
//
// We don't support SET for HII and VPD type PCD entry in PEI phase.
@@ -105,33 +385,81 @@ PeiRegisterCallBackWorker (
}
+
+/**
+ Find the Pcd database.
+
+ @param FileHandle Handle of the file the external PCD database binary located.
+
+ @retval The base address of external PCD database binary.
+ @retval NULL Return NULL if not find.
+**/
+VOID *
+LocateExPcdBinary (
+ IN EFI_PEI_FILE_HANDLE FileHandle
+ )
+{
+ EFI_STATUS Status;
+ VOID *PcdDb;
+
+ PcdDb = NULL;
+
+ ASSERT (FileHandle != NULL);
+
+ Status = PeiServicesFfsFindSectionData (EFI_SECTION_RAW, FileHandle, &PcdDb);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Check the first bytes (Header Signature Guid) and build version.
+ //
+ if (!CompareGuid (PcdDb, &gPcdDataBaseSignatureGuid) ||
+ (((PEI_PCD_DATABASE *) PcdDb)->BuildVersion != PCD_SERVICE_PEIM_VERSION)) {
+ ASSERT (FALSE);
+ }
+ return PcdDb;
+}
+
+
/**
The function builds the PCD database.
+
+ @param FileHandle Handle of the file the external PCD database binary located.
+
+ @return Pointer to PCD database.
**/
-VOID
+PEI_PCD_DATABASE *
BuildPcdDatabase (
- VOID
+ IN EFI_PEI_FILE_HANDLE FileHandle
)
{
- PEI_PCD_DATABASE *Database;
- VOID *CallbackFnTable;
- UINTN SizeOfCallbackFnTable;
-
- Database = BuildGuidHob (&gPcdDataBaseHobGuid, sizeof (PEI_PCD_DATABASE));
+ PEI_PCD_DATABASE *Database;
+ PEI_PCD_DATABASE *PeiPcdDbBinary;
+ VOID *CallbackFnTable;
+ UINTN SizeOfCallbackFnTable;
+
+ //
+ // Locate the external PCD database binary for one section of current FFS
+ //
+ PeiPcdDbBinary = LocateExPcdBinary (FileHandle);
+
+ ASSERT(PeiPcdDbBinary != NULL);
+
+ Database = BuildGuidHob (&gPcdDataBaseHobGuid, PeiPcdDbBinary->Length + PeiPcdDbBinary->UninitDataBaseSize);
- ZeroMem (Database, sizeof (PEI_PCD_DATABASE));
+ ZeroMem (Database, PeiPcdDbBinary->Length + PeiPcdDbBinary->UninitDataBaseSize);
//
- // gPEIPcdDbInit is smaller than PEI_PCD_DATABASE
+ // PeiPcdDbBinary is smaller than Database
//
-
- CopyMem (&Database->Init, &gPEIPcdDbInit, sizeof (gPEIPcdDbInit));
+ CopyMem (Database, PeiPcdDbBinary, PeiPcdDbBinary->Length);
- SizeOfCallbackFnTable = PEI_LOCAL_TOKEN_NUMBER * sizeof (PCD_PPI_CALLBACK) * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry);
+ SizeOfCallbackFnTable = Database->LocalTokenCount * sizeof (PCD_PPI_CALLBACK) * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry);
CallbackFnTable = BuildGuidHob (&gEfiCallerIdGuid, SizeOfCallbackFnTable);
ZeroMem (CallbackFnTable, SizeOfCallbackFnTable);
+
+ return Database;
}
/**
@@ -215,6 +543,7 @@ GetSkuEnabledTokenNumber (
SKU_ID *SkuIdTable;
INTN Index;
UINT8 *Value;
+ BOOLEAN FoundSku;
PeiPcdDb = GetPcdDatabase ();
@@ -223,13 +552,30 @@ GetSkuEnabledTokenNumber (
SkuHead = (SKU_HEAD *) ((UINT8 *)PeiPcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));
Value = (UINT8 *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuDataStartOffset));
SkuIdTable = (SKU_ID *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuIdTableOffset));
-
+
+ //
+ // Find the current system's SKU ID entry in SKU ID table.
+ //
+ FoundSku = FALSE;
for (Index = 0; Index < SkuIdTable[0]; Index++) {
- if (PeiPcdDb->Init.SystemSkuId == SkuIdTable[Index + 1]) {
+ if (PeiPcdDb->SystemSkuId == SkuIdTable[Index + 1]) {
+ FoundSku = TRUE;
break;
}
}
+ //
+ // Find the default SKU ID entry in SKU ID table.
+ //
+ if(!FoundSku) {
+ for (Index = 0; Index < SkuIdTable[0]; Index++) {
+ if (0 == SkuIdTable[Index + 1]) {
+ break;
+ }
+ }
+ }
+ ASSERT (Index < SkuIdTable[0]);
+
switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
case PCD_TYPE_VPD:
Value = (UINT8 *) &(((VPD_HEAD *) Value)[Index]);
@@ -238,14 +584,18 @@ GetSkuEnabledTokenNumber (
case PCD_TYPE_HII:
Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[Index]);
return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_HII);
-
+
+ case PCD_TYPE_HII|PCD_TYPE_STRING:
+ Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[Index]);
+ return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_HII | PCD_TYPE_STRING);
+
case PCD_TYPE_STRING:
Value = (UINT8 *) &(((STRING_HEAD *) Value)[Index]);
return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_STRING);
case PCD_TYPE_DATA:
Value += Size * Index;
- return (UINT32) (Value - (UINT8 *) PeiPcdDb);
+ return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_DATA);
default:
ASSERT (FALSE);
@@ -281,6 +631,8 @@ InvokeCallbackOnSet (
EFI_HOB_GUID_TYPE *GuidHob;
PCD_PPI_CALLBACK *CallbackTable;
UINTN Idx;
+ PEI_PCD_DATABASE *PeiPcdDb;
+ UINT32 LocalTokenCount;
//
// TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
@@ -288,12 +640,15 @@ InvokeCallbackOnSet (
// as the array index.
//
TokenNumber--;
-
+
+ PeiPcdDb = GetPcdDatabase ();
+ LocalTokenCount = PeiPcdDb->LocalTokenCount;
+
if (Guid == NULL) {
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
- ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
+ ASSERT (TokenNumber + 1 < (LocalTokenCount + 1));
}
GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid);
@@ -359,11 +714,13 @@ SetWorker (
)
{
UINT32 LocalTokenNumber;
+ UINTN PeiNexTokenNumber;
PEI_PCD_DATABASE *PeiPcdDb;
STRING_HEAD StringTableIdx;
UINTN Offset;
VOID *InternalData;
UINTN MaxSize;
+ UINT32 LocalTokenCount;
if (!FeaturePcdGet(PcdPeiFullPcdDatabaseEnable)) {
return EFI_UNSUPPORTED;
@@ -375,15 +732,13 @@ SetWorker (
// as the array index.
//
TokenNumber--;
+ PeiPcdDb = GetPcdDatabase ();
+ LocalTokenCount = PeiPcdDb->LocalTokenCount;
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
- ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
-
- PeiPcdDb = GetPcdDatabase ();
-
- LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];
+ ASSERT (TokenNumber + 1 < (LocalTokenCount + 1));
if (PtrType) {
//
@@ -405,18 +760,12 @@ SetWorker (
// For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX
// type PCD entry in ExSetWorker.
//
- if (TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1) {
+ PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount;
+ if (TokenNumber + 1 < PeiNexTokenNumber + 1) {
InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);
}
- if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
- if (PtrType) {
- GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);
- } else {
- MaxSize = *Size;
- }
- LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);
- }
+ LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber + 1);
Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
InternalData = (VOID *) ((UINT8 *) PeiPcdDb + Offset);
@@ -433,7 +782,7 @@ SetWorker (
case PCD_TYPE_STRING:
if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {
StringTableIdx = *((STRING_HEAD *)InternalData);
- CopyMem (&PeiPcdDb->Init.StringTable[StringTableIdx], Data, *Size);
+ CopyMem ((UINT8 *)PeiPcdDb + PeiPcdDb->StringTableOffset + StringTableIdx, Data, *Size);
return EFI_SUCCESS;
} else {
return EFI_INVALID_PARAMETER;
@@ -503,7 +852,7 @@ ExSetValueWorker (
}
/**
- Set value for a dynamic PCD entry.
+ Set value for a dynamic-ex PCD entry.
This routine find the local token number according to dynamic-ex PCD's token
space guid and token number firstly, and invoke callback function if this PCD
@@ -597,7 +946,7 @@ GetWorker (
STRING_HEAD StringTableIdx;
PEI_PCD_DATABASE *PeiPcdDb;
UINT32 LocalTokenNumber;
- UINTN MaxSize;
+ UINT32 LocalTokenCount;
//
// TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
@@ -606,29 +955,21 @@ GetWorker (
//
TokenNumber--;
+ PeiPcdDb = GetPcdDatabase ();
+ LocalTokenCount = PeiPcdDb->LocalTokenCount;
+
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
- ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
+ ASSERT (TokenNumber + 1 < (LocalTokenCount + 1));
ASSERT ((GetSize == PeiPcdGetSize(TokenNumber + 1)) || (GetSize == 0));
- PeiPcdDb = GetPcdDatabase ();
-
- LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];
-
- if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
- if (GetSize == 0) {
- GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);
- } else {
- MaxSize = GetSize;
- }
- LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);
- }
+ LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber + 1);
Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
- StringTable = PeiPcdDb->Init.StringTable;
-
+ StringTable = (UINT8 *)PeiPcdDb + PeiPcdDb->StringTableOffset;
+
switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
case PCD_TYPE_VPD:
{
@@ -642,7 +983,7 @@ GetWorker (
{
VariableHead = (VARIABLE_HEAD *) ((UINT8 *)PeiPcdDb + Offset);
- Guid = &(PeiPcdDb->Init.GuidTable[VariableHead->GuidTableIndex]);
+ Guid = (EFI_GUID *) ((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset) + VariableHead->GuidTableIndex;
Name = (UINT16*)&StringTable[VariableHead->StringIndex];
Status = GetHiiVariable (Guid, Name, &Data, &DataSize);
@@ -681,16 +1022,16 @@ GetWorker (
}
/**
- Get local token number according to dynamic-ex PCD's {token space guid:token number}
+ Get Token Number according to dynamic-ex PCD's {token space guid:token number}
A dynamic-ex type PCD, developer must provide pair of token space guid: token number
in DEC file. PCD database maintain a mapping table that translate pair of {token
- space guid: token number} to local token number.
+ space guid: token number} to Token Number.
@param Guid Token space guid for dynamic-ex PCD entry.
- @param ExTokenNumber EDES_TODO: Add parameter description
+ @param ExTokenNumber Dynamic-ex PCD token number.
- @return local token number for dynamic-ex PCD.
+ @return Token Number for dynamic-ex PCD.
**/
UINTN
@@ -707,11 +1048,11 @@ GetExPcdTokenNumber (
PEI_PCD_DATABASE *PeiPcdDb;
PeiPcdDb = GetPcdDatabase();
-
- ExMap = PeiPcdDb->Init.ExMapTable;
- GuidTable = PeiPcdDb->Init.GuidTable;
- MatchGuid = ScanGuid (GuidTable, sizeof(PeiPcdDb->Init.GuidTable), Guid);
+ ExMap = (DYNAMICEX_MAPPING *)((UINT8 *)PeiPcdDb + PeiPcdDb->ExMapTableOffset);
+ GuidTable = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset);
+
+ MatchGuid = ScanGuid (GuidTable, PeiPcdDb->GuidTableCount * sizeof(EFI_GUID), Guid);
//
// We need to ASSERT here. If GUID can't be found in GuidTable, this is a
// error in the BUILD system.
@@ -720,10 +1061,10 @@ GetExPcdTokenNumber (
MatchGuidIdx = MatchGuid - GuidTable;
- for (Index = 0; Index < PEI_EXMAPPING_TABLE_SIZE; Index++) {
+ for (Index = 0; Index < PeiPcdDb->ExTokenCount; Index++) {
if ((ExTokenNumber == ExMap[Index].ExTokenNumber) &&
(MatchGuidIdx == ExMap[Index].ExGuidIndex)) {
- return ExMap[Index].LocalTokenNumber;
+ return ExMap[Index].TokenNumber;
}
}
@@ -750,7 +1091,7 @@ GetPcdDatabase (
}
/**
- Get SKU ID tabble from PCD database.
+ Get SKU ID table from PCD database.
@param LocalTokenNumberTableIdx Index of local token number in token number table.
@param Database PCD database.
@@ -767,7 +1108,7 @@ GetSkuIdArray (
SKU_HEAD *SkuHead;
UINTN LocalTokenNumber;
- LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];
+ LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx);
ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0);
@@ -793,14 +1134,14 @@ GetSizeTableIndex (
)
{
UINTN Index;
- UINTN SizeTableIdx;
+ UINTN SizeTableIdx;
UINTN LocalTokenNumber;
SKU_ID *SkuIdTable;
SizeTableIdx = 0;
- for (Index=0; Index<LocalTokenNumberTableIdx; Index++) {
- LocalTokenNumber = Database->Init.LocalTokenNumberTable[Index];
+ for (Index = 0; Index < LocalTokenNumberTableIdx; Index++) {
+ LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + Index);
if ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER) {
//
@@ -809,11 +1150,12 @@ GetSizeTableIndex (
//
if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {
//
- // We have only one entry for VPD enabled PCD entry:
+ // We have only two entry for VPD enabled PCD entry:
// 1) MAX Size.
- // We consider current size is equal to MAX size.
+ // 2) Current Size
+ // Current size is equal to MAX size.
//
- SizeTableIdx++;
+ SizeTableIdx += 2;
} else {
if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {
//
diff --git a/MdeModulePkg/Universal/PCD/Pei/Service.h b/MdeModulePkg/Universal/PCD/Pei/Service.h
index 284768625..916e70895 100644
--- a/MdeModulePkg/Universal/PCD/Pei/Service.h
+++ b/MdeModulePkg/Universal/PCD/Pei/Service.h
@@ -1,7 +1,7 @@
/** @file
The internal header file declares the private functions used by PeiPcd driver.
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -19,7 +19,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Ppi/ReadOnlyVariable2.h>
#include <Ppi/Pcd.h>
#include <Ppi/PiPcd.h>
+#include <Ppi/PcdInfo.h>
+#include <Ppi/PiPcdInfo.h>
#include <Guid/PcdDataBaseHobGuid.h>
+#include <Guid/PcdDataBaseSignatureGuid.h>
#include <Library/DebugLib.h>
#include <Library/PeimEntryPoint.h>
#include <Library/BaseLib.h>
@@ -27,13 +30,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/PeiServicesLib.h>
#include <Library/PcdLib.h>
#include <Library/BaseMemoryLib.h>
-
+#include <Library/MemoryAllocationLib.h>
//
// Please make sure the PCD Serivce PEIM Version is consistent with
// the version of the generated PEIM PCD Database by build tool.
//
-#define PCD_SERVICE_PEIM_VERSION 2
+#define PCD_SERVICE_PEIM_VERSION 4
//
// PCD_PEI_SERVICE_DRIVER_VERSION is defined in Autogen.h.
@@ -42,6 +45,61 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#error "Please make sure the version of PCD PEIM Service and the generated PCD PEI Database match."
#endif
+/**
+ Retrieve additional information associated with a PCD token in the default token space.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully.
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+EFIAPI
+PeiGetPcdInfoGetInfo (
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ );
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully.
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+EFIAPI
+PeiGetPcdInfoGetInfoEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ );
+
+/**
+ Retrieve the currently set SKU Id.
+
+ @return The currently set SKU Id. If the platform has not set at a SKU Id, then the
+ default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU
+ Id is returned.
+**/
+UINTN
+EFIAPI
+PeiGetPcdInfoGetSku (
+ VOID
+ );
+
//
// PPI Interface Implementation Declaration.
//
@@ -752,6 +810,26 @@ PeiPcdGetNextTokenSpace (
IN OUT CONST EFI_GUID **Guid
);
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+PeiGetPcdInfo (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ );
/* Internal Function definitions */
/**
@@ -896,16 +974,16 @@ typedef struct {
} EX_PCD_ENTRY_ATTRIBUTE;
/**
- Get local token number according to dynamic-ex PCD's {token space guid:token number}
+ Get Token Number according to dynamic-ex PCD's {token space guid:token number}
A dynamic-ex type PCD, developer must provide pair of token space guid: token number
in DEC file. PCD database maintain a mapping table that translate pair of {token
- space guid: token number} to local token number.
+ space guid: token number} to Token Number.
@param Guid Token space guid for dynamic-ex PCD entry.
@param ExTokenNumber Token number for dynamic-ex PCD.
- @return local token number for dynamic-ex PCD.
+ @return Token Number for dynamic-ex PCD.
**/
UINTN
@@ -915,6 +993,21 @@ GetExPcdTokenNumber (
);
/**
+ Find the local token number according to system SKU ID.
+
+ @param LocalTokenNumber PCD token number
+ @param Size The size of PCD entry.
+
+ @return Token number according to system SKU ID.
+
+**/
+UINT32
+GetSkuEnabledTokenNumber (
+ UINT32 LocalTokenNumber,
+ UINTN Size
+ );
+
+/**
The function registers the CallBackOnSet fucntion
according to TokenNumber and EFI_GUID space.
@@ -938,10 +1031,15 @@ PeiRegisterCallBackWorker (
/**
The function builds the PCD database.
+
+ @param FileHandle Handle of the file the external PCD database binary located.
+
+ @return Pointer to PCD database.
+
**/
-VOID
+PEI_PCD_DATABASE *
BuildPcdDatabase (
- VOID
+ IN EFI_PEI_FILE_HANDLE FileHandle
);
/**
@@ -1015,10 +1113,5 @@ SetPtrTypeSize (
IN PEI_PCD_DATABASE *Database
);
-//
-// The init Database created by PCD Database generation tool
-//
-extern PEI_PCD_DATABASE_INIT gPEIPcdDbInit;
-
#endif
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
index 44dae1ba0..d4ab369a4 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
@@ -1799,6 +1799,55 @@ ExtendValueToU64 (
Value->Value.u64 = Temp;
}
+/**
+ Get UINT64 type value.
+
+ @param Value Input Hii value.
+
+ @retval UINT64 Return the UINT64 type value.
+
+**/
+UINT64
+HiiValueToUINT64 (
+ IN EFI_HII_VALUE *Value
+ )
+{
+ UINT64 RetVal;
+
+ RetVal = 0;
+
+ switch (Value->Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ RetVal = Value->Value.u8;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ RetVal = Value->Value.u16;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ RetVal = Value->Value.u32;
+ break;
+
+ case EFI_IFR_TYPE_BOOLEAN:
+ RetVal = Value->Value.b;
+ break;
+
+ case EFI_IFR_TYPE_DATE:
+ RetVal = *(UINT64*) &Value->Value.date;
+ break;
+
+ case EFI_IFR_TYPE_TIME:
+ RetVal = (*(UINT64*) &Value->Value.time) & 0xffffff;
+ break;
+
+ default:
+ RetVal = Value->Value.u64;
+ break;
+ }
+
+ return RetVal;
+}
/**
Compare two Hii value.
@@ -1899,7 +1948,7 @@ CompareHiiValue (
//
// Take remain types(integer, boolean, date/time) as integer
//
- Temp64 = (INT64) (Value1->Value.u64 - Value2->Value.u64);
+ Temp64 = HiiValueToUINT64(Value1) - HiiValueToUINT64(Value2);
if (Temp64 > 0) {
*Result = 1;
} else if (Temp64 < 0) {
@@ -2036,11 +2085,7 @@ GetQuestionValueFromForm (
)
{
EFI_STATUS Status;
- EFI_HANDLE DriverHandle;
- EFI_HANDLE Handle;
- EFI_HII_HANDLE *HiiHandles;
EFI_HII_HANDLE HiiHandle;
- UINTN Index;
FORM_BROWSER_STATEMENT *Question;
FORM_BROWSER_FORMSET *FormSet;
FORM_BROWSER_FORM *Form;
@@ -2054,7 +2099,6 @@ GetQuestionValueFromForm (
(DevicePath == NULL && InputHiiHandle != NULL) );
GetTheVal = TRUE;
- DriverHandle = NULL;
HiiHandle = NULL;
Question = NULL;
Form = NULL;
@@ -2063,38 +2107,10 @@ GetQuestionValueFromForm (
// Get HiiHandle.
//
if (DevicePath != NULL) {
- //
- // 1. Get Driver handle.
- //
- Status = gBS->LocateDevicePath (
- &gEfiDevicePathProtocolGuid,
- &DevicePath,
- &DriverHandle
- );
- if (EFI_ERROR (Status) || (DriverHandle == NULL)) {
+ HiiHandle = DevicePathToHiiHandle (DevicePath, FormSetGuid);
+ if (HiiHandle == NULL) {
return FALSE;
}
-
- //
- // 2. Get Hii handle
- //
- HiiHandles = HiiGetHiiHandles (NULL);
- if (HiiHandles == NULL) {
- return FALSE;
- }
-
- for (Index = 0; HiiHandles[Index] != NULL; Index++) {
- Status = mHiiDatabase->GetPackageListHandle (
- mHiiDatabase,
- HiiHandles[Index],
- &Handle
- );
- if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {
- HiiHandle = HiiHandles[Index];
- break;
- }
- }
- FreePool (HiiHandles);
} else {
HiiHandle = InputHiiHandle;
}
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
index 4006fcd6f..ce2ba6fab 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
@@ -348,9 +348,19 @@ InitializeConfigHdr (
/**
Find the global storage link base on the input storate type, name and guid.
+ For EFI_HII_VARSTORE_EFI_VARIABLE and EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER,
+ same guid + name = same storage
+
+ For EFI_HII_VARSTORE_NAME_VALUE:
+ same guid + HiiHandle = same storage
+
+ For EFI_HII_VARSTORE_BUFFER:
+ same guid + name + HiiHandle = same storage
+
@param StorageType Storage type.
@param StorageGuid Storage guid.
@param StorageName Storage Name.
+ @param HiiHandle HiiHandle for this varstore.
@return Pointer to a GLOBAL_STORAGE data structure.
@@ -359,7 +369,8 @@ BROWSER_STORAGE *
FindStorageInList (
IN UINT8 StorageType,
IN EFI_GUID *StorageGuid,
- IN CHAR16 *StorageName
+ IN CHAR16 *StorageName,
+ IN EFI_HII_HANDLE HiiHandle
)
{
LIST_ENTRY *Link;
@@ -370,12 +381,16 @@ FindStorageInList (
BrowserStorage = BROWSER_STORAGE_FROM_LINK (Link);
if ((BrowserStorage->Type == StorageType) && CompareGuid (&BrowserStorage->Guid, StorageGuid)) {
- if (StorageType == EFI_HII_VARSTORE_NAME_VALUE) {
+ if (StorageType == EFI_HII_VARSTORE_NAME_VALUE && BrowserStorage->HiiHandle == HiiHandle) {
return BrowserStorage;
}
if (StrCmp (BrowserStorage->Name, StorageName) == 0) {
- return BrowserStorage;
+ if (StorageType == EFI_HII_VARSTORE_EFI_VARIABLE || StorageType == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
+ return BrowserStorage;
+ } else if (StorageType == EFI_HII_VARSTORE_BUFFER && BrowserStorage->HiiHandle == HiiHandle) {
+ return BrowserStorage;
+ }
}
}
@@ -494,7 +509,7 @@ CreateStorage (
Storage->Signature = FORMSET_STORAGE_SIGNATURE;
InsertTailList (&FormSet->StorageListHead, &Storage->Link);
- BrowserStorage = FindStorageInList(StorageType, StorageGuid, UnicodeString);
+ BrowserStorage = FindStorageInList(StorageType, StorageGuid, UnicodeString, FormSet->HiiHandle);
if (BrowserStorage == NULL) {
BrowserStorage = AllocateZeroPool (sizeof (BROWSER_STORAGE));
ASSERT (BrowserStorage != NULL);
@@ -508,7 +523,10 @@ CreateStorage (
BrowserStorage->Name = UnicodeString;
}
+ BrowserStorage->HiiHandle = FormSet->HiiHandle;
InitializeConfigHdr (FormSet, BrowserStorage);
+
+ BrowserStorage->Initialized = FALSE;
}
Storage->BrowserStorage = BrowserStorage;
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c b/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
index 8e6dff0dd..fb3ff7b26 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
@@ -1040,6 +1040,87 @@ ProcessAction (
return EFI_SUCCESS;
}
+/**
+ Check whether the formset guid is in this Hii package list.
+
+ @param HiiHandle The HiiHandle for this HII package list.
+ @param FormSetGuid The formset guid for the request formset.
+
+ @retval TRUE Find the formset guid.
+ @retval FALSE Not found the formset guid.
+
+**/
+BOOLEAN
+GetFormsetGuidFromHiiHandle (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_GUID *FormSetGuid
+ )
+{
+ EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
+ UINTN BufferSize;
+ UINT32 Offset;
+ UINT32 Offset2;
+ UINT32 PackageListLength;
+ EFI_HII_PACKAGE_HEADER PackageHeader;
+ UINT8 *Package;
+ UINT8 *OpCodeData;
+ EFI_STATUS Status;
+ BOOLEAN FindGuid;
+
+ BufferSize = 0;
+ HiiPackageList = NULL;
+ FindGuid = FALSE;
+
+ Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandle, &BufferSize, HiiPackageList);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ HiiPackageList = AllocatePool (BufferSize);
+ ASSERT (HiiPackageList != NULL);
+
+ Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandle, &BufferSize, HiiPackageList);
+ }
+ if (EFI_ERROR (Status) || HiiPackageList == NULL) {
+ return FALSE;
+ }
+
+ //
+ // Get Form package from this HII package List
+ //
+ Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
+ Offset2 = 0;
+ CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));
+
+ while (Offset < PackageListLength) {
+ Package = ((UINT8 *) HiiPackageList) + Offset;
+ CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
+ Offset += PackageHeader.Length;
+
+ if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {
+ //
+ // Search FormSet in this Form Package
+ //
+ Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);
+ while (Offset2 < PackageHeader.Length) {
+ OpCodeData = Package + Offset2;
+
+ if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {
+ if (CompareGuid (FormSetGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))){
+ FindGuid = TRUE;
+ break;
+ }
+ }
+
+ Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
+ }
+ }
+ if (FindGuid) {
+ break;
+ }
+ }
+
+ FreePool (HiiPackageList);
+
+ return FindGuid;
+}
/**
Find HII Handle in the HII database associated with given Device Path.
@@ -1048,6 +1129,7 @@ ProcessAction (
@param DevicePath Device Path associated with the HII package list
handle.
+ @param FormsetGuid The formset guid for this formset.
@retval Handle HII package list Handle associated with the Device
Path.
@@ -1055,15 +1137,13 @@ ProcessAction (
**/
EFI_HII_HANDLE
-EFIAPI
DevicePathToHiiHandle (
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN EFI_GUID *FormsetGuid
)
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;
- UINTN BufferSize;
- UINTN HandleCount;
UINTN Index;
EFI_HANDLE Handle;
EFI_HANDLE DriverHandle;
@@ -1088,32 +1168,8 @@ DevicePathToHiiHandle (
//
// Retrieve all HII Handles from HII database
//
- BufferSize = 0x1000;
- HiiHandles = AllocatePool (BufferSize);
- ASSERT (HiiHandles != NULL);
- Status = mHiiDatabase->ListPackageLists (
- mHiiDatabase,
- EFI_HII_PACKAGE_TYPE_ALL,
- NULL,
- &BufferSize,
- HiiHandles
- );
- if (Status == EFI_BUFFER_TOO_SMALL) {
- FreePool (HiiHandles);
- HiiHandles = AllocatePool (BufferSize);
- ASSERT (HiiHandles != NULL);
-
- Status = mHiiDatabase->ListPackageLists (
- mHiiDatabase,
- EFI_HII_PACKAGE_TYPE_ALL,
- NULL,
- &BufferSize,
- HiiHandles
- );
- }
-
- if (EFI_ERROR (Status)) {
- FreePool (HiiHandles);
+ HiiHandles = HiiGetHiiHandles (NULL);
+ if (HiiHandles == NULL) {
return NULL;
}
@@ -1121,16 +1177,21 @@ DevicePathToHiiHandle (
// Search Hii Handle by Driver Handle
//
HiiHandle = NULL;
- HandleCount = BufferSize / sizeof (EFI_HII_HANDLE);
- for (Index = 0; Index < HandleCount; Index++) {
+ for (Index = 0; HiiHandles[Index] != NULL; Index++) {
Status = mHiiDatabase->GetPackageListHandle (
mHiiDatabase,
HiiHandles[Index],
&Handle
);
if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {
- HiiHandle = HiiHandles[Index];
- break;
+ if (GetFormsetGuidFromHiiHandle(HiiHandles[Index], FormsetGuid)) {
+ HiiHandle = HiiHandles[Index];
+ break;
+ }
+
+ if (HiiHandle != NULL) {
+ break;
+ }
}
}
@@ -1157,17 +1218,8 @@ FormSetGuidToHiiHandle (
)
{
EFI_HII_HANDLE *HiiHandles;
- UINTN Index;
- EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
- UINTN BufferSize;
- UINT32 Offset;
- UINT32 Offset2;
- UINT32 PackageListLength;
- EFI_HII_PACKAGE_HEADER PackageHeader;
- UINT8 *Package;
- UINT8 *OpCodeData;
- EFI_STATUS Status;
EFI_HII_HANDLE HiiHandle;
+ UINTN Index;
ASSERT (ComparingGuid != NULL);
@@ -1182,61 +1234,14 @@ FormSetGuidToHiiHandle (
// Search for formset of each class type
//
for (Index = 0; HiiHandles[Index] != NULL; Index++) {
- BufferSize = 0;
- HiiPackageList = NULL;
- Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList);
- if (Status == EFI_BUFFER_TOO_SMALL) {
- HiiPackageList = AllocatePool (BufferSize);
- ASSERT (HiiPackageList != NULL);
-
- Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList);
- }
- if (EFI_ERROR (Status) || HiiPackageList == NULL) {
- return NULL;
+ if (GetFormsetGuidFromHiiHandle(HiiHandles[Index], ComparingGuid)) {
+ HiiHandle = HiiHandles[Index];
+ break;
}
- //
- // Get Form package from this HII package List
- //
- Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
- Offset2 = 0;
- CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));
-
- while (Offset < PackageListLength) {
- Package = ((UINT8 *) HiiPackageList) + Offset;
- CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
-
- if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {
- //
- // Search FormSet in this Form Package
- //
- Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);
- while (Offset2 < PackageHeader.Length) {
- OpCodeData = Package + Offset2;
-
- if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {
- //
- // Try to compare against formset GUID
- //
- if (CompareGuid (ComparingGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
- HiiHandle = HiiHandles[Index];
- break;
- }
- }
-
- Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
- }
- }
- if (HiiHandle != NULL) {
- break;
- }
- Offset += PackageHeader.Length;
+ if (HiiHandle != NULL) {
+ break;
}
-
- FreePool (HiiPackageList);
- if (HiiHandle != NULL) {
- break;
- }
}
FreePool (HiiHandles);
@@ -1375,7 +1380,7 @@ ProcessGotoOpCode (
if (mPathFromText != NULL) {
DevicePath = mPathFromText->ConvertTextToDevicePath(StringPtr);
if (DevicePath != NULL) {
- HiiHandle = DevicePathToHiiHandle (DevicePath);
+ HiiHandle = DevicePathToHiiHandle (DevicePath, &Statement->HiiValue.Value.ref.FormSetGuid);
FreePool (DevicePath);
}
FreePool (StringPtr);
@@ -1494,7 +1499,6 @@ ProcessQuestionConfig (
EFI_STATUS Status;
CHAR16 *ConfigResp;
CHAR16 *Progress;
- EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
if (Question->QuestionConfig == 0) {
return EFI_SUCCESS;
@@ -1511,12 +1515,8 @@ ProcessQuestionConfig (
//
// Send config to Configuration Driver
//
- ConfigAccess = Selection->FormSet->ConfigAccess;
- if (ConfigAccess == NULL) {
- return EFI_UNSUPPORTED;
- }
- Status = ConfigAccess->RouteConfig (
- ConfigAccess,
+ Status = mHiiConfigRouting->RouteConfig (
+ mHiiConfigRouting,
ConfigResp,
&Progress
);
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
index 7975a1df1..66238e055 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
@@ -645,6 +645,17 @@ BrowserCallback (
}
}
+ if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE ||
+ Storage->Type == EFI_HII_VARSTORE_BUFFER) {
+ if (mSystemLevelFormSet == NULL || mSystemLevelFormSet->HiiHandle == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (Storage->HiiHandle != mSystemLevelFormSet->HiiHandle) {
+ continue;
+ }
+ }
+
Status = ProcessStorage (&TotalSize, &ResultsData, RetrieveData, Storage);
if (EFI_ERROR (Status)) {
return Status;
@@ -1259,7 +1270,6 @@ GetQuestionValue (
BOOLEAN IsString;
CHAR16 TemStr[5];
UINT8 DigitUint8;
- UINT8 *TemBuffer;
Status = EFI_SUCCESS;
Value = NULL;
@@ -1476,147 +1486,118 @@ GetQuestionValue (
FreePool (Value);
}
} else {
- if (Storage->Type == EFI_HII_VARSTORE_BUFFER || Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
- //
- // Request current settings from Configuration Driver
- //
- if (FormSet->ConfigAccess == NULL) {
- return EFI_NOT_FOUND;
- }
-
- //
- // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||
- // <ConfigHdr> + "&" + <VariableName>
- //
- if (IsBufferStorage) {
- Length = StrLen (Storage->ConfigHdr);
- Length += StrLen (Question->BlockName);
- } else {
- Length = StrLen (Storage->ConfigHdr);
- Length += StrLen (Question->VariableName) + 1;
- }
- ConfigRequest = AllocateZeroPool ((Length + 1) * sizeof (CHAR16));
- ASSERT (ConfigRequest != NULL);
+ //
+ // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||
+ // <ConfigHdr> + "&" + <VariableName>
+ //
+ if (IsBufferStorage) {
+ Length = StrLen (Storage->ConfigHdr);
+ Length += StrLen (Question->BlockName);
+ } else {
+ Length = StrLen (Storage->ConfigHdr);
+ Length += StrLen (Question->VariableName) + 1;
+ }
+ ConfigRequest = AllocateZeroPool ((Length + 1) * sizeof (CHAR16));
+ ASSERT (ConfigRequest != NULL);
- StrCpy (ConfigRequest, Storage->ConfigHdr);
- if (IsBufferStorage) {
- StrCat (ConfigRequest, Question->BlockName);
- } else {
- StrCat (ConfigRequest, L"&");
- StrCat (ConfigRequest, Question->VariableName);
- }
+ StrCpy (ConfigRequest, Storage->ConfigHdr);
+ if (IsBufferStorage) {
+ StrCat (ConfigRequest, Question->BlockName);
+ } else {
+ StrCat (ConfigRequest, L"&");
+ StrCat (ConfigRequest, Question->VariableName);
+ }
- Status = FormSet->ConfigAccess->ExtractConfig (
- FormSet->ConfigAccess,
- ConfigRequest,
- &Progress,
- &Result
- );
- FreePool (ConfigRequest);
- if (EFI_ERROR (Status)) {
- return Status;
- }
+ //
+ // Request current settings from Configuration Driver
+ //
+ Status = mHiiConfigRouting->ExtractConfig (
+ mHiiConfigRouting,
+ ConfigRequest,
+ &Progress,
+ &Result
+ );
+ FreePool (ConfigRequest);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
- //
- // Skip <ConfigRequest>
- //
- if (IsBufferStorage) {
- Value = StrStr (Result, L"&VALUE");
- if (Value == NULL) {
- FreePool (Result);
- return EFI_NOT_FOUND;
- }
- //
- // Skip "&VALUE"
- //
- Value = Value + 6;
- } else {
- Value = Result + Length;
- }
- if (*Value != '=') {
+ //
+ // Skip <ConfigRequest>
+ //
+ if (IsBufferStorage) {
+ Value = StrStr (Result, L"&VALUE");
+ if (Value == NULL) {
FreePool (Result);
return EFI_NOT_FOUND;
}
//
- // Skip '=', point to value
+ // Skip "&VALUE"
//
- Value = Value + 1;
+ Value = Value + 6;
+ } else {
+ Value = Result + Length;
+ }
+ if (*Value != '=') {
+ FreePool (Result);
+ return EFI_NOT_FOUND;
+ }
+ //
+ // Skip '=', point to value
+ //
+ Value = Value + 1;
+ //
+ // Suppress <AltResp> if any
+ //
+ StringPtr = Value;
+ while (*StringPtr != L'\0' && *StringPtr != L'&') {
+ StringPtr++;
+ }
+ *StringPtr = L'\0';
+
+ LengthStr = StrLen (Value);
+ Status = EFI_SUCCESS;
+ if (!IsBufferStorage && IsString) {
//
- // Suppress <AltResp> if any
+ // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
+ // Add string tail char L'\0' into Length
//
- StringPtr = Value;
- while (*StringPtr != L'\0' && *StringPtr != L'&') {
- StringPtr++;
- }
- *StringPtr = L'\0';
-
- LengthStr = StrLen (Value);
- Status = EFI_SUCCESS;
- if (!IsBufferStorage && IsString) {
+ Length = StorageWidth + sizeof (CHAR16);
+ if (Length < ((LengthStr / 4 + 1) * 2)) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ } else {
+ StringPtr = (CHAR16 *) Dst;
+ ZeroMem (TemStr, sizeof (TemStr));
+ for (Index = 0; Index < LengthStr; Index += 4) {
+ StrnCpy (TemStr, Value + Index, 4);
+ StringPtr[Index/4] = (CHAR16) StrHexToUint64 (TemStr);
+ }
//
- // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
- // Add string tail char L'\0' into Length
+ // Add tailing L'\0' character
//
- Length = StorageWidth + sizeof (CHAR16);
- if (Length < ((LengthStr / 4 + 1) * 2)) {
- Status = EFI_BUFFER_TOO_SMALL;
- } else {
- StringPtr = (CHAR16 *) Dst;
- ZeroMem (TemStr, sizeof (TemStr));
- for (Index = 0; Index < LengthStr; Index += 4) {
- StrnCpy (TemStr, Value + Index, 4);
- StringPtr[Index/4] = (CHAR16) StrHexToUint64 (TemStr);
- }
- //
- // Add tailing L'\0' character
- //
- StringPtr[Index/4] = L'\0';
- }
+ StringPtr[Index/4] = L'\0';
+ }
+ } else {
+ if (StorageWidth < ((LengthStr + 1) / 2)) {
+ Status = EFI_BUFFER_TOO_SMALL;
} else {
- if (StorageWidth < ((LengthStr + 1) / 2)) {
- Status = EFI_BUFFER_TOO_SMALL;
- } else {
- ZeroMem (TemStr, sizeof (TemStr));
- for (Index = 0; Index < LengthStr; Index ++) {
- TemStr[0] = Value[LengthStr - Index - 1];
- DigitUint8 = (UINT8) StrHexToUint64 (TemStr);
- if ((Index & 1) == 0) {
- Dst [Index/2] = DigitUint8;
- } else {
- Dst [Index/2] = (UINT8) ((DigitUint8 << 4) + Dst [Index/2]);
- }
+ ZeroMem (TemStr, sizeof (TemStr));
+ for (Index = 0; Index < LengthStr; Index ++) {
+ TemStr[0] = Value[LengthStr - Index - 1];
+ DigitUint8 = (UINT8) StrHexToUint64 (TemStr);
+ if ((Index & 1) == 0) {
+ Dst [Index/2] = DigitUint8;
+ } else {
+ Dst [Index/2] = (UINT8) ((DigitUint8 << 4) + Dst [Index/2]);
}
}
}
+ }
- if (EFI_ERROR (Status)) {
- FreePool (Result);
- return Status;
- }
- } else if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
- TemBuffer = NULL;
- TemBuffer = AllocateZeroPool (Storage->Size);
- if (TemBuffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- return Status;
- }
- Length = Storage->Size;
- Status = gRT->GetVariable (
- Storage->Name,
- &Storage->Guid,
- NULL,
- &Length,
- TemBuffer
- );
- if (EFI_ERROR (Status)) {
- FreePool (TemBuffer);
- return Status;
- }
-
- CopyMem (Dst, TemBuffer + Question->VarStoreInfo.VarOffset, StorageWidth);
-
- FreePool (TemBuffer);
+ if (EFI_ERROR (Status)) {
+ FreePool (Result);
+ return Status;
}
//
@@ -1860,111 +1841,78 @@ SetQuestionValue (
}
}
} else if (SetValueTo == GetSetValueWithHiiDriver) {
- if (Storage->Type == EFI_HII_VARSTORE_BUFFER || Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
- //
- // <ConfigResp> ::= <ConfigHdr> + <BlockName> + "&VALUE=" + "<HexCh>StorageWidth * 2" ||
- // <ConfigHdr> + "&" + <VariableName> + "=" + "<string>"
- //
- if (IsBufferStorage) {
- Length = StrLen (Question->BlockName) + 7;
- } else {
- Length = StrLen (Question->VariableName) + 2;
- }
- if (!IsBufferStorage && IsString) {
- Length += (StrLen ((CHAR16 *) Src) * 4);
- } else {
- Length += (StorageWidth * 2);
- }
- ConfigResp = AllocateZeroPool ((StrLen (Storage->ConfigHdr) + Length + 1) * sizeof (CHAR16));
- ASSERT (ConfigResp != NULL);
-
- StrCpy (ConfigResp, Storage->ConfigHdr);
- if (IsBufferStorage) {
- StrCat (ConfigResp, Question->BlockName);
- StrCat (ConfigResp, L"&VALUE=");
- } else {
- StrCat (ConfigResp, L"&");
- StrCat (ConfigResp, Question->VariableName);
- StrCat (ConfigResp, L"=");
- }
+ //
+ // <ConfigResp> ::= <ConfigHdr> + <BlockName> + "&VALUE=" + "<HexCh>StorageWidth * 2" ||
+ // <ConfigHdr> + "&" + <VariableName> + "=" + "<string>"
+ //
+ if (IsBufferStorage) {
+ Length = StrLen (Question->BlockName) + 7;
+ } else {
+ Length = StrLen (Question->VariableName) + 2;
+ }
+ if (!IsBufferStorage && IsString) {
+ Length += (StrLen ((CHAR16 *) Src) * 4);
+ } else {
+ Length += (StorageWidth * 2);
+ }
+ ConfigResp = AllocateZeroPool ((StrLen (Storage->ConfigHdr) + Length + 1) * sizeof (CHAR16));
+ ASSERT (ConfigResp != NULL);
- Value = ConfigResp + StrLen (ConfigResp);
+ StrCpy (ConfigResp, Storage->ConfigHdr);
+ if (IsBufferStorage) {
+ StrCat (ConfigResp, Question->BlockName);
+ StrCat (ConfigResp, L"&VALUE=");
+ } else {
+ StrCat (ConfigResp, L"&");
+ StrCat (ConfigResp, Question->VariableName);
+ StrCat (ConfigResp, L"=");
+ }
- if (!IsBufferStorage && IsString) {
- //
- // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
- //
- TemName = (CHAR16 *) Src;
- TemString = Value;
- for (; *TemName != L'\0'; TemName++) {
- TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemName, 4);
- }
- } else {
- //
- // Convert Buffer to Hex String
- //
- TemBuffer = Src + StorageWidth - 1;
- TemString = Value;
- for (Index = 0; Index < StorageWidth; Index ++, TemBuffer --) {
- TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);
- }
- }
+ Value = ConfigResp + StrLen (ConfigResp);
+ if (!IsBufferStorage && IsString) {
//
- // Convert to lower char.
+ // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
//
- for (TemString = Value; *Value != L'\0'; Value++) {
- if (*Value >= L'A' && *Value <= L'Z') {
- *Value = (CHAR16) (*Value - L'A' + L'a');
- }
+ TemName = (CHAR16 *) Src;
+ TemString = Value;
+ for (; *TemName != L'\0'; TemName++) {
+ TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemName, 4);
}
-
+ } else {
//
- // Submit Question Value to Configuration Driver
+ // Convert Buffer to Hex String
//
- if (FormSet->ConfigAccess != NULL) {
- Status = FormSet->ConfigAccess->RouteConfig (
- FormSet->ConfigAccess,
- ConfigResp,
- &Progress
- );
- if (EFI_ERROR (Status)) {
- FreePool (ConfigResp);
- return Status;
- }
- }
- FreePool (ConfigResp);
-
- } else if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
- TemBuffer = NULL;
- TemBuffer = AllocateZeroPool(Storage->Size);
- if (TemBuffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- return Status;
+ TemBuffer = Src + StorageWidth - 1;
+ TemString = Value;
+ for (Index = 0; Index < StorageWidth; Index ++, TemBuffer --) {
+ TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);
}
- Length = Storage->Size;
- Status = gRT->GetVariable (
- Storage->Name,
- &Storage->Guid,
- NULL,
- &Length,
- TemBuffer
- );
-
- CopyMem (TemBuffer + Question->VarStoreInfo.VarOffset, Src, StorageWidth);
-
- Status = gRT->SetVariable (
- Storage->Name,
- &Storage->Guid,
- Storage->Attributes,
- Storage->Size,
- TemBuffer
- );
- FreePool (TemBuffer);
- if (EFI_ERROR (Status)){
- return Status;
+ }
+
+ //
+ // Convert to lower char.
+ //
+ for (TemString = Value; *Value != L'\0'; Value++) {
+ if (*Value >= L'A' && *Value <= L'Z') {
+ *Value = (CHAR16) (*Value - L'A' + L'a');
}
}
+
+ //
+ // Submit Question Value to Configuration Driver
+ //
+ Status = mHiiConfigRouting->RouteConfig (
+ mHiiConfigRouting,
+ ConfigResp,
+ &Progress
+ );
+ if (EFI_ERROR (Status)) {
+ FreePool (ConfigResp);
+ return Status;
+ }
+ FreePool (ConfigResp);
+
//
// Sync storage, from editbuffer to buffer.
//
@@ -2511,8 +2459,6 @@ SubmitForm (
EFI_STRING Progress;
BROWSER_STORAGE *Storage;
FORMSET_STORAGE *FormSetStorage;
- UINTN BufferSize;
- UINT8 *TmpBuf;
FORM_BROWSER_FORMSET *LocalFormSet;
FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;
@@ -2564,72 +2510,18 @@ SubmitForm (
}
//
- // 2. Set value to hii driver or efi variable.
+ // 2. Set value to hii config routine protocol.
//
- if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
- Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
- //
- // Send <ConfigResp> to Configuration Driver
- //
- if (FormSet->ConfigAccess != NULL) {
- Status = FormSet->ConfigAccess->RouteConfig (
- FormSet->ConfigAccess,
- ConfigResp,
- &Progress
- );
- if (EFI_ERROR (Status)) {
- FreePool (ConfigResp);
- return Status;
- }
- }
- } else if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
- TmpBuf = NULL;
- TmpBuf = AllocateZeroPool(Storage->Size);
- if (TmpBuf == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- return Status;
- }
-
- BufferSize = Storage->Size;
- Status = gRT->GetVariable (
- Storage->Name,
- &Storage->Guid,
- NULL,
- &BufferSize,
- TmpBuf
- );
- if (EFI_ERROR (Status)) {
- FreePool (TmpBuf);
- FreePool (ConfigResp);
- return Status;
- }
- ASSERT (BufferSize == Storage->Size);
- Status = mHiiConfigRouting->ConfigToBlock (
- mHiiConfigRouting,
- ConfigResp,
- TmpBuf,
- &BufferSize,
- &Progress
- );
- if (EFI_ERROR (Status)) {
- FreePool (TmpBuf);
- FreePool (ConfigResp);
- return Status;
- }
-
- Status = gRT->SetVariable (
- Storage->Name,
- &Storage->Guid,
- Storage->Attributes,
- Storage->Size,
- TmpBuf
- );
- FreePool (TmpBuf);
- if (EFI_ERROR (Status)) {
- FreePool (ConfigResp);
- return Status;
- }
+ Status = mHiiConfigRouting->RouteConfig (
+ mHiiConfigRouting,
+ ConfigResp,
+ &Progress
+ );
+ if (EFI_ERROR (Status)) {
+ FreePool (ConfigResp);
+ return Status;
}
+
FreePool (ConfigResp);
//
// 3. Config success, update storage shadow Buffer, only update the data belong to this form.
@@ -2670,69 +2562,19 @@ SubmitForm (
return Status;
}
- if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
- Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
-
- //
- // 2. Send <ConfigResp> to Configuration Driver
- //
- if (FormSet->ConfigAccess != NULL) {
- Status = FormSet->ConfigAccess->RouteConfig (
- FormSet->ConfigAccess,
- ConfigResp,
- &Progress
- );
- if (EFI_ERROR (Status)) {
- FreePool (ConfigResp);
- return Status;
- }
- }
- } else if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
- //
- // 1&2. Set the edit data to the variable.
- //
- TmpBuf = NULL;
- TmpBuf = AllocateZeroPool (Storage->Size);
- if (TmpBuf == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- return Status;
- }
- BufferSize = Storage->Size;
- Status = gRT->GetVariable (
- Storage->Name,
- &Storage->Guid,
- NULL,
- &BufferSize,
- TmpBuf
- );
- ASSERT (BufferSize == Storage->Size);
- Status = mHiiConfigRouting->ConfigToBlock (
- mHiiConfigRouting,
- ConfigResp,
- TmpBuf,
- &BufferSize,
- &Progress
- );
- if (EFI_ERROR (Status)) {
- FreePool (TmpBuf);
- FreePool (ConfigResp);
- return Status;
- }
-
- Status = gRT->SetVariable (
- Storage->Name,
- &Storage->Guid,
- Storage->Attributes,
- Storage->Size,
- TmpBuf
- );
- if (EFI_ERROR (Status)) {
- FreePool (TmpBuf);
- FreePool (ConfigResp);
- return Status;
- }
- FreePool (TmpBuf);
+ //
+ // 2. Send <ConfigResp> to Routine config Protocol.
+ //
+ Status = mHiiConfigRouting->RouteConfig (
+ mHiiConfigRouting,
+ ConfigResp,
+ &Progress
+ );
+ if (EFI_ERROR (Status)) {
+ FreePool (ConfigResp);
+ return Status;
}
+
FreePool (ConfigResp);
//
// 3. Config success, update storage shadow Buffer
@@ -2817,9 +2659,7 @@ GetDefaultValueFromAltCfg (
Value = NULL;
Storage = Question->Storage;
- if ((Storage == NULL) ||
- (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) ||
- (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
+ if ((Storage == NULL) || (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {
return Status;
}
@@ -2838,7 +2678,11 @@ GetDefaultValueFromAltCfg (
Dst = (UINT8 *) &Question->HiiValue.Value;
}
- IsBufferStorage = (BOOLEAN) ((Storage->Type == EFI_HII_VARSTORE_BUFFER) ? TRUE : FALSE);
+ if (Storage->Type == EFI_HII_VARSTORE_BUFFER || Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
+ IsBufferStorage = TRUE;
+ } else {
+ IsBufferStorage = FALSE;
+ }
IsString = (BOOLEAN) ((Question->HiiValue.Type == EFI_IFR_TYPE_STRING) ? TRUE : FALSE);
//
@@ -2863,8 +2707,8 @@ GetDefaultValueFromAltCfg (
StrCat (ConfigRequest, Question->VariableName);
}
- Status = FormSet->ConfigAccess->ExtractConfig (
- FormSet->ConfigAccess,
+ Status = mHiiConfigRouting->ExtractConfig (
+ mHiiConfigRouting,
ConfigRequest,
&Progress,
&Result
@@ -2894,6 +2738,11 @@ GetDefaultValueFromAltCfg (
goto Done;
}
+ if (ConfigResp == NULL) {
+ Status = EFI_NOT_FOUND;
+ goto Done;
+ }
+
//
// Skip <ConfigRequest>
//
@@ -3880,18 +3729,20 @@ CleanBrowserStorage (
Storage = FORMSET_STORAGE_FROM_LINK (Link);
Link = GetNextNode (&FormSet->StorageListHead, Link);
- if ((Storage->BrowserStorage->Type != EFI_HII_VARSTORE_BUFFER) &&
- (Storage->BrowserStorage->Type != EFI_HII_VARSTORE_NAME_VALUE) &&
- (Storage->BrowserStorage->Type != EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
- continue;
- }
+ if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
+ if (Storage->ConfigRequest == NULL || Storage->BrowserStorage->ConfigRequest == NULL) {
+ continue;
+ }
- if (Storage->ConfigRequest == NULL || Storage->BrowserStorage->ConfigRequest == NULL) {
- continue;
+ ConfigRequest = FormSet->QuestionInited ? Storage->ConfigRequest : Storage->ConfigElements;
+ RemoveConfigRequest (Storage->BrowserStorage, ConfigRequest);
+ } else if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_BUFFER ||
+ Storage->BrowserStorage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
+ if (Storage->BrowserStorage->ConfigRequest != NULL) {
+ FreePool (Storage->BrowserStorage->ConfigRequest);
+ }
+ Storage->BrowserStorage->Initialized = FALSE;
}
-
- ConfigRequest = FormSet->QuestionInited ? Storage->ConfigRequest : Storage->ConfigElements;
- RemoveConfigRequest (Storage->BrowserStorage, ConfigRequest);
}
}
@@ -4244,86 +4095,57 @@ LoadStorage (
ConfigRequestAdjust(Storage);
return;
}
-
- Status = gRT->GetVariable (
- Storage->BrowserStorage->Name,
- &Storage->BrowserStorage->Guid,
- NULL,
- (UINTN*)&Storage->BrowserStorage->Size,
- Storage->BrowserStorage->EditBuffer
- );
- //
- // If get variable fail, extract default from IFR binary
- //
- if (EFI_ERROR (Status)) {
- ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForStorage, Storage->BrowserStorage, TRUE);
- }
-
- Storage->BrowserStorage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);
- //
- // Input NULL for ConfigRequest field means sync all fields from editbuffer to buffer.
- //
- SynchronizeStorage(FormSet, Storage->BrowserStorage, NULL, TRUE);
break;
case EFI_HII_VARSTORE_BUFFER:
case EFI_HII_VARSTORE_NAME_VALUE:
//
- // Skip if there is no RequestElement
+ // Skip if there is no RequestElement or data has initilized.
//
- if (Storage->ElementCount == 0) {
+ if (Storage->ElementCount == 0 || Storage->BrowserStorage->Initialized) {
return;
}
+ Storage->BrowserStorage->Initialized = TRUE;
+ break;
- //
- // Adjust the ConfigRequest string, only the field not saved in BrowserStorage->AllConfig
- // will used to call ExtractConfig.
- // If not elements need to udpate, return.
- //
- if (!ConfigRequestAdjust(Storage)) {
- return;
- }
- ASSERT (Storage->ConfigElements != NULL);
+ default:
+ return;
+ }
- Status = EFI_NOT_FOUND;
- if (FormSet->ConfigAccess != NULL) {
- //
- // Request current settings from Configuration Driver
- //
- Status = FormSet->ConfigAccess->ExtractConfig (
- FormSet->ConfigAccess,
- Storage->ConfigElements,
- &Progress,
- &Result
- );
-
- if (!EFI_ERROR (Status)) {
- //
- // Convert Result from <ConfigAltResp> to <ConfigResp>
- //
- StrPtr = StrStr (Result, L"&GUID=");
- if (StrPtr != NULL) {
- *StrPtr = L'\0';
- }
-
- Status = ConfigRespToStorage (Storage->BrowserStorage, Result);
- FreePool (Result);
- }
- }
+ //
+ // Request current settings from Configuration Driver
+ //
+ Status = mHiiConfigRouting->ExtractConfig (
+ mHiiConfigRouting,
+ Storage->ConfigRequest,
+ &Progress,
+ &Result
+ );
- if (EFI_ERROR (Status)) {
- //
- // Base on the configRequest string to get default value.
- //
- GetDefaultForFormset (FormSet, Storage->BrowserStorage, Storage->ConfigElements);
- }
+ //
+ // If get value fail, extract default from IFR binary
+ //
+ if (EFI_ERROR (Status)) {
+ ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForStorage, Storage->BrowserStorage, TRUE);
+ } else {
+ //
+ // Convert Result from <ConfigAltResp> to <ConfigResp>
+ //
+ StrPtr = StrStr (Result, L"&GUID=");
+ if (StrPtr != NULL) {
+ *StrPtr = L'\0';
+ }
+
+ Status = ConfigRespToStorage (Storage->BrowserStorage, Result);
+ FreePool (Result);
+ }
- SynchronizeStorage(FormSet, Storage->BrowserStorage, Storage->ConfigElements, TRUE);
- break;
+ Storage->BrowserStorage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);
- default:
- break;
- }
+ //
+ // Input NULL for ConfigRequest field means sync all fields from editbuffer to buffer.
+ //
+ SynchronizeStorage(FormSet, Storage->BrowserStorage, NULL, TRUE);
}
/**
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
index 77a0ad1ba..9cb4653c8 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
@@ -136,6 +136,9 @@ typedef struct {
UINT8 Type; // Storage type
+ BOOLEAN Initialized; // Whether this varstore is initialized, efi varstore not used.
+
+ EFI_HII_HANDLE HiiHandle; // HiiHandle for this varstore, efi varstore not used.
EFI_GUID Guid;
CHAR16 *Name; // For EFI_IFR_VARSTORE
@@ -1613,5 +1616,25 @@ VOID
CleanBrowserStorage (
IN OUT FORM_BROWSER_FORMSET *FormSet
);
-
+
+/**
+ Find HII Handle in the HII database associated with given Device Path.
+
+ If DevicePath is NULL, then ASSERT.
+
+ @param DevicePath Device Path associated with the HII package list
+ handle.
+ @param FormsetGuid The formset guid for this formset.
+
+ @retval Handle HII package list Handle associated with the Device
+ Path.
+ @retval NULL Hii Package list handle is not found.
+
+**/
+EFI_HII_HANDLE
+DevicePathToHiiHandle (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN EFI_GUID *FormsetGuid
+ );
+
#endif
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Reclaim.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Reclaim.c
index 11bf1a02b..1732a0cd6 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Reclaim.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Reclaim.c
@@ -3,7 +3,7 @@
Handles non-volatile variable store garbage collection, using FTW
(Fault Tolerant Write) protocol.
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -99,8 +99,7 @@ GetLbaAndOffsetByAddress (
VariableBase. Fault Tolerant Write protocol is used for writing.
@param VariableBase Base address of variable to write
- @param Buffer Point to the data buffer.
- @param BufferSize The number of bytes of the data Buffer.
+ @param VariableBuffer Point to the variable data buffer.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND Fail to locate Fault Tolerant Write protocol.
@@ -110,15 +109,13 @@ GetLbaAndOffsetByAddress (
EFI_STATUS
FtwVariableSpace (
IN EFI_PHYSICAL_ADDRESS VariableBase,
- IN UINT8 *Buffer,
- IN UINTN BufferSize
+ IN VARIABLE_STORE_HEADER *VariableBuffer
)
{
EFI_STATUS Status;
EFI_HANDLE FvbHandle;
EFI_LBA VarLba;
UINTN VarOffset;
- UINT8 *FtwBuffer;
UINTN FtwBufferSize;
EFI_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol;
@@ -143,17 +140,9 @@ FtwVariableSpace (
if (EFI_ERROR (Status)) {
return EFI_ABORTED;
}
- //
- // Prepare for the variable data.
- //
- FtwBufferSize = ((VARIABLE_STORE_HEADER *) ((UINTN) VariableBase))->Size;
- FtwBuffer = AllocatePool (FtwBufferSize);
- if (FtwBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- SetMem (FtwBuffer, FtwBufferSize, (UINT8) 0xff);
- CopyMem (FtwBuffer, Buffer, BufferSize);
+ FtwBufferSize = ((VARIABLE_STORE_HEADER *) ((UINTN) VariableBase))->Size;
+ ASSERT (FtwBufferSize == VariableBuffer->Size);
//
// FTW write record.
@@ -165,9 +154,8 @@ FtwVariableSpace (
FtwBufferSize, // NumBytes
NULL, // PrivateData NULL
FvbHandle, // Fvb Handle
- FtwBuffer // write buffer
+ (VOID *) VariableBuffer // write buffer
);
- FreePool (FtwBuffer);
return Status;
}
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
index 51dd0fd6f..c66eb8750 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
@@ -566,7 +566,8 @@ GetEndPointer (
@param IsVolatile The variable store is volatile or not;
if it is non-volatile, need FTW.
@param UpdatingPtrTrack Pointer to updating variable pointer track structure.
- @param ReclaimAnyway If TRUE, do reclaim anyway.
+ @param NewVariable Pointer to new variable.
+ @param NewVariableSize New variable size.
@return EFI_OUT_OF_RESOURCES
@return EFI_SUCCESS
@@ -579,7 +580,8 @@ Reclaim (
OUT UINTN *LastVariableOffset,
IN BOOLEAN IsVolatile,
IN OUT VARIABLE_POINTER_TRACK *UpdatingPtrTrack,
- IN BOOLEAN ReclaimAnyway
+ IN VARIABLE_HEADER *NewVariable,
+ IN UINTN NewVariableSize
)
{
VARIABLE_HEADER *Variable;
@@ -590,65 +592,72 @@ Reclaim (
UINT8 *ValidBuffer;
UINTN MaximumBufferSize;
UINTN VariableSize;
- UINTN VariableNameSize;
- UINTN UpdatingVariableNameSize;
UINTN NameSize;
UINT8 *CurrPtr;
VOID *Point0;
VOID *Point1;
BOOLEAN FoundAdded;
EFI_STATUS Status;
- CHAR16 *VariableNamePtr;
- CHAR16 *UpdatingVariableNamePtr;
UINTN CommonVariableTotalSize;
UINTN HwErrVariableTotalSize;
- BOOLEAN NeedDoReclaim;
VARIABLE_HEADER *UpdatingVariable;
+ VARIABLE_HEADER *UpdatingInDeletedTransition;
UpdatingVariable = NULL;
+ UpdatingInDeletedTransition = NULL;
if (UpdatingPtrTrack != NULL) {
UpdatingVariable = UpdatingPtrTrack->CurrPtr;
+ UpdatingInDeletedTransition = UpdatingPtrTrack->InDeletedTransitionPtr;
}
- NeedDoReclaim = FALSE;
VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase);
CommonVariableTotalSize = 0;
HwErrVariableTotalSize = 0;
- //
- // Start Pointers for the variable.
- //
- Variable = GetStartPointer (VariableStoreHeader);
- MaximumBufferSize = sizeof (VARIABLE_STORE_HEADER);
+ if (IsVolatile) {
+ //
+ // Start Pointers for the variable.
+ //
+ Variable = GetStartPointer (VariableStoreHeader);
+ MaximumBufferSize = sizeof (VARIABLE_STORE_HEADER);
- while (IsValidVariableHeader (Variable)) {
- NextVariable = GetNextVariablePtr (Variable);
- if (Variable->State == VAR_ADDED ||
- Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)
- ) {
- VariableSize = (UINTN) NextVariable - (UINTN) Variable;
- MaximumBufferSize += VariableSize;
- } else {
- NeedDoReclaim = TRUE;
- }
+ while (IsValidVariableHeader (Variable)) {
+ NextVariable = GetNextVariablePtr (Variable);
+ if ((Variable->State == VAR_ADDED || Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) &&
+ Variable != UpdatingVariable &&
+ Variable != UpdatingInDeletedTransition
+ ) {
+ VariableSize = (UINTN) NextVariable - (UINTN) Variable;
+ MaximumBufferSize += VariableSize;
+ }
- Variable = NextVariable;
- }
+ Variable = NextVariable;
+ }
- if (!ReclaimAnyway && !NeedDoReclaim) {
- DEBUG ((EFI_D_INFO, "Variable driver: no DELETED variable found, so no variable space could be reclaimed.\n"));
- return EFI_SUCCESS;
- }
+ if (NewVariable != NULL) {
+ //
+ // Add the new variable size.
+ //
+ MaximumBufferSize += NewVariableSize;
+ }
- //
- // Reserve the 1 Bytes with Oxff to identify the
- // end of the variable buffer.
- //
- MaximumBufferSize += 1;
- ValidBuffer = AllocatePool (MaximumBufferSize);
- if (ValidBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
+ //
+ // Reserve the 1 Bytes with Oxff to identify the
+ // end of the variable buffer.
+ //
+ MaximumBufferSize += 1;
+ ValidBuffer = AllocatePool (MaximumBufferSize);
+ if (ValidBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ } else {
+ //
+ // For NV variable reclaim, don't allocate pool here and just use mNvVariableCache
+ // as the buffer to reduce SMRAM consumption for SMM variable driver.
+ //
+ MaximumBufferSize = mNvVariableCache->Size;
+ ValidBuffer = (UINT8 *) mNvVariableCache;
}
SetMem (ValidBuffer, MaximumBufferSize, 0xff);
@@ -665,25 +674,7 @@ Reclaim (
Variable = GetStartPointer (VariableStoreHeader);
while (IsValidVariableHeader (Variable)) {
NextVariable = GetNextVariablePtr (Variable);
- if (Variable->State == VAR_ADDED) {
- if (UpdatingVariable != NULL) {
- if (UpdatingVariable == Variable) {
- Variable = NextVariable;
- continue;
- }
-
- VariableNameSize = NameSizeOfVariable(Variable);
- UpdatingVariableNameSize = NameSizeOfVariable(UpdatingVariable);
-
- VariableNamePtr = GetVariableNamePtr (Variable);
- UpdatingVariableNamePtr = GetVariableNamePtr (UpdatingVariable);
- if (CompareGuid (&Variable->VendorGuid, &UpdatingVariable->VendorGuid) &&
- VariableNameSize == UpdatingVariableNameSize &&
- CompareMem (VariableNamePtr, UpdatingVariableNamePtr, VariableNameSize) == 0 ) {
- Variable = NextVariable;
- continue;
- }
- }
+ if (Variable != UpdatingVariable && Variable->State == VAR_ADDED) {
VariableSize = (UINTN) NextVariable - (UINTN) Variable;
CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize);
CurrPtr += VariableSize;
@@ -697,28 +688,12 @@ Reclaim (
}
//
- // Reinstall the variable being updated if it is not NULL.
- //
- if (UpdatingVariable != NULL) {
- VariableSize = (UINTN)(GetNextVariablePtr (UpdatingVariable)) - (UINTN)UpdatingVariable;
- CopyMem (CurrPtr, (UINT8 *) UpdatingVariable, VariableSize);
- UpdatingPtrTrack->CurrPtr = (VARIABLE_HEADER *)((UINTN)UpdatingPtrTrack->StartPtr + ((UINTN)CurrPtr - (UINTN)GetStartPointer ((VARIABLE_STORE_HEADER *) ValidBuffer)));
- UpdatingPtrTrack->InDeletedTransitionPtr = NULL;
- CurrPtr += VariableSize;
- if ((!IsVolatile) && ((UpdatingVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
- HwErrVariableTotalSize += VariableSize;
- } else if ((!IsVolatile) && ((UpdatingVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
- CommonVariableTotalSize += VariableSize;
- }
- }
-
- //
// Reinstall all in delete transition variables.
//
- Variable = GetStartPointer (VariableStoreHeader);
+ Variable = GetStartPointer (VariableStoreHeader);
while (IsValidVariableHeader (Variable)) {
NextVariable = GetNextVariablePtr (Variable);
- if (Variable != UpdatingVariable && Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
+ if (Variable != UpdatingVariable && Variable != UpdatingInDeletedTransition && Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
//
// Buffer has cached all ADDED variable.
@@ -762,12 +737,49 @@ Reclaim (
Variable = NextVariable;
}
+ //
+ // Install the new variable if it is not NULL.
+ //
+ if (NewVariable != NULL) {
+ if ((UINTN) (CurrPtr - ValidBuffer) + NewVariableSize > VariableStoreHeader->Size) {
+ //
+ // No enough space to store the new variable.
+ //
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ if (!IsVolatile) {
+ if ((NewVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ HwErrVariableTotalSize += NewVariableSize;
+ } else if ((NewVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ CommonVariableTotalSize += NewVariableSize;
+ }
+ if ((HwErrVariableTotalSize > PcdGet32 (PcdHwErrStorageSize)) ||
+ (CommonVariableTotalSize > VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize))) {
+ //
+ // No enough space to store the new variable by NV or NV+HR attribute.
+ //
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ }
+
+ CopyMem (CurrPtr, (UINT8 *) NewVariable, NewVariableSize);
+ ((VARIABLE_HEADER *) CurrPtr)->State = VAR_ADDED;
+ if (UpdatingVariable != NULL) {
+ UpdatingPtrTrack->CurrPtr = (VARIABLE_HEADER *)((UINTN)UpdatingPtrTrack->StartPtr + ((UINTN)CurrPtr - (UINTN)GetStartPointer ((VARIABLE_STORE_HEADER *) ValidBuffer)));
+ UpdatingPtrTrack->InDeletedTransitionPtr = NULL;
+ }
+ CurrPtr += NewVariableSize;
+ }
+
if (IsVolatile) {
//
// If volatile variable store, just copy valid buffer.
//
SetMem ((UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size, 0xff);
- CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) (CurrPtr - (UINT8 *) ValidBuffer));
+ CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) (CurrPtr - ValidBuffer));
+ *LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer);
Status = EFI_SUCCESS;
} else {
//
@@ -775,33 +787,37 @@ Reclaim (
//
Status = FtwVariableSpace (
VariableBase,
- ValidBuffer,
- (UINTN) (CurrPtr - (UINT8 *) ValidBuffer)
+ (VARIABLE_STORE_HEADER *) ValidBuffer
);
- CopyMem (mNvVariableCache, (CHAR8 *)(UINTN)VariableBase, VariableStoreHeader->Size);
- }
- if (!EFI_ERROR (Status)) {
- *LastVariableOffset = (UINTN) (CurrPtr - (UINT8 *) ValidBuffer);
- if (!IsVolatile) {
+ if (!EFI_ERROR (Status)) {
+ *LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer);
mVariableModuleGlobal->HwErrVariableTotalSize = HwErrVariableTotalSize;
mVariableModuleGlobal->CommonVariableTotalSize = CommonVariableTotalSize;
- }
- } else {
- NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase);
- while (IsValidVariableHeader (NextVariable)) {
- VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER);
- if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
- mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize);
- } else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
- mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize);
- }
+ } else {
+ NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase);
+ while (IsValidVariableHeader (NextVariable)) {
+ VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER);
+ if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize);
+ } else if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize);
+ }
- NextVariable = GetNextVariablePtr (NextVariable);
+ NextVariable = GetNextVariablePtr (NextVariable);
+ }
+ *LastVariableOffset = (UINTN) NextVariable - (UINTN) VariableBase;
}
- *LastVariableOffset = (UINTN) NextVariable - (UINTN) VariableBase;
}
- FreePool (ValidBuffer);
+Done:
+ if (IsVolatile) {
+ FreePool (ValidBuffer);
+ } else {
+ //
+ // For NV variable reclaim, we use mNvVariableCache as the buffer, so copy the data back.
+ //
+ CopyMem (mNvVariableCache, (UINT8 *)(UINTN)VariableBase, VariableStoreHeader->Size);
+ }
return Status;
}
@@ -1706,27 +1722,22 @@ UpdateVariable (
goto Done;
}
//
- // Perform garbage collection & reclaim operation.
+ // Perform garbage collection & reclaim operation, and integrate the new variable at the same time.
//
Status = Reclaim (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
- &mVariableModuleGlobal->NonVolatileLastVariableOffset, FALSE, Variable, FALSE);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
- //
- // If still no enough space, return out of resources.
- //
- if ((((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0)
- && ((VarSize + mVariableModuleGlobal->HwErrVariableTotalSize) > PcdGet32 (PcdHwErrStorageSize)))
- || (((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 0)
- && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > NonVolatileVarableStoreSize - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize)))) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
- if (Variable->CurrPtr != NULL) {
- CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) Variable->StartPtr));
- CacheVariable->InDeletedTransitionPtr = NULL;
+ &mVariableModuleGlobal->NonVolatileLastVariableOffset, FALSE, Variable, NextVariable, HEADER_ALIGN (VarSize));
+ if (!EFI_ERROR (Status)) {
+ //
+ // The new variable has been integrated successfully during reclaiming.
+ //
+ if (Variable->CurrPtr != NULL) {
+ CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) Variable->StartPtr));
+ CacheVariable->InDeletedTransitionPtr = NULL;
+ }
+ UpdateVariableInfo (VariableName, VendorGuid, FALSE, FALSE, TRUE, FALSE, FALSE);
+ FlushHobVariableToFlash (VariableName, VendorGuid);
}
+ goto Done;
}
//
// Four steps
@@ -1824,26 +1835,21 @@ UpdateVariable (
if ((UINT32) (VarSize + mVariableModuleGlobal->VolatileLastVariableOffset) >
((VARIABLE_STORE_HEADER *) ((UINTN) (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase)))->Size) {
//
- // Perform garbage collection & reclaim operation.
+ // Perform garbage collection & reclaim operation, and integrate the new variable at the same time.
//
Status = Reclaim (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase,
- &mVariableModuleGlobal->VolatileLastVariableOffset, TRUE, Variable, FALSE);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
- //
- // If still no enough space, return out of resources.
- //
- if ((UINT32) (VarSize + mVariableModuleGlobal->VolatileLastVariableOffset) >
- ((VARIABLE_STORE_HEADER *) ((UINTN) (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase)))->Size
- ) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
- if (Variable->CurrPtr != NULL) {
- CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) Variable->StartPtr));
- CacheVariable->InDeletedTransitionPtr = NULL;
+ &mVariableModuleGlobal->VolatileLastVariableOffset, TRUE, Variable, NextVariable, HEADER_ALIGN (VarSize));
+ if (!EFI_ERROR (Status)) {
+ //
+ // The new variable has been integrated successfully during reclaiming.
+ //
+ if (Variable->CurrPtr != NULL) {
+ CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) Variable->StartPtr));
+ CacheVariable->InDeletedTransitionPtr = NULL;
+ }
+ UpdateVariableInfo (VariableName, VendorGuid, TRUE, FALSE, TRUE, FALSE, FALSE);
}
+ goto Done;
}
NextVariable->State = VAR_ADDED;
@@ -2693,7 +2699,8 @@ ReclaimForOS(
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
FALSE,
NULL,
- FALSE
+ NULL,
+ 0
);
ASSERT_EFI_ERROR (Status);
}
@@ -2963,7 +2970,8 @@ VariableWriteServiceInitialize (
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
FALSE,
NULL,
- TRUE
+ NULL,
+ 0
);
if (EFI_ERROR (Status)) {
return Status;
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
index a10ad8755..9c8626cdc 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
@@ -133,8 +133,7 @@ FlushHobVariableToFlash (
VariableBase. Fault Tolerant Write protocol is used for writing.
@param VariableBase Base address of the variable to write.
- @param Buffer Point to the data buffer.
- @param BufferSize The number of bytes of the data Buffer.
+ @param VariableBuffer Point to the variable data buffer.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND Fail to locate Fault Tolerant Write protocol.
@@ -144,8 +143,7 @@ FlushHobVariableToFlash (
EFI_STATUS
FtwVariableSpace (
IN EFI_PHYSICAL_ADDRESS VariableBase,
- IN UINT8 *Buffer,
- IN UINTN BufferSize
+ IN VARIABLE_STORE_HEADER *VariableBuffer
);