/** @file\r
Framework PEIM to initialize memory on a Quark Memory Controller.\r
\r
-Copyright (c) 2013 Intel Corporation.\r
+Copyright (c) 2013 - 2016, Intel Corporation.\r
\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
PEI_CAPSULE_PPI *Capsule;\r
VOID *LargeMemRangeBuf;\r
UINTN LargeMemRangeBufLen;\r
+ UINT8 MorControl;\r
+ UINTN DataSize;\r
\r
//\r
// Test the memory from 1M->TOM\r
RequiredMemSize = 0;\r
RetriveRequiredMemorySize (PeiServices, &RequiredMemSize);\r
\r
+ //\r
+ // Detect MOR request by the OS.\r
+ //\r
+ MorControl = 0;\r
+ DataSize = sizeof (MorControl);\r
+ Status = VariableServices->GetVariable (\r
+ VariableServices,\r
+ MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,\r
+ &gEfiMemoryOverwriteControlDataGuid,\r
+ NULL,\r
+ &DataSize,\r
+ &MorControl\r
+ );\r
+\r
PeiMemoryIndex = 0;\r
\r
for (Index = 0; Index < NumRanges; Index++)\r
DEBUG ((EFI_D_INFO, "Found 0x%x bytes at ", MemoryMap[Index].RangeLength));\r
DEBUG ((EFI_D_INFO, "0x%x.\n", MemoryMap[Index].PhysicalAddress));\r
\r
+ //\r
+ // If OS requested a memory overwrite perform it now. Only do it for memory\r
+ // used by the OS.\r
+ //\r
+ if (MOR_CLEAR_MEMORY_VALUE (MorControl) && MemoryMap[Index].Type == DualChannelDdrMainMemory) {\r
+ DEBUG ((EFI_D_INFO, "Clear memory per MOR request.\n"));\r
+ if ((UINTN)MemoryMap[Index].RangeLength > 0) {\r
+ if ((UINTN)MemoryMap[Index].PhysicalAddress == 0) {\r
+ //\r
+ // ZeroMem() generates an ASSERT() if Buffer parameter is NULL.\r
+ // Clear byte at 0 and start clear operation at address 1.\r
+ //\r
+ *(UINT8 *)(0) = 0;\r
+ ZeroMem ((VOID *)1, (UINTN)MemoryMap[Index].RangeLength - 1);\r
+ } else {\r
+ ZeroMem (\r
+ (VOID *)(UINTN)MemoryMap[Index].PhysicalAddress,\r
+ (UINTN)MemoryMap[Index].RangeLength\r
+ );\r
+ }\r
+ }\r
+ }\r
+\r
if ((MemoryMap[Index].Type == DualChannelDdrMainMemory) &&\r
(MemoryMap[Index].PhysicalAddress + MemoryMap[Index].RangeLength < MAX_ADDRESS) &&\r
(MemoryMap[Index].PhysicalAddress >= PeiMemoryBaseAddress) &&\r
// memory above 1MB. So Memory Callback can set cache for the system memory\r
// correctly on S3 boot path, just like it does on Normal boot path.\r
//\r
- ASSERT_EFI_ERROR ((S3MemoryRangeData->SystemMemoryLength - 0x100000) > 0);\r
+ ASSERT ((S3MemoryRangeData->SystemMemoryLength - 0x100000) > 0);\r
BuildResourceDescriptorHob (\r
EFI_RESOURCE_SYSTEM_MEMORY,\r
(\r
OUT UINTN *Size\r
)\r
{\r
- EFI_STATUS Status;\r
EFI_PEI_HOB_POINTERS Hob;\r
EFI_MEMORY_TYPE_INFORMATION *MemoryData;\r
UINT8 Index;\r
TempPageNum = 0;\r
Index = 0;\r
\r
- Status = PeiServicesGetHobList ((VOID **)&Hob.Raw);\r
+ PeiServicesGetHobList ((VOID **)&Hob.Raw);\r
while (!END_OF_HOB_LIST (Hob)) {\r
if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION &&\r
CompareGuid (&Hob.Guid->Name, &gEfiMemoryTypeInformationGuid)\r
PEI_MEMORY_RANGE_SMRAM SmramMask;\r
PEI_MEMORY_RANGE_SMRAM TsegMask;\r
UINT32 BlockNum;\r
- UINT8 EsmramcRegister;\r
UINT8 ExtendedMemoryIndex;\r
UINT32 Register;\r
\r
//\r
// Generate Memory ranges for the memory map.\r
//\r
- EsmramcRegister = 0;\r
MemorySize = 0;\r
\r
RowLength = TotalMemorySize;\r