]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/CpuS3DataDxe/CpuS3Data.c
UefiCpuPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / UefiCpuPkg / CpuS3DataDxe / CpuS3Data.c
index 3489b9549ce0a3a5c9139c2ef7032b68df4fca1b..2be335d9190369c2d8183131018f1854f9b22936 100644 (file)
@@ -9,16 +9,10 @@ number of CPUs reported by the MP Services Protocol, so this module does not
 support hot plug CPUs.  This module can be copied into a CPU specific package\r
 and customized if these additional features are required.\r
 \r
-Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved.<BR>\r
 Copyright (c) 2015, Red Hat, Inc.\r
 \r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -31,6 +25,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/MtrrLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
 \r
 #include <Protocol/MpService.h>\r
 #include <Guid/EventGroup.h>\r
@@ -46,9 +41,7 @@ typedef struct {
 } ACPI_CPU_DATA_EX;\r
 \r
 /**\r
-  Allocate EfiACPIMemoryNVS below 4G memory address.\r
-\r
-  This function allocates EfiACPIMemoryNVS below 4G memory address.\r
+  Allocate EfiACPIMemoryNVS memory.\r
 \r
   @param[in] Size   Size of memory to allocate.\r
 \r
@@ -56,7 +49,7 @@ typedef struct {
 \r
 **/\r
 VOID *\r
-AllocateAcpiNvsMemoryBelow4G (\r
+AllocateAcpiNvsMemory (\r
   IN UINTN  Size\r
   )\r
 {\r
@@ -64,9 +57,8 @@ AllocateAcpiNvsMemoryBelow4G (
   EFI_STATUS            Status;\r
   VOID                  *Buffer;\r
 \r
-  Address = BASE_4GB - 1;\r
   Status  = gBS->AllocatePages (\r
-                   AllocateMaxAddress,\r
+                   AllocateAnyPages,\r
                    EfiACPIMemoryNVS,\r
                    EFI_SIZE_TO_PAGES (Size),\r
                    &Address\r
@@ -81,6 +73,28 @@ AllocateAcpiNvsMemoryBelow4G (
   return Buffer;\r
 }\r
 \r
+/**\r
+  Allocate memory and clean it with zero.\r
+\r
+  @param[in] Size   Size of memory to allocate.\r
+\r
+  @return       Allocated address for output.\r
+\r
+**/\r
+VOID *\r
+AllocateZeroPages (\r
+  IN UINTN  Size\r
+  )\r
+{\r
+  VOID                  *Buffer;\r
+\r
+  Buffer = AllocatePages (EFI_SIZE_TO_PAGES (Size));\r
+  if (Buffer != NULL) {\r
+    ZeroMem (Buffer, Size);\r
+  }\r
+\r
+  return Buffer;\r
+}\r
 /**\r
   Callback function executed when the EndOfDxe event group is signaled.\r
 \r
@@ -160,15 +174,18 @@ CpuS3DataInitialize (
   VOID                       *Gdt;\r
   VOID                       *Idt;\r
   EFI_EVENT                  Event;\r
+  ACPI_CPU_DATA              *OldAcpiCpuData;\r
 \r
   if (!PcdGetBool (PcdAcpiS3Enable)) {\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
   //\r
-  // Allocate ACPI NVS memory below 4G memory for use on ACPI S3 resume.\r
+  // Set PcdCpuS3DataAddress to the base address of the ACPI_CPU_DATA structure\r
   //\r
-  AcpiCpuDataEx = AllocateAcpiNvsMemoryBelow4G (sizeof (ACPI_CPU_DATA_EX));\r
+  OldAcpiCpuData = (ACPI_CPU_DATA *) (UINTN) PcdGet64 (PcdCpuS3DataAddress);\r
+\r
+  AcpiCpuDataEx = AllocateZeroPages (sizeof (ACPI_CPU_DATA_EX));\r
   ASSERT (AcpiCpuDataEx != NULL);\r
   AcpiCpuData = &AcpiCpuDataEx->AcpiCpuData;\r
 \r
@@ -204,9 +221,13 @@ CpuS3DataInitialize (
   AcpiCpuData->MtrrTable    = (EFI_PHYSICAL_ADDRESS)(UINTN)&AcpiCpuDataEx->MtrrTable;\r
 \r
   //\r
-  // Allocate stack space for all CPUs\r
+  // Allocate stack space for all CPUs.\r
+  // Use ACPI NVS memory type because this data will be directly used by APs\r
+  // in S3 resume phase in long mode. Also during S3 resume, the stack buffer\r
+  // will only be used as scratch space. i.e. we won't read anything from it\r
+  // before we write to it, in PiSmmCpuDxeSmm.\r
   //\r
-  Stack = AllocateAcpiNvsMemoryBelow4G (NumberOfCpus * AcpiCpuData->StackSize);\r
+  Stack = AllocateAcpiNvsMemory (NumberOfCpus * AcpiCpuData->StackSize);\r
   ASSERT (Stack != NULL);\r
   AcpiCpuData->StackAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Stack;\r
 \r
@@ -217,11 +238,11 @@ CpuS3DataInitialize (
   AsmReadIdtr (&AcpiCpuDataEx->IdtrProfile);\r
 \r
   //\r
-  // Allocate GDT and IDT in ACPI NVS and copy current GDT and IDT contents\r
+  // Allocate GDT and IDT and copy current GDT and IDT contents\r
   //\r
   GdtSize = AcpiCpuDataEx->GdtrProfile.Limit + 1;\r
   IdtSize = AcpiCpuDataEx->IdtrProfile.Limit + 1;\r
-  Gdt = AllocateAcpiNvsMemoryBelow4G (GdtSize + IdtSize);\r
+  Gdt = AllocateZeroPages (GdtSize + IdtSize);\r
   ASSERT (Gdt != NULL);\r
   Idt = (VOID *)((UINTN)Gdt + GdtSize);\r
   CopyMem (Gdt, (VOID *)AcpiCpuDataEx->GdtrProfile.Base, GdtSize);\r
@@ -229,32 +250,40 @@ CpuS3DataInitialize (
   AcpiCpuDataEx->GdtrProfile.Base = (UINTN)Gdt;\r
   AcpiCpuDataEx->IdtrProfile.Base = (UINTN)Idt;\r
 \r
-  //\r
-  // Allocate buffer for empty RegisterTable and PreSmmInitRegisterTable for all CPUs\r
-  //\r
-  TableSize = 2 * NumberOfCpus * sizeof (CPU_REGISTER_TABLE);\r
-  RegisterTable = (CPU_REGISTER_TABLE *)AllocateAcpiNvsMemoryBelow4G (TableSize);\r
-  ASSERT (RegisterTable != NULL);\r
-  for (Index = 0; Index < NumberOfCpus; Index++) {\r
-    Status = MpServices->GetProcessorInfo (\r
+  if (OldAcpiCpuData != NULL) {\r
+    AcpiCpuData->RegisterTable           = OldAcpiCpuData->RegisterTable;\r
+    AcpiCpuData->PreSmmInitRegisterTable = OldAcpiCpuData->PreSmmInitRegisterTable;\r
+    AcpiCpuData->ApLocation              = OldAcpiCpuData->ApLocation;\r
+    CopyMem (&AcpiCpuData->CpuStatus, &OldAcpiCpuData->CpuStatus, sizeof (CPU_STATUS_INFORMATION));\r
+  } else {\r
+    //\r
+    // Allocate buffer for empty RegisterTable and PreSmmInitRegisterTable for all CPUs\r
+    //\r
+    TableSize = 2 * NumberOfCpus * sizeof (CPU_REGISTER_TABLE);\r
+    RegisterTable = (CPU_REGISTER_TABLE *)AllocateZeroPages (TableSize);\r
+    ASSERT (RegisterTable != NULL);\r
+\r
+    for (Index = 0; Index < NumberOfCpus; Index++) {\r
+      Status = MpServices->GetProcessorInfo (\r
                            MpServices,\r
                            Index,\r
                            &ProcessorInfoBuffer\r
                            );\r
-    ASSERT_EFI_ERROR (Status);\r
-\r
-    RegisterTable[Index].InitialApicId      = (UINT32)ProcessorInfoBuffer.ProcessorId;\r
-    RegisterTable[Index].TableLength        = 0;\r
-    RegisterTable[Index].AllocatedSize      = 0;\r
-    RegisterTable[Index].RegisterTableEntry = NULL;\r
-\r
-    RegisterTable[NumberOfCpus + Index].InitialApicId      = (UINT32)ProcessorInfoBuffer.ProcessorId;\r
-    RegisterTable[NumberOfCpus + Index].TableLength        = 0;\r
-    RegisterTable[NumberOfCpus + Index].AllocatedSize      = 0;\r
-    RegisterTable[NumberOfCpus + Index].RegisterTableEntry = NULL;\r
+      ASSERT_EFI_ERROR (Status);\r
+\r
+      RegisterTable[Index].InitialApicId      = (UINT32)ProcessorInfoBuffer.ProcessorId;\r
+      RegisterTable[Index].TableLength        = 0;\r
+      RegisterTable[Index].AllocatedSize      = 0;\r
+      RegisterTable[Index].RegisterTableEntry = 0;\r
+\r
+      RegisterTable[NumberOfCpus + Index].InitialApicId      = (UINT32)ProcessorInfoBuffer.ProcessorId;\r
+      RegisterTable[NumberOfCpus + Index].TableLength        = 0;\r
+      RegisterTable[NumberOfCpus + Index].AllocatedSize      = 0;\r
+      RegisterTable[NumberOfCpus + Index].RegisterTableEntry = 0;\r
+    }\r
+    AcpiCpuData->RegisterTable           = (EFI_PHYSICAL_ADDRESS)(UINTN)RegisterTable;\r
+    AcpiCpuData->PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)(RegisterTable + NumberOfCpus);\r
   }\r
-  AcpiCpuData->RegisterTable           = (EFI_PHYSICAL_ADDRESS)(UINTN)RegisterTable;\r
-  AcpiCpuData->PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)(RegisterTable + NumberOfCpus);\r
 \r
   //\r
   // Set PcdCpuS3DataAddress to the base address of the ACPI_CPU_DATA structure\r