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")); @@ -151,6 +154,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 // 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) &&