]> git.proxmox.com Git - mirror_edk2.git/blobdiff - QuarkPlatformPkg/Platform/Pei/PlatformInit/MrcWrapper.c
QuarkPlatformPkg/PlatformInit: Fix recovery detection issues
[mirror_edk2.git] / QuarkPlatformPkg / Platform / Pei / PlatformInit / MrcWrapper.c
index eee696e0e7f000dc617b11606ebfd82215f54670..7b7ca61817e94fec66b57484e694cf3aceb8a816 100644 (file)
@@ -1,7 +1,7 @@
 /** @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
@@ -554,7 +554,6 @@ InstallEfiMemory (
   UINT64                                PeiMemoryLength;\r
   UINTN                                 BufferSize;\r
   UINTN                                 PeiMemoryIndex;\r
-  UINTN                                 RequiredMemSize;\r
   EFI_RESOURCE_ATTRIBUTE_TYPE           Attribute;\r
   EFI_PHYSICAL_ADDRESS                  BadMemoryAddress;\r
   EFI_SMRAM_DESCRIPTOR                  DescriptorAcpiVariable;\r
@@ -563,6 +562,8 @@ InstallEfiMemory (
   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
@@ -612,10 +613,18 @@ InstallEfiMemory (
   ASSERT_EFI_ERROR (Status);\r
 \r
   //\r
-  // Get required memory size for ACPI use. This helps to put ACPI memory on the topest\r
+  // Detect MOR request by the OS.\r
   //\r
-  RequiredMemSize = 0;\r
-  RetriveRequiredMemorySize (PeiServices, &RequiredMemSize);\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
@@ -624,6 +633,29 @@ InstallEfiMemory (
     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
@@ -696,15 +728,14 @@ InstallEfiMemory (
   //\r
   Status = SetPlatformImrPolicy (\r
               PeiMemoryBaseAddress,\r
-              PeiMemoryLength,\r
-              RequiredMemSize\r
+              PeiMemoryLength\r
               );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   //\r
   // Carve out the top memory reserved for ACPI\r
   //\r
-  Status        = PeiServicesInstallPeiMemory (PeiMemoryBaseAddress, (PeiMemoryLength - RequiredMemSize));\r
+  Status        = PeiServicesInstallPeiMemory (PeiMemoryBaseAddress, PeiMemoryLength);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   BuildResourceDescriptorHob (\r
@@ -995,7 +1026,7 @@ InstallS3Memory (
   // 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
@@ -1034,70 +1065,6 @@ InstallS3Memory (
   return EFI_SUCCESS;\r
 }\r
 \r
-/**\r
-\r
-  This function returns the size, in bytes, required for the DXE phase.\r
-\r
-  @param  PeiServices    PEI Services table.\r
-  @param  Size           Pointer to the size, in bytes, required for the DXE phase.\r
-\r
-  @return  None\r
-\r
-**/\r
-VOID\r
-RetriveRequiredMemorySize (\r
-  IN      EFI_PEI_SERVICES                  **PeiServices,\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
-  UINTN                          TempPageNum;\r
-\r
-  MemoryData  = NULL;\r
-  TempPageNum = 0;\r
-  Index       = 0;\r
-\r
-  Status      = 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
-          ) {\r
-      MemoryData = (EFI_MEMORY_TYPE_INFORMATION *) (Hob.Raw + sizeof (EFI_HOB_GENERIC_HEADER) + sizeof (EFI_GUID));\r
-      break;\r
-    }\r
-\r
-    Hob.Raw = GET_NEXT_HOB (Hob);\r
-  }\r
-  //\r
-  // Platform PEIM should supply such a information. Generic PEIM doesn't assume any default value\r
-  //\r
-  if (!MemoryData) {\r
-    return ;\r
-  }\r
-\r
-  while (MemoryData[Index].Type != EfiMaxMemoryType) {\r
-    //\r
-    // Accumulate default memory size requirements\r
-    //\r
-    TempPageNum += MemoryData[Index].NumberOfPages;\r
-    Index++;\r
-  }\r
-\r
-  if (TempPageNum == 0) {\r
-    return ;\r
-  }\r
-\r
-  //\r
-  // Add additional pages used by DXE memory manager\r
-  //\r
-  (*Size) = (TempPageNum + EDKII_DXE_MEM_SIZE_PAGES) * EFI_PAGE_SIZE;\r
-\r
-  return ;\r
-}\r
-\r
 /**\r
 \r
   This function returns the memory ranges to be enabled, along with information\r
@@ -1132,7 +1099,6 @@ GetMemoryMap (
   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
@@ -1155,7 +1121,6 @@ GetMemoryMap (
   //\r
   // Generate Memory ranges for the memory map.\r
   //\r
-  EsmramcRegister = 0;\r
   MemorySize = 0;\r
 \r
   RowLength = TotalMemorySize;\r
@@ -1445,7 +1410,6 @@ Done:
 \r
   @param  PeiMemoryBaseAddress  Base address of memory allocated for PEI.\r
   @param  PeiMemoryLength       Length in bytes of the PEI memory (includes ACPI memory).\r
-  @param  RequiredMemSize       Size in bytes of the ACPI/Runtime memory\r
 \r
   @return EFI_SUCCESS           The function completed successfully.\r
           EFI_ACCESS_DENIED     Access to IMRs failed.\r
@@ -1454,8 +1418,7 @@ Done:
 EFI_STATUS\r
 SetPlatformImrPolicy (\r
   IN      EFI_PHYSICAL_ADDRESS    PeiMemoryBaseAddress,\r
-  IN      UINT64                  PeiMemoryLength,\r
-  IN      UINTN                   RequiredMemSize\r
+  IN      UINT64                  PeiMemoryLength\r
   )\r
 {\r
   UINT8         Index;\r
@@ -1478,17 +1441,6 @@ SetPlatformImrPolicy (
     }\r
   }\r
 \r
-  //\r
-  // Add IMR0 protection for the 'PeiMemory'\r
-  //\r
-  QncImrWrite (\r
-            QUARK_NC_MEMORY_MANAGER_IMR0,\r
-            (UINT32)(((RShiftU64(PeiMemoryBaseAddress, 8)) & IMRL_MASK) | IMR_EN),\r
-            (UINT32)((RShiftU64((PeiMemoryBaseAddress+PeiMemoryLength-RequiredMemSize + EFI_PAGES_TO_SIZE(EDKII_DXE_MEM_SIZE_PAGES-1) - 1), 8)) & IMRL_MASK),\r
-            (UINT32)(CPU_SNOOP + CPU0_NON_SMM),\r
-            (UINT32)(CPU_SNOOP + CPU0_NON_SMM)\r
-        );\r
-\r
   //\r
   // Add IMR2 protection for shadowed RMU binary.\r
   //\r
@@ -1511,28 +1463,6 @@ SetPlatformImrPolicy (
             (UINT32)(CPU_SNOOP + CPU0_NON_SMM)\r
         );\r
 \r
-  //\r
-  // Add IMR5 protection for the legacy S3 and AP Startup Vector region (below 1MB).\r
-  //\r
-  QncImrWrite (\r
-            QUARK_NC_MEMORY_MANAGER_IMR5,\r
-            (UINT32)(((RShiftU64(AP_STARTUP_VECTOR, 8)) & IMRL_MASK) | IMR_EN),\r
-            (UINT32)((RShiftU64((AP_STARTUP_VECTOR + EFI_PAGE_SIZE - 1), 8)) & IMRH_MASK),\r
-            (UINT32)(CPU_SNOOP + CPU0_NON_SMM),\r
-            (UINT32)(CPU_SNOOP + CPU0_NON_SMM)\r
-        );\r
-\r
-  //\r
-  // Add IMR6 protection for the ACPI Reclaim/ACPI/Runtime Services.\r
-  //\r
-  QncImrWrite (\r
-            QUARK_NC_MEMORY_MANAGER_IMR6,\r
-            (UINT32)(((RShiftU64((PeiMemoryBaseAddress+PeiMemoryLength-RequiredMemSize+EFI_PAGES_TO_SIZE(EDKII_DXE_MEM_SIZE_PAGES-1)), 8)) & IMRL_MASK) | IMR_EN),\r
-            (UINT32)((RShiftU64((PeiMemoryBaseAddress+PeiMemoryLength-EFI_PAGE_SIZE-1), 8)) & IMRH_MASK),\r
-            (UINT32)(CPU_SNOOP + CPU0_NON_SMM),\r
-            (UINT32)(CPU_SNOOP + CPU0_NON_SMM)\r
-        );\r
-\r
   //\r
   // Enable IMR4 protection of eSRAM.\r
   //\r