summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--QuarkPlatformPkg/Platform/Pei/PlatformInit/MemoryCallback.c51
-rw-r--r--QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.c41
2 files changed, 90 insertions, 2 deletions
diff --git a/QuarkPlatformPkg/Platform/Pei/PlatformInit/MemoryCallback.c b/QuarkPlatformPkg/Platform/Pei/PlatformInit/MemoryCallback.c
index 728e2b1f6b..d5fb94195d 100644
--- a/QuarkPlatformPkg/Platform/Pei/PlatformInit/MemoryCallback.c
+++ b/QuarkPlatformPkg/Platform/Pei/PlatformInit/MemoryCallback.c
@@ -7,7 +7,7 @@ following action is performed in this file,
4. Set MTRR for PEI
5. Create FV HOB and Flash HOB
-Copyright (c) 2013 Intel Corporation.
+Copyright (c) 2013 - 2016, Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -108,6 +108,9 @@ MemoryDiscoveredPpiNotifyCallback (
UINT8 CpuAddressWidth;
UINT32 RegEax;
MTRR_SETTINGS MtrrSettings;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
+ UINT8 MorControl;
+ UINTN DataSize;
DEBUG ((EFI_D_INFO, "Platform PEIM Memory Callback\n"));
@@ -152,6 +155,52 @@ MemoryDiscoveredPpiNotifyCallback (
PERF_END (NULL, "SetCache", NULL, 0);
//
+ // Get necessary PPI
+ //
+ Status = PeiServicesLocatePpi (
+ &gEfiPeiReadOnlyVariable2PpiGuid, // GUID
+ 0, // INSTANCE
+ NULL, // EFI_PEI_PPI_DESCRIPTOR
+ (VOID **)&VariableServices // PPI
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Detect MOR request by the OS.
+ //
+ MorControl = 0;
+ DataSize = sizeof (MorControl);
+ Status = VariableServices->GetVariable (
+ VariableServices,
+ MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
+ &gEfiMemoryOverwriteControlDataGuid,
+ NULL,
+ &DataSize,
+ &MorControl
+ );
+ //
+ // If OS requested a memory overwrite perform it now for Embedded SRAM
+ //
+ if (MOR_CLEAR_MEMORY_VALUE (MorControl)) {
+ DEBUG ((EFI_D_INFO, "Clear Embedded SRAM per MOR request.\n"));
+ if (PcdGet32 (PcdESramMemorySize) > 0) {
+ if (PcdGet32 (PcdEsramStage1Base) == 0) {
+ //
+ // ZeroMem() generates an ASSERT() if Buffer parameter is NULL.
+ // Clear byte at 0 and start clear operation at address 1.
+ //
+ *(UINT8 *)(0) = 0;
+ ZeroMem ((VOID *)1, (UINTN)PcdGet32 (PcdESramMemorySize) - 1);
+ } else {
+ ZeroMem (
+ (VOID *)(UINTN)PcdGet32 (PcdEsramStage1Base),
+ (UINTN)PcdGet32 (PcdESramMemorySize)
+ );
+ }
+ }
+ }
+
+ //
// Install PeiReset for PeiResetSystem service
//
Status = PeiServicesInstallPpi (&mPpiList[0]);
diff --git a/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.c b/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.c
index eee696e0e7..70c9cf98a0 100644
--- a/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.c
+++ b/QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.c
@@ -1,7 +1,7 @@
/** @file
Framework PEIM to initialize memory on a Quark Memory Controller.
-Copyright (c) 2013 Intel Corporation.
+Copyright (c) 2013 - 2016, Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -563,6 +563,8 @@ InstallEfiMemory (
PEI_CAPSULE_PPI *Capsule;
VOID *LargeMemRangeBuf;
UINTN LargeMemRangeBufLen;
+ UINT8 MorControl;
+ UINTN DataSize;
//
// Test the memory from 1M->TOM
@@ -617,6 +619,20 @@ InstallEfiMemory (
RequiredMemSize = 0;
RetriveRequiredMemorySize (PeiServices, &RequiredMemSize);
+ //
+ // Detect MOR request by the OS.
+ //
+ MorControl = 0;
+ DataSize = sizeof (MorControl);
+ Status = VariableServices->GetVariable (
+ VariableServices,
+ MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
+ &gEfiMemoryOverwriteControlDataGuid,
+ NULL,
+ &DataSize,
+ &MorControl
+ );
+
PeiMemoryIndex = 0;
for (Index = 0; Index < NumRanges; Index++)
@@ -624,6 +640,29 @@ InstallEfiMemory (
DEBUG ((EFI_D_INFO, "Found 0x%x bytes at ", MemoryMap[Index].RangeLength));
DEBUG ((EFI_D_INFO, "0x%x.\n", MemoryMap[Index].PhysicalAddress));
+ //
+ // If OS requested a memory overwrite perform it now. Only do it for memory
+ // used by the OS.
+ //
+ if (MOR_CLEAR_MEMORY_VALUE (MorControl) && MemoryMap[Index].Type == DualChannelDdrMainMemory) {
+ DEBUG ((EFI_D_INFO, "Clear memory per MOR request.\n"));
+ if ((UINTN)MemoryMap[Index].RangeLength > 0) {
+ if ((UINTN)MemoryMap[Index].PhysicalAddress == 0) {
+ //
+ // ZeroMem() generates an ASSERT() if Buffer parameter is NULL.
+ // Clear byte at 0 and start clear operation at address 1.
+ //
+ *(UINT8 *)(0) = 0;
+ ZeroMem ((VOID *)1, (UINTN)MemoryMap[Index].RangeLength - 1);
+ } else {
+ ZeroMem (
+ (VOID *)(UINTN)MemoryMap[Index].PhysicalAddress,
+ (UINTN)MemoryMap[Index].RangeLength
+ );
+ }
+ }
+ }
+
if ((MemoryMap[Index].Type == DualChannelDdrMainMemory) &&
(MemoryMap[Index].PhysicalAddress + MemoryMap[Index].RangeLength < MAX_ADDRESS) &&
(MemoryMap[Index].PhysicalAddress >= PeiMemoryBaseAddress) &&