]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/AcpiPlatformDxe/Qemu.c
Revert "OvmfPkg/PlatformPei: assign PciSize on both i440fx/q35 branches explicitly"
[mirror_edk2.git] / OvmfPkg / AcpiPlatformDxe / Qemu.c
index 1ac443f3f26990d51a13d53dc0296ca06c0dfe81..f60e00f58af3b72fc153ae497a605ab8e7670cee 100644 (file)
@@ -1,14 +1,11 @@
 /** @file\r
   OVMF ACPI QEMU support\r
 \r
-  Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\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
+  Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>\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
+  Copyright (C) 2012-2014, Red Hat, Inc.\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -18,6 +15,7 @@
 #include <Library/QemuFwCfgLib.h>\r
 #include <Library/DxeServicesTableLib.h>\r
 #include <Library/PcdLib.h>\r
+#include <Library/OrderedCollectionLib.h>\r
 #include <IndustryStandard/Acpi.h>\r
 \r
 BOOLEAN\r
@@ -100,8 +98,8 @@ QemuInstallAcpiMadtTable (
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  Madt->Header           = *(EFI_ACPI_DESCRIPTION_HEADER *) AcpiTableBuffer;\r
-  Madt->Header.Length    = NewBufferSize;\r
+  CopyMem (&(Madt->Header), AcpiTableBuffer, sizeof (EFI_ACPI_DESCRIPTION_HEADER));\r
+  Madt->Header.Length    = (UINT32) NewBufferSize;\r
   Madt->LocalApicAddress = PcdGet32 (PcdCpuLocalApicBaseAddress);\r
   Madt->Flags            = EFI_ACPI_1_0_PCAT_COMPAT;\r
   Ptr = Madt + 1;\r
@@ -110,8 +108,8 @@ QemuInstallAcpiMadtTable (
   for (Loop = 0; Loop < CpuCount; ++Loop) {\r
     LocalApic->Type            = EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC;\r
     LocalApic->Length          = sizeof (*LocalApic);\r
-    LocalApic->AcpiProcessorId = Loop;\r
-    LocalApic->ApicId          = Loop;\r
+    LocalApic->AcpiProcessorId = (UINT8) Loop;\r
+    LocalApic->ApicId          = (UINT8) Loop;\r
     LocalApic->Flags           = 1; // enabled\r
     ++LocalApic;\r
   }\r
@@ -120,7 +118,7 @@ QemuInstallAcpiMadtTable (
   IoApic = Ptr;\r
   IoApic->Type             = EFI_ACPI_1_0_IO_APIC;\r
   IoApic->Length           = sizeof (*IoApic);\r
-  IoApic->IoApicId         = CpuCount;\r
+  IoApic->IoApicId         = (UINT8) CpuCount;\r
   IoApic->Reserved         = EFI_ACPI_RESERVED_BYTE;\r
   IoApic->IoApicAddress    = 0xFEC00000;\r
   IoApic->SystemVectorBase = 0x00000000;\r
@@ -148,13 +146,13 @@ QemuInstallAcpiMadtTable (
     Iso->Type                        = EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE;\r
     Iso->Length                      = sizeof (*Iso);\r
     Iso->Bus                         = 0x00; // ISA\r
-    Iso->Source                      = Loop;\r
-    Iso->GlobalSystemInterruptVector = Loop;\r
+    Iso->Source                      = (UINT8) Loop;\r
+    Iso->GlobalSystemInterruptVector = (UINT32) Loop;\r
     Iso->Flags                       = 0x000D; // Level-tiggered, Active High\r
     ++Iso;\r
   }\r
   ASSERT (\r
-    Iso - (EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE *)Ptr ==\r
+    (UINTN) (Iso - (EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE *)Ptr) ==\r
       1 + PciLinkIsoCount\r
     );\r
   Ptr = Iso;\r
@@ -174,7 +172,7 @@ QemuInstallAcpiMadtTable (
   LocalApicNmi->LocalApicInti   = 0x01;\r
   Ptr = LocalApicNmi + 1;\r
 \r
-  ASSERT ((UINT8 *)Ptr - (UINT8 *)Madt == NewBufferSize);\r
+  ASSERT ((UINTN) ((UINT8 *)Ptr - (UINT8 *)Madt) == NewBufferSize);\r
   Status = InstallAcpiTable (AcpiProtocol, Madt, NewBufferSize, TableKey);\r
 \r
   FreePool (Madt);\r
@@ -196,6 +194,23 @@ typedef struct {
   PCI_WINDOW PciWindow64;\r
 } FIRMWARE_DATA;\r
 \r
+typedef struct {\r
+  UINT8 BytePrefix;\r
+  UINT8 ByteValue;\r
+} AML_BYTE;\r
+\r
+typedef struct {\r
+  UINT8    NameOp;\r
+  UINT8    RootChar;\r
+  UINT8    NameChar[4];\r
+  UINT8    PackageOp;\r
+  UINT8    PkgLength;\r
+  UINT8    NumElements;\r
+  AML_BYTE Pm1aCntSlpTyp;\r
+  AML_BYTE Pm1bCntSlpTyp;\r
+  AML_BYTE Reserved[2];\r
+} SYSTEM_STATE_PACKAGE;\r
+\r
 #pragma pack()\r
 \r
 \r
@@ -230,7 +245,7 @@ PopulateFwData(
       Desc = &AllDesc[CurDesc];\r
       ExclTop = Desc->BaseAddress + Desc->Length;\r
 \r
-      if (ExclTop <= BASE_4GB) {\r
+      if (ExclTop <= (UINT64) PcdGet32 (PcdOvmfFdBaseAddress)) {\r
         switch (Desc->GcdMemoryType) {\r
           case EfiGcdMemoryTypeNonExistent:\r
             break;\r
@@ -295,6 +310,86 @@ PopulateFwData(
 }\r
 \r
 \r
+STATIC\r
+VOID\r
+EFIAPI\r
+GetSuspendStates (\r
+  UINTN                *SuspendToRamSize,\r
+  SYSTEM_STATE_PACKAGE *SuspendToRam,\r
+  UINTN                *SuspendToDiskSize,\r
+  SYSTEM_STATE_PACKAGE *SuspendToDisk\r
+  )\r
+{\r
+  STATIC CONST SYSTEM_STATE_PACKAGE Template = {\r
+    0x08,                   // NameOp\r
+    '\\',                   // RootChar\r
+    { '_', 'S', 'x', '_' }, // NameChar[4]\r
+    0x12,                   // PackageOp\r
+    0x0A,                   // PkgLength\r
+    0x04,                   // NumElements\r
+    { 0x0A, 0x00 },         // Pm1aCntSlpTyp\r
+    { 0x0A, 0x00 },         // Pm1bCntSlpTyp -- we don't support it\r
+    {                       // Reserved[2]\r
+      { 0x0A, 0x00 },\r
+      { 0x0A, 0x00 }\r
+    }\r
+  };\r
+  RETURN_STATUS                     Status;\r
+  FIRMWARE_CONFIG_ITEM              FwCfgItem;\r
+  UINTN                             FwCfgSize;\r
+  UINT8                             SystemStates[6];\r
+\r
+  //\r
+  // configure defaults\r
+  //\r
+  *SuspendToRamSize = sizeof Template;\r
+  CopyMem (SuspendToRam, &Template, sizeof Template);\r
+  SuspendToRam->NameChar[2]             = '3'; // S3\r
+  SuspendToRam->Pm1aCntSlpTyp.ByteValue = 1;   // PIIX4: STR\r
+\r
+  *SuspendToDiskSize = sizeof Template;\r
+  CopyMem (SuspendToDisk, &Template, sizeof Template);\r
+  SuspendToDisk->NameChar[2]             = '4'; // S4\r
+  SuspendToDisk->Pm1aCntSlpTyp.ByteValue = 2;   // PIIX4: POSCL\r
+\r
+  //\r
+  // check for overrides\r
+  //\r
+  Status = QemuFwCfgFindFile ("etc/system-states", &FwCfgItem, &FwCfgSize);\r
+  if (Status != RETURN_SUCCESS || FwCfgSize != sizeof SystemStates) {\r
+    DEBUG ((DEBUG_INFO, "ACPI using S3/S4 defaults\n"));\r
+    return;\r
+  }\r
+  QemuFwCfgSelectItem (FwCfgItem);\r
+  QemuFwCfgReadBytes (sizeof SystemStates, SystemStates);\r
+\r
+  //\r
+  // Each byte corresponds to a system state. In each byte, the MSB tells us\r
+  // whether the given state is enabled. If so, the three LSBs specify the\r
+  // value to be written to the PM control register's SUS_TYP bits.\r
+  //\r
+  if (SystemStates[3] & BIT7) {\r
+    SuspendToRam->Pm1aCntSlpTyp.ByteValue =\r
+        SystemStates[3] & (BIT2 | BIT1 | BIT0);\r
+    DEBUG ((DEBUG_INFO, "ACPI S3 value: %d\n",\r
+            SuspendToRam->Pm1aCntSlpTyp.ByteValue));\r
+  } else {\r
+    *SuspendToRamSize = 0;\r
+    DEBUG ((DEBUG_INFO, "ACPI S3 disabled\n"));\r
+  }\r
+\r
+  if (SystemStates[4] & BIT7) {\r
+    SuspendToDisk->Pm1aCntSlpTyp.ByteValue =\r
+        SystemStates[4] & (BIT2 | BIT1 | BIT0);\r
+    DEBUG ((DEBUG_INFO, "ACPI S4 value: %d\n",\r
+            SuspendToDisk->Pm1aCntSlpTyp.ByteValue));\r
+  } else {\r
+    *SuspendToDiskSize = 0;\r
+    DEBUG ((DEBUG_INFO, "ACPI S4 disabled\n"));\r
+  }\r
+}\r
+\r
+\r
 STATIC\r
 EFI_STATUS\r
 EFIAPI\r
@@ -312,10 +407,16 @@ QemuInstallAcpiSsdtTable (
 \r
   FwData = AllocateReservedPool (sizeof (*FwData));\r
   if (FwData != NULL) {\r
-    UINTN SsdtSize;\r
-    UINT8 *Ssdt;\r
-\r
-    SsdtSize = AcpiTableBufferSize + 17;\r
+    UINTN                SuspendToRamSize;\r
+    SYSTEM_STATE_PACKAGE SuspendToRam;\r
+    UINTN                SuspendToDiskSize;\r
+    SYSTEM_STATE_PACKAGE SuspendToDisk;\r
+    UINTN                SsdtSize;\r
+    UINT8                *Ssdt;\r
+\r
+    GetSuspendStates (&SuspendToRamSize,  &SuspendToRam,\r
+                      &SuspendToDiskSize, &SuspendToDisk);\r
+    SsdtSize = AcpiTableBufferSize + 17 + SuspendToRamSize + SuspendToDiskSize;\r
     Ssdt = AllocatePool (SsdtSize);\r
 \r
     if (Ssdt != NULL) {\r
@@ -352,6 +453,14 @@ QemuInstallAcpiSsdtTable (
         *(UINT32*) SsdtPtr = sizeof (*FwData);\r
         SsdtPtr += 4;\r
 \r
+        //\r
+        // add suspend system states\r
+        //\r
+        CopyMem (SsdtPtr, &SuspendToRam, SuspendToRamSize);\r
+        SsdtPtr += SuspendToRamSize;\r
+        CopyMem (SsdtPtr, &SuspendToDisk, SuspendToDiskSize);\r
+        SsdtPtr += SuspendToDiskSize;\r
+\r
         ASSERT((UINTN) (SsdtPtr - Ssdt) == SsdtSize);\r
         ((EFI_ACPI_DESCRIPTION_HEADER *) Ssdt)->Length = (UINT32) SsdtSize;\r
         Status = InstallAcpiTable (AcpiProtocol, Ssdt, SsdtSize, TableKey);\r
@@ -400,4 +509,3 @@ QemuInstallAcpiTable (
            TableKey\r
            );\r
 }\r
-\r