]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.c
Upload BSD-licensed Vlv2TbltDevicePkg and Vlv2DeviceRefCodePkg to
[mirror_edk2.git] / Vlv2TbltDevicePkg / AcpiPlatform / AcpiPlatformHooks.c
diff --git a/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.c b/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.c
new file mode 100644 (file)
index 0000000..3489650
--- /dev/null
@@ -0,0 +1,500 @@
+/** @file\r
+\r
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>\r
+                                                                                   \r\r
+  This program and the accompanying materials are licensed and made available under\r\r
+  the terms and conditions of the BSD License that accompanies this distribution.  \r\r
+  The full text of the license may be found at                                     \r\r
+  http://opensource.org/licenses/bsd-license.php.                                  \r\r
+                                                                                   \r\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,            \r\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.    \r\r
+                                                                                   \r\r
+\r
+Module Name:\r
+\r
+  AcpiPlatformHooks.c\r
+\r
+Abstract:\r
+\r
+  ACPI Platform Driver Hooks\r
+\r
+--*/\r
+\r
+//\r
+// Statements that include other files.\r
+//\r
+#include "AcpiPlatform.h"\r
+#include "AcpiPlatformHooks.h"\r
+#include "Platform.h"\r
+\r
+//\r
+// Prototypes of the various hook functions.\r
+//\r
+#include "AcpiPlatformHooksLib.h"\r
+\r
+extern EFI_GLOBAL_NVS_AREA_PROTOCOL  mGlobalNvsArea;\r
+extern SYSTEM_CONFIGURATION             mSystemConfiguration;\r
+\r
+ENHANCED_SPEEDSTEP_PROTOCOL             *mEistProtocol  = NULL;\r
+\r
+EFI_CPU_ID_MAP              mCpuApicIdAcpiIdMapTable[MAX_CPU_NUM];\r
+\r
+EFI_STATUS\r
+AppendCpuMapTableEntry (\r
+  IN EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE   *AcpiLocalApic\r
+  )\r
+{\r
+  BOOLEAN Added;\r
+  UINTN   Index;\r
+\r
+  for (Index = 0; Index < MAX_CPU_NUM; Index++) {\r
+    if ((mCpuApicIdAcpiIdMapTable[Index].ApicId == AcpiLocalApic->ApicId) && mCpuApicIdAcpiIdMapTable[Index].Flags) {\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  Added = FALSE;\r
+  for (Index = 0; Index < MAX_CPU_NUM; Index++) {\r
+      if (!mCpuApicIdAcpiIdMapTable[Index].Flags) {\r
+        mCpuApicIdAcpiIdMapTable[Index].Flags           = 1;\r
+        mCpuApicIdAcpiIdMapTable[Index].ApicId          = AcpiLocalApic->ApicId;\r
+        mCpuApicIdAcpiIdMapTable[Index].AcpiProcessorId = AcpiLocalApic->AcpiProcessorId;\r
+      Added = TRUE;\r
+      break;\r
+    }\r
+  }\r
+\r
+  ASSERT (Added);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+UINT32\r
+ProcessorId2ApicId (\r
+  UINT32  AcpiProcessorId\r
+  )\r
+{\r
+  UINTN Index;\r
+\r
+  ASSERT (AcpiProcessorId < MAX_CPU_NUM);\r
+  for (Index = 0; Index < MAX_CPU_NUM; Index++) {\r
+    if (mCpuApicIdAcpiIdMapTable[Index].Flags && (mCpuApicIdAcpiIdMapTable[Index].AcpiProcessorId == AcpiProcessorId)) {\r
+      return mCpuApicIdAcpiIdMapTable[Index].ApicId;\r
+    }\r
+  }\r
+\r
+  return (UINT32) -1;\r
+}\r
+\r
+UINT8\r
+GetProcNumberInPackage (\r
+  IN UINT8  Package\r
+  )\r
+{\r
+  UINTN Index;\r
+  UINT8 Number;\r
+\r
+  Number = 0;\r
+  for (Index = 0; Index < MAX_CPU_NUM; Index++) {\r
+    if (mCpuApicIdAcpiIdMapTable[Index].Flags && (((mCpuApicIdAcpiIdMapTable[Index].ApicId >> 0x04) & 0x01) == Package)) {\r
+      Number++;\r
+    }\r
+  }\r
+\r
+  return Number;\r
+}\r
+\r
+EFI_STATUS\r
+LocateCpuEistProtocol (\r
+  IN UINT32                           CpuIndex,\r
+  OUT ENHANCED_SPEEDSTEP_PROTOCOL     **EistProtocol\r
+  )\r
+{\r
+  UINTN                       HandleCount;\r
+  EFI_HANDLE                  *HandleBuffer;\r
+  ENHANCED_SPEEDSTEP_PROTOCOL *EistProt;\r
+  UINTN                       Index;\r
+  UINT32                      ApicId;\r
+  EFI_STATUS                  Status;\r
+\r
+  HandleCount = 0;\r
+  gBS->LocateHandleBuffer (\r
+         ByProtocol,\r
+         &gEnhancedSpeedstepProtocolGuid,\r
+         NULL,\r
+         &HandleCount,\r
+         &HandleBuffer\r
+         );\r
+\r
+  Index     = 0;\r
+  EistProt  = NULL;\r
+  Status    = EFI_NOT_FOUND;\r
+  while (Index < HandleCount) {\r
+    gBS->HandleProtocol (\r
+           HandleBuffer[Index],\r
+           &gEnhancedSpeedstepProtocolGuid,\r
+          (VOID **) &EistProt\r
+           );\r
+    //\r
+    // Adjust the CpuIndex by +1 due to the AcpiProcessorId is 1 based.\r
+    //\r
+    ApicId = ProcessorId2ApicId (CpuIndex+1);\r
+    if (ApicId == (UINT32) -1) {\r
+      break;\r
+    }\r
+\r
+    if (EistProt->ProcApicId == ApicId) {\r
+      Status = EFI_SUCCESS;\r
+      break;\r
+    }\r
+\r
+    Index++;\r
+  }\r
+\r
+  if (HandleBuffer != NULL) {\r
+    gBS->FreePool (HandleBuffer);\r
+  }\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    *EistProtocol = EistProt;\r
+  } else {\r
+    *EistProtocol = NULL;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+PlatformHookInit (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  Status = gBS->LocateProtocol (\r
+                  &gEnhancedSpeedstepProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &mEistProtocol\r
+                  );\r
+\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Called for every ACPI table found in the BIOS flash.\r
+  Returns whether a table is active or not. Inactive tables\r
+  are not published in the ACPI table list.\r
+\r
+  This hook can be used to implement optional SSDT tables or\r
+  enabling/disabling specific functionality (e.g. SPCR table)\r
+  based on a setup switch or platform preference. In case of\r
+  optional SSDT tables,the platform flash will include all the\r
+  SSDT tables but will return EFI_SUCCESS only for those tables\r
+  that need to be published.\r
+\r
+  @param[in]  *Table         Pointer to the active table.\r
+\r
+  @retval  EFI_SUCCESS       if the table is active.\r
+  @retval  EFI_UNSUPPORTED   if the table is not active.\r
+\r
+**/\r
+EFI_STATUS\r
+AcpiPlatformHooksIsActiveTable (\r
+  IN OUT EFI_ACPI_COMMON_HEADER     *Table\r
+  )\r
+{\r
+  EFI_ACPI_DESCRIPTION_HEADER *TableHeader;\r
+\r
+  TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;\r
+\r
+  if (TableHeader->Signature == EFI_ACPI_2_0_STATIC_RESOURCE_AFFINITY_TABLE_SIGNATURE) {\r
+\r
+  }\r
+\r
+  if ((mSystemConfiguration.ENDBG2 == 0) && (CompareMem (&TableHeader->OemTableId, "INTLDBG2", 8) == 0)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+    Update the GV3 SSDT table.\r
+\r
+    @param[in][out]  *TableHeader   The table to be set.\r
+\r
+    @retval  EFI_SUCCESS            Returns Success.\r
+\r
+**/\r
+EFI_STATUS\r
+PatchGv3SsdtTable (\r
+  IN OUT   EFI_ACPI_DESCRIPTION_HEADER  *TableHeader\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  UINT8                       *CurrPtr;\r
+  UINT8                       *SsdtPointer;\r
+  UINT32                      Signature;\r
+  UINT32                      CpuFixes;\r
+  UINT32                      NpssFixes;\r
+  UINT32                      SpssFixes;\r
+  UINT32                      CpuIndex;\r
+  UINT32                      PackageSize;\r
+  UINT32                      NewPackageSize;\r
+  UINT32                      AdjustSize;\r
+  UINTN                       EntryIndex;\r
+  UINTN                       TableIndex;\r
+  EFI_ACPI_NAME_COMMAND       *PssTable;\r
+  EFI_PSS_PACKAGE             *PssTableItemPtr;\r
+  ENHANCED_SPEEDSTEP_PROTOCOL *EistProt;\r
+  EIST_INFORMATION            *EistInfo;\r
+  EFI_ACPI_CPU_PSS_STATE      *PssState;\r
+  EFI_ACPI_NAMEPACK_DWORD     *NamePtr;\r
+  //\r
+  // Loop through the ASL looking for values that we must fix up.\r
+  //\r
+  NpssFixes = 0;\r
+  SpssFixes = 0;\r
+  CpuFixes  = 0;\r
+  CpuIndex  = 0;\r
+  CurrPtr   = (UINT8 *) TableHeader;\r
+\r
+  EistProt  = NULL;\r
+  for (SsdtPointer = CurrPtr; SsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); SsdtPointer++) {\r
+    Signature = *(UINT32 *) SsdtPointer;\r
+    switch (Signature) {\r
+\r
+    case SIGNATURE_32 ('_', 'P', 'R', '_'):\r
+      //\r
+      // _CPUX ('0' to '0xF')\r
+      //\r
+      CpuIndex = *(SsdtPointer + 7);\r
+      if (CpuIndex >= '0' && CpuIndex <= '9') {\r
+        CpuIndex -= '0';\r
+      } else {\r
+        if (CpuIndex > '9') {\r
+          CpuIndex -= '7';\r
+        }\r
+      }\r
+\r
+      CpuFixes++;\r
+      LocateCpuEistProtocol (CpuIndex, &EistProt);\r
+      break;\r
+\r
+    case SIGNATURE_32 ('D', 'O', 'M', 'N'):\r
+\r
+      NamePtr = ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (SsdtPointer);\r
+      if (NamePtr->StartByte != AML_NAME_OP) {\r
+        continue;\r
+      }\r
+\r
+      if (NamePtr->Size != AML_NAME_DWORD_SIZE) {\r
+        continue;\r
+      }\r
+\r
+      NamePtr->Value = 0;\r
+\r
+        if (mCpuApicIdAcpiIdMapTable[CpuIndex].Flags) {\r
+          NamePtr->Value = (mCpuApicIdAcpiIdMapTable[CpuIndex].ApicId >> 0x04) & 0x01;\r
+      }\r
+      break;\r
+\r
+    case SIGNATURE_32 ('N', 'C', 'P', 'U'):\r
+\r
+      NamePtr = ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (SsdtPointer);\r
+      if (NamePtr->StartByte != AML_NAME_OP) {\r
+        continue;\r
+      }\r
+\r
+      if (NamePtr->Size != AML_NAME_DWORD_SIZE) {\r
+        continue;\r
+      }\r
+\r
+        NamePtr->Value = 0;\r
+        if (mCpuApicIdAcpiIdMapTable[CpuIndex].Flags) {\r
+          NamePtr->Value = GetProcNumberInPackage ((mCpuApicIdAcpiIdMapTable[CpuIndex].ApicId >> 0x04) & 0x01);\r
+      }\r
+      break;\r
+\r
+    case SIGNATURE_32 ('N', 'P', 'S', 'S'):\r
+    case SIGNATURE_32 ('S', 'P', 'S', 'S'):\r
+      if (EistProt == NULL) {\r
+        continue;\r
+      }\r
+\r
+      PssTable = ACPI_NAME_COMMAND_FROM_NAME_STR (SsdtPointer);\r
+      if (PssTable->StartByte != AML_NAME_OP) {\r
+        continue;\r
+      }\r
+\r
+      Status      = EistProt->GetEistTable (EistProt, &EistInfo, (VOID **) &PssState);\r
+\r
+      AdjustSize  = PssTable->NumEntries * sizeof (EFI_PSS_PACKAGE);\r
+      AdjustSize -= EistInfo->NumStates * sizeof (EFI_PSS_PACKAGE);\r
+      PackageSize     = (PssTable->Size & 0xF) + ((PssTable->Size & 0xFF00) >> 4);\r
+      NewPackageSize  = PackageSize - AdjustSize;\r
+      PssTable->Size  = (UINT16) ((NewPackageSize & 0xF) + ((NewPackageSize & 0x0FF0) << 4));\r
+\r
+      //\r
+      // Set most significant two bits of byte zero to 01, meaning two bytes used.\r
+      //\r
+      PssTable->Size |= 0x40;\r
+\r
+      //\r
+      // Set unused table to Noop Code.\r
+      //\r
+      SetMem( (UINT8 *) PssTable + NewPackageSize + AML_NAME_PREFIX_SIZE, AdjustSize, AML_NOOP_OP);\r
+      PssTable->NumEntries  = (UINT8) EistInfo->NumStates;\r
+      PssTableItemPtr       = (EFI_PSS_PACKAGE *) ((UINT8 *) PssTable + sizeof (EFI_ACPI_NAME_COMMAND));\r
+\r
+      //\r
+      // Update the size.\r
+      //\r
+      for (TableIndex = 0; TableIndex < EistInfo->NumStates; TableIndex++) {\r
+        EntryIndex                = EistInfo->NumStates - TableIndex - 1;\r
+        PssTableItemPtr->CoreFreq = PssState[EntryIndex].CoreFrequency * PssState[EntryIndex].Control;\r
+        PssTableItemPtr->Power    = PssState[EntryIndex].Power * 1000;\r
+        if (PssTable->NameStr == SIGNATURE_32 ('N', 'P', 'S', 'S')) {\r
+          PssTableItemPtr->BMLatency    = PssState[EntryIndex].BusMasterLatency;\r
+          PssTableItemPtr->TransLatency = PssState[EntryIndex].TransitionLatency;\r
+        } else {\r
+          //\r
+          // This method should be supported by SMM PPM Handler.\r
+          //\r
+          PssTableItemPtr->BMLatency    = PssState[EntryIndex].BusMasterLatency * 2;\r
+          PssTableItemPtr->TransLatency = PssState[EntryIndex].TransitionLatency * 10;\r
+        }\r
+\r
+        PssTableItemPtr->Control  = PssState[EntryIndex].Control;\r
+        PssTableItemPtr->Status   = PssState[EntryIndex].Status;\r
+        PssTableItemPtr++;\r
+      }\r
+\r
+      if (PssTable->NameStr == SIGNATURE_32 ('N', 'P', 'S', 'S')) {\r
+        NpssFixes++;\r
+      } else {\r
+        SpssFixes++;\r
+      }\r
+\r
+      SsdtPointer = (UINT8 *) PssTable + PackageSize;\r
+      break;\r
+    }\r
+  }\r
+\r
+  //\r
+  // N fixes together currently.\r
+  //\r
+  ASSERT (CpuFixes == (UINT32) MAX_CPU_NUM);\r
+  ASSERT (SpssFixes == NpssFixes);\r
+  ASSERT (CpuFixes >= SpssFixes);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+    Update the DSDT table.\r
+\r
+    @param[in][out]  *TableHeader   The table to be set.\r
+\r
+    @retval  EFI_SUCCESS            Returns EFI_SUCCESS.\r
+\r
+**/\r
+EFI_STATUS\r
+PatchDsdtTable (\r
+  IN OUT   EFI_ACPI_DESCRIPTION_HEADER  *TableHeader\r
+  )\r
+{\r
+\r
+  UINT8                              *CurrPtr;\r
+  UINT8                              *DsdtPointer;\r
+  UINT32                             *Signature;\r
+  UINT8                              *EndPtr;\r
+  UINT8   *Operation;\r
+  UINT32  *Address;\r
+  UINT16  *Size;\r
+\r
+  //\r
+  // Fix PCI32 resource "FIX0" -- PSYS system status area\r
+  //\r
+  CurrPtr = (UINT8*) &((EFI_ACPI_DESCRIPTION_HEADER*) TableHeader)[0];\r
+  EndPtr = (UINT8*) TableHeader;\r
+  EndPtr = EndPtr + TableHeader->Length;\r
+  while (CurrPtr < (EndPtr-2)) {\r
+    //\r
+    // Removed the _S3 tag to indicate that we do not support S3. The 4th byte is blank space\r
+    // since there are only 3 char "_S3".\r
+    //\r
+    if (mSystemConfiguration.AcpiSuspendState == 0) {\r
+      //\r
+      // For iasl compiler version 20061109.\r
+      //\r
+      if ((CurrPtr[0] == '_') && (CurrPtr[1] == 'S') && (CurrPtr[2] == '3') && (CurrPtr[3] == '_')) {\r
+        break;\r
+      }\r
+      //\r
+      // For iasl compiler version 20040527.\r
+      //\r
+      if ((CurrPtr[0] == '\\') && (CurrPtr[1] == '_') && (CurrPtr[2] == 'S') && (CurrPtr[3] == '3')) {\r
+        break;\r
+      }\r
+    }\r
+    CurrPtr++;\r
+  }\r
+  CurrPtr = (UINT8*) &((EFI_ACPI_DESCRIPTION_HEADER*) TableHeader)[0];\r
+  EndPtr = (UINT8*) TableHeader;\r
+  EndPtr = EndPtr + TableHeader->Length;\r
+  while (CurrPtr < (EndPtr-2)) {\r
+    //\r
+    // For mipi dsi port select _DEP.\r
+    //\r
+    if (mSystemConfiguration.MipiDsi== 1) {\r
+      //\r
+      // For iasl compiler version 20061109.\r
+      //\r
+      if ((CurrPtr[0] == 'N') && (CurrPtr[1] == 'D') && (CurrPtr[2] == 'E') && (CurrPtr[3] == 'P')) {\r
+        CurrPtr[0] = '_';\r
+        break;\r
+      }\r
+\r
+    } else {\r
+      if ((CurrPtr[0] == 'P') && (CurrPtr[1] == 'D') && (CurrPtr[2] == 'E') && (CurrPtr[3] == 'P')) {\r
+        CurrPtr[0] = '_';\r
+        break;\r
+      }\r
+\r
+    }\r
+    CurrPtr++;\r
+  }\r
+  //\r
+  // Loop through the ASL looking for values that we must fix up.\r
+  //\r
+  CurrPtr = (UINT8 *) TableHeader;\r
+  for (DsdtPointer = CurrPtr; DsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); DsdtPointer++) {\r
+    Signature = (UINT32 *) DsdtPointer;\r
+\r
+    switch (*Signature) {\r
+    //\r
+    // GNVS operation region.\r
+    //\r
+    case (SIGNATURE_32 ('G', 'N', 'V', 'S')):\r
+      //\r
+      // Conditional match.  For Region Objects, the Operator will always be the\r
+      // byte immediately before the specific name.  Therefore, subtract 1 to check\r
+      // the Operator.\r
+      //\r
+      Operation = DsdtPointer - 1;\r
+      if (*Operation == AML_OPREGION_OP) {\r
+        Address   = (UINT32 *) (DsdtPointer + 6);\r
+        *Address  = (UINT32) (UINTN) mGlobalNvsArea.Area;\r
+        Size      = (UINT16 *) (DsdtPointer + 11);\r
+        *Size     = sizeof (EFI_GLOBAL_NVS_AREA);\r
+      }\r
+      break;\r
+    default:\r
+      break;\r
+    }\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
+\r