Ver código fonte

Hisilicon/D05: Add PPTT support

Add Processor Properties Topology Table, PPTT include
Processor hierarchy node, Cache Type Structure and ID structure.

PPTT is needed for lscpu command to show socket information correctly.
https://bugs.linaro.org/show_bug.cgi?id=3206

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ming Huang <huangming23@huawei.com>
Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Graeme Gregory <graeme.gregory@linaro.org>
Reveiwed-by: Jeremy Linton <jeremy.linton@arm.com>
Heyi Guo 6 anos atrás
pai
commit
fca814692c

+ 1 - 0
Platform/Hisilicon/D05/D05.dsc

@@ -506,6 +506,7 @@
   MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
 
   Silicon/Hisilicon/Hi1616/D05AcpiTables/AcpiTablesHi1616.inf
+  Silicon/Hisilicon/Hi1616/Pptt/Pptt.inf
   Silicon/Hisilicon/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
 
   #

+ 1 - 0
Platform/Hisilicon/D05/D05.fdf

@@ -241,6 +241,7 @@ READ_LOCK_STATUS   = TRUE
   INF Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf
 
   INF RuleOverride=ACPITABLE Silicon/Hisilicon/Hi1616/D05AcpiTables/AcpiTablesHi1616.inf
+  INF Silicon/Hisilicon/Hi1616/Pptt/Pptt.inf
   INF Silicon/Hisilicon/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
 
   #

+ 529 - 0
Silicon/Hisilicon/Hi1616/Pptt/Pptt.c

@@ -0,0 +1,529 @@
+/** @file
+*
+*  Copyright (c) 2018, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2018, Linaro Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+*  Based on the files under Platform/ARM/JunoPkg/AcpiTables/
+*
+**/
+
+#include "Pptt.h"
+
+EFI_ACPI_TABLE_PROTOCOL       *mAcpiTableProtocol = NULL;
+EFI_ACPI_SDT_PROTOCOL         *mAcpiSdtProtocol   = NULL;
+
+EFI_ACPI_DESCRIPTION_HEADER mPpttHeader =
+  ARM_ACPI_HEADER (
+    EFI_ACPI_6_2_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
+    EFI_ACPI_DESCRIPTION_HEADER,
+    EFI_ACPI_6_2_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION
+  );
+
+EFI_ACPI_6_2_PPTT_STRUCTURE_ID mPpttSocketType2[PPTT_SOCKET_COMPONENT_NO] =
+{
+  {2, sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_ID), {0, 0}, PPTT_VENDOR_ID, 0, 0, 0, 0, 0}
+};
+
+EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE mPpttCacheType1[PPTT_CACHE_NO];
+
+
+STATIC
+VOID
+InitCacheInfo (
+  VOID
+  )
+{
+  UINT8                                        Index;
+  EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE_ATTRIBUTES Type1Attributes;
+  CSSELR_DATA                                  CsselrData;
+  CCSIDR_DATA                                  CcsidrData;
+
+  for (Index = 0; Index < PPTT_CACHE_NO; Index++) {
+    CsselrData.Data = 0;
+    CcsidrData.Data = 0;
+    SetMem (
+      &Type1Attributes,
+      sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE_ATTRIBUTES),
+      0
+      );
+
+    if (Index == 0) { //L1I
+      CsselrData.Bits.InD = 1;
+      CsselrData.Bits.Level = 0;
+      Type1Attributes.CacheType  = 1;
+    } else if (Index == 1) {
+      Type1Attributes.CacheType  = 0;
+      CsselrData.Bits.Level = Index - 1;
+    } else {
+      Type1Attributes.CacheType  = 2;
+      CsselrData.Bits.Level = Index - 1;
+    }
+
+    CcsidrData.Data = ReadCCSIDR (CsselrData.Data);
+
+    if (CcsidrData.Bits.Wa == 1) {
+      Type1Attributes.AllocationType = EFI_ACPI_6_2_CACHE_ATTRIBUTES_ALLOCATION_WRITE;
+      if (CcsidrData.Bits.Ra == 1) {
+        Type1Attributes.AllocationType = EFI_ACPI_6_2_CACHE_ATTRIBUTES_ALLOCATION_READ_WRITE;
+      }
+    }
+
+    if (CcsidrData.Bits.Wt == 1) {
+      Type1Attributes.WritePolicy = 1;
+    }
+    DEBUG ((DEBUG_INFO,
+            "[Acpi PPTT] Level = %x!CcsidrData = %x!\n",
+            CsselrData.Bits.Level,
+            CcsidrData.Data));
+
+    mPpttCacheType1[Index].Type = EFI_ACPI_6_2_PPTT_TYPE_CACHE;
+    mPpttCacheType1[Index].Length = sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE);
+    mPpttCacheType1[Index].Reserved[0] = 0;
+    mPpttCacheType1[Index].Reserved[1] = 0;
+    mPpttCacheType1[Index].Flags.SizePropertyValid = 1;
+    mPpttCacheType1[Index].Flags.NumberOfSetsValid = 1;
+    mPpttCacheType1[Index].Flags.AssociativityValid = 1;
+    mPpttCacheType1[Index].Flags.AllocationTypeValid = 1;
+    mPpttCacheType1[Index].Flags.CacheTypeValid = 1;
+    mPpttCacheType1[Index].Flags.WritePolicyValid = 1;
+    mPpttCacheType1[Index].Flags.LineSizeValid = 1;
+    mPpttCacheType1[Index].Flags.Reserved = 0;
+    mPpttCacheType1[Index].NextLevelOfCache = 0;
+
+    if (Index != PPTT_CACHE_NO - 1) {
+      mPpttCacheType1[Index].NumberOfSets = (UINT16)CcsidrData.Bits.NumSets + 1;
+      mPpttCacheType1[Index].Associativity = (UINT16)CcsidrData.Bits.Associativity + 1;
+      mPpttCacheType1[Index].LineSize = (UINT16)( 1 << (CcsidrData.Bits.LineSize + 4));
+      mPpttCacheType1[Index].Size = mPpttCacheType1[Index].LineSize *      \
+                                    mPpttCacheType1[Index].Associativity * \
+                                    mPpttCacheType1[Index].NumberOfSets;
+      CopyMem (
+        &mPpttCacheType1[Index].Attributes,
+        &Type1Attributes,
+        sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE_ATTRIBUTES)
+        );
+    } else {
+      // L3 cache
+      mPpttCacheType1[Index].Size = 0x1000000;       // 16m
+      mPpttCacheType1[Index].NumberOfSets = 0x2000;
+      mPpttCacheType1[Index].Associativity = 0x10;   // CacheAssociativity16Way
+      SetMem (
+        &mPpttCacheType1[Index].Attributes,
+        sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE_ATTRIBUTES),
+        0x0A
+        );
+      mPpttCacheType1[Index].LineSize = 0x80;        // 128byte
+    }
+  }
+}
+
+STATIC
+EFI_STATUS
+AddCoreTable (
+  IN     EFI_ACPI_DESCRIPTION_HEADER *PpttTable,
+  IN OUT UINT32                      *PpttTableLengthRemain,
+  IN     UINT32                      Parent,
+  IN     UINT32                      ResourceNo,
+  IN     UINT32                      ProcessorId
+  )
+{
+  EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *PpttType0;
+  EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE     *PpttType1;
+  UINT32                                *PrivateResource;
+  UINT8                                 Index;
+
+  if (*PpttTableLengthRemain <
+      (sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR) + ResourceNo * 4)) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  PpttType0 = (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *)((UINT8 *)PpttTable +
+                                                        PpttTable->Length);
+  PpttType0->Type = 0;
+  SetMem (&PpttType0->Flags, sizeof (PpttType0->Flags), 0);
+  PpttType0->Flags.AcpiProcessorIdValid = EFI_ACPI_6_2_PPTT_PROCESSOR_ID_VALID;
+  PpttType0->Parent= Parent;
+  PpttType0->AcpiProcessorId = ProcessorId;
+  PpttType0->NumberOfPrivateResources = ResourceNo;
+  PpttType0->Length = sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR) +
+                      ResourceNo * 4;
+
+  *PpttTableLengthRemain  -= (UINTN)PpttType0->Length;
+  PpttTable->Length += PpttType0->Length;
+  PrivateResource = (UINT32 *)((UINT8 *)PpttType0 +
+                               sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR));
+
+  // Add cache type structure
+  for (Index = 0; Index < ResourceNo; Index++, PrivateResource++) {
+    if (*PpttTableLengthRemain < sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE)) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+    *PrivateResource = PpttTable->Length;
+    PpttType1 = (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE *)((UINT8 *)PpttTable +
+                                                      PpttTable->Length);
+    gBS->CopyMem (
+           PpttType1,
+           &mPpttCacheType1[Index],
+           sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE)
+           );
+    *PpttTableLengthRemain -= PpttType1->Length;
+    PpttTable->Length += PpttType1->Length;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+AddClusterTable (
+  IN     EFI_ACPI_DESCRIPTION_HEADER *PpttTable,
+  IN OUT UINT32                      *PpttTableLengthRemain,
+  IN     UINT32                      Parent,
+  IN     UINT32                      ResourceNo
+  )
+{
+  EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *PpttType0;
+  EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE     *PpttType1;
+  UINT32                                *PrivateResource;
+
+  if ((*PpttTableLengthRemain) <
+      (sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR) + ResourceNo * 4)) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  PpttType0 = (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *)((UINT8 *)PpttTable +
+                                                        PpttTable->Length);
+  PpttType0->Type = 0;
+  SetMem (&PpttType0->Flags, sizeof (PpttType0->Flags), 0);
+  PpttType0->Parent= Parent;
+  PpttType0->NumberOfPrivateResources = ResourceNo;
+  PpttType0->Length = sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR) +
+                      ResourceNo * 4;
+
+  *PpttTableLengthRemain -= PpttType0->Length;
+  PpttTable->Length += PpttType0->Length;
+  PrivateResource = (UINT32 *)((UINT8 *)PpttType0 +
+                               sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR));
+
+  // Add cache type structure
+  if (*PpttTableLengthRemain < sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE)) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  *PrivateResource = PpttTable->Length;
+  PpttType1 = (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE *)((UINT8 *)PpttTable +
+                                                    PpttTable->Length);
+  gBS->CopyMem (
+         PpttType1,
+         &mPpttCacheType1[2],
+         sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE)
+         );
+  *PpttTableLengthRemain -= PpttType1->Length;
+  PpttTable->Length += PpttType1->Length;
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+AddScclTable (
+  IN     EFI_ACPI_DESCRIPTION_HEADER *PpttTable,
+  IN OUT UINT32                      *PpttTableLengthRemain,
+  IN     UINT32                      Parent,
+  IN     UINT32                      ResourceNo
+  )
+{
+  EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *PpttType0;
+  EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE     *PpttType1;
+  UINT32                                *PrivateResource;
+
+  if (*PpttTableLengthRemain <
+      (sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR) + ResourceNo * 4)) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  PpttType0 = (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *)((UINT8 *)PpttTable +
+                                                        PpttTable->Length);
+  PpttType0->Type = 0;
+  SetMem (&PpttType0->Flags, sizeof (PpttType0->Flags), 0);
+  PpttType0->Parent= Parent;
+  PpttType0->NumberOfPrivateResources = ResourceNo;
+  PpttType0->Length = sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR) +
+                      ResourceNo * 4;
+
+  *PpttTableLengthRemain -= PpttType0->Length;
+  PpttTable->Length += PpttType0->Length;
+  PrivateResource = (UINT32 *)((UINT8 *)PpttType0 +
+                               sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR));
+
+  // Add cache type structure
+  if (*PpttTableLengthRemain < sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE)) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  *PrivateResource = PpttTable->Length;
+  PpttType1 = (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE *)((UINT8 *)PpttTable +
+                                                    PpttTable->Length);
+  gBS->CopyMem (
+         PpttType1,
+         &mPpttCacheType1[3],
+         sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE)
+         );
+  *PpttTableLengthRemain -= PpttType1->Length;
+  PpttTable->Length += PpttType1->Length;
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+AddSocketTable (
+  IN     EFI_ACPI_DESCRIPTION_HEADER *PpttTable,
+  IN OUT UINT32                      *PpttTableLengthRemain,
+  IN     UINT32                      Parent,
+  IN     UINT32                      ResourceNo
+  )
+{
+  EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *PpttType0;
+  EFI_ACPI_6_2_PPTT_STRUCTURE_ID        *PpttType2;
+  UINT32                                *PrivateResource;
+  UINT8                                 Index;
+
+  if (*PpttTableLengthRemain < sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR)) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  PpttType0 = (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *)((UINT8 *)PpttTable +
+                                                        PpttTable->Length);
+  PpttType0->Type = 0;
+  SetMem (&PpttType0->Flags, sizeof (PpttType0->Flags), 0);
+  PpttType0->Flags.PhysicalPackage = EFI_ACPI_6_2_PPTT_PROCESSOR_ID_VALID;
+  PpttType0->Parent= Parent;
+  PpttType0->NumberOfPrivateResources = ResourceNo;
+  PpttType0->Length = sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR) +
+                      ResourceNo * 4;
+  PpttTable->Length += PpttType0->Length;
+
+  *PpttTableLengthRemain -= PpttType0->Length;
+  if (*PpttTableLengthRemain < ResourceNo * 4) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  PrivateResource = (UINT32 *)((UINT8 *)PpttType0 +
+                               sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR));
+  DEBUG ((DEBUG_INFO,
+          "[Acpi PPTT]  sizeof(EFI_ACPI_6_2_PPTT_STRUCTURE_ID) = %x!\n",
+          sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_ID)));
+
+  for (Index = 0; Index < ResourceNo; Index++, PrivateResource++) {
+    if (*PpttTableLengthRemain < sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_ID)) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+    *PrivateResource = PpttTable->Length;
+    PpttType2 = (EFI_ACPI_6_2_PPTT_STRUCTURE_ID *)((UINT8 *)PpttTable +
+                                                   PpttTable->Length);
+    gBS->CopyMem (
+           PpttType2,
+           &mPpttSocketType2[Index],
+           sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_ID)
+           );
+    *PpttTableLengthRemain -= PpttType2->Length;
+    PpttTable->Length += PpttType2->Length;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+VOID
+GetApic (
+  IN     EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE *ApicTable,
+  IN OUT EFI_ACPI_DESCRIPTION_HEADER                  *PpttTable,
+  IN     UINT32                                       PpttTableLengthRemain,
+  IN     UINT32                                       Index1
+)
+{
+  UINT32 IndexSocket, IndexSccl, IndexCluster, IndexCore;
+  UINT32 SocketOffset, ScclOffset, ClusterOffset;
+  UINT32 Parent = 0;
+  UINT32 ResourceNo = 0;
+
+  // Get APIC data
+  for (IndexSocket = 0; IndexSocket < PPTT_SOCKET_NO; IndexSocket++) {
+    SocketOffset = 0;
+    for (IndexSccl = 0; IndexSccl < PPTT_SCCL_NO; IndexSccl++) {
+      ScclOffset = 0;
+      for (IndexCluster = 0; IndexCluster < PPTT_CLUSTER_NO; IndexCluster++) {
+        ClusterOffset = 0;
+        for (IndexCore = 0; IndexCore < PPTT_CORE_NO; IndexCore++) {
+          if (ApicTable->GicInterfaces[Index1].AcpiProcessorUid != Index1) {
+            // This processor is unusable
+            DEBUG ((DEBUG_ERROR, "[Acpi PPTT] Please check MADT table for UID!\n"));
+            return;
+          }
+          if ((ApicTable->GicInterfaces[Index1].Flags & BIT0) == 0) {
+            // This processor is unusable
+            Index1++;
+            continue;
+          }
+
+          if (SocketOffset == 0) {
+            // Add socket0 for type0 table
+            ResourceNo = PPTT_SOCKET_COMPONENT_NO;
+            SocketOffset = PpttTable->Length;
+            Parent = 0;
+            AddSocketTable (
+              PpttTable,
+              &PpttTableLengthRemain,
+              Parent,
+              ResourceNo
+              );
+          }
+          if (ScclOffset == 0) {
+            // Add socket0sccl0 for type0 table
+            ResourceNo = 1;
+            ScclOffset =  PpttTable->Length;
+            Parent = SocketOffset;
+            AddScclTable (
+              PpttTable,
+              &PpttTableLengthRemain,
+              Parent,
+              ResourceNo
+              );
+          }
+          if (ClusterOffset == 0) {
+            // Add socket0sccl0ClusterId for type0 table
+            ResourceNo = 1;
+            ClusterOffset =  PpttTable->Length ;
+            Parent = ScclOffset;
+            AddClusterTable (
+              PpttTable,
+              &PpttTableLengthRemain,
+              Parent,
+              ResourceNo
+              );
+          }
+
+          // Add socket0sccl0ClusterIdCoreId for type0 table
+          ResourceNo = 2;
+          Parent = ClusterOffset;
+          AddCoreTable (
+            PpttTable,
+            &PpttTableLengthRemain,
+            Parent,
+            ResourceNo,
+            Index1
+            );
+
+          Index1++;
+        }
+      }
+    }
+  }
+  return ;
+}
+
+STATIC
+VOID
+PpttSetAcpiTable (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  )
+{
+  UINTN                                         AcpiTableHandle;
+  EFI_STATUS                                    Status;
+  UINT8                                         Checksum;
+  EFI_ACPI_SDT_HEADER                           *Table;
+  EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE  *ApicTable;
+  EFI_ACPI_TABLE_VERSION                        TableVersion;
+  EFI_ACPI_DESCRIPTION_HEADER                   *PpttTable;
+  UINTN                                         TableKey;
+  UINT32                                        Index0, Index1;
+  UINT32                                        PpttTableLengthRemain = 0;
+
+  gBS->CloseEvent (Event);
+
+  InitCacheInfo ();
+
+  PpttTable = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (PPTT_TABLE_MAX_LEN);
+  gBS->CopyMem (
+         (VOID *)PpttTable,
+         &mPpttHeader,
+         sizeof (EFI_ACPI_DESCRIPTION_HEADER)
+         );
+  PpttTableLengthRemain = PPTT_TABLE_MAX_LEN - sizeof (EFI_ACPI_DESCRIPTION_HEADER);
+
+  for (Index0 = 0; Index0 < EFI_ACPI_MAX_NUM_TABLES; Index0++) {
+    Status = mAcpiSdtProtocol->GetAcpiTable (
+                                 Index0,
+                                 &Table,
+                                 &TableVersion,
+                                 &TableKey
+                                 );
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+
+    // Find APIC table
+    if (Table->Signature == EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE) {
+      break;
+    }
+
+  }
+
+  if (!EFI_ERROR (Status) && (Index0 != EFI_ACPI_MAX_NUM_TABLES)) {
+    ApicTable = (EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE *)Table;
+    Index1 = 0;
+
+    GetApic (ApicTable, PpttTable, PpttTableLengthRemain, Index1);
+
+    Checksum = CalculateCheckSum8 ((UINT8 *)(PpttTable), PpttTable->Length);
+    PpttTable->Checksum = Checksum;
+
+    AcpiTableHandle = 0;
+    Status = mAcpiTableProtocol->InstallAcpiTable (
+                                   mAcpiTableProtocol,
+                                   PpttTable,
+                                   PpttTable->Length,
+                                   &AcpiTableHandle);
+  }
+
+  FreePool (PpttTable);
+  return ;
+}
+
+EFI_STATUS
+EFIAPI
+PpttEntryPoint(
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS              Status;
+  EFI_EVENT               ReadyToBootEvent;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiAcpiTableProtocolGuid,
+                  NULL,
+                  (VOID **)&mAcpiTableProtocol);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gBS->LocateProtocol (
+                  &gEfiAcpiSdtProtocolGuid,
+                  NULL,
+                  (VOID **)&mAcpiSdtProtocol);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = EfiCreateEventReadyToBootEx (
+             TPL_NOTIFY,
+             PpttSetAcpiTable,
+             NULL,
+             &ReadyToBootEvent
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "Acpi Pptt init done.\n"));
+
+  return Status;
+}

+ 67 - 0
Silicon/Hisilicon/Hi1616/Pptt/Pptt.h

@@ -0,0 +1,67 @@
+/** @file
+*
+*  Copyright (c) 2018, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2018, Linaro Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+*  Based on the files under Platform/ARM/JunoPkg/AcpiTables/
+*
+**/
+
+#ifndef _PPTT_H_
+#define _PPTT_H_
+
+#include <IndustryStandard/Acpi.h>
+#include <Library/ArmLib/ArmLibPrivate.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Protocol/AcpiTable.h>
+#include "../D05AcpiTables/Hi1616Platform.h"
+
+#define PPTT_VENDOR_ID             SIGNATURE_32('H', 'I', 'S', 'I')
+
+#define EFI_ACPI_MAX_NUM_TABLES    20
+
+#define PPTT_TABLE_MAX_LEN         0x6000
+#define PPTT_SOCKET_NO             0x2
+#define PPTT_SCCL_NO               0x2
+#define PPTT_CLUSTER_NO            0x4
+#define PPTT_CORE_NO               0x4
+#define PPTT_SOCKET_COMPONENT_NO   0x1
+#define PPTT_CACHE_NO              0x4
+
+typedef union {
+  struct {
+    UINT32    InD           :1;
+    UINT32    Level         :3;
+    UINT32    Reserved      :28;
+  } Bits;
+  UINT32 Data;
+} CSSELR_DATA;
+
+typedef union {
+  struct {
+    UINT32    LineSize           :3;
+    UINT32    Associativity      :10;
+    UINT32    NumSets            :15;
+    UINT32    Wa                 :1;
+    UINT32    Ra                 :1;
+    UINT32    Wb                 :1;
+    UINT32    Wt                 :1;
+  } Bits;
+  UINT32 Data;
+} CCSIDR_DATA;
+
+#endif    // _PPTT_H_
+

+ 48 - 0
Silicon/Hisilicon/Hi1616/Pptt/Pptt.inf

@@ -0,0 +1,48 @@
+/** @file
+*
+*  Copyright (c) 2018, Hisilicon Limited. All rights reserved.
+*  Copyright (c) 2018, Linaro Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+*  Based on the files under Platform/ARM/JunoPkg/AcpiTables/
+*
+**/
+
+[Defines]
+  INF_VERSION                    = 0x0001001A
+  BASE_NAME                      = AcpiPptt
+  FILE_GUID                      = AAB14F90-DC2E-4f33-A594-C7894A5B412D
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = PpttEntryPoint
+
+[Sources.common]
+  Pptt.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+  ArmLib
+  BaseMemoryLib
+  DebugLib
+  HobLib
+  UefiDriverEntryPoint
+  UefiRuntimeServicesTableLib
+
+[Protocols]
+  gEfiAcpiSdtProtocolGuid                       ## PROTOCOL ALWAYS_CONSUMED
+  gEfiAcpiTableProtocolGuid                     ## PROTOCOL ALWAYS_CONSUMED
+
+[Depex]
+  gEfiAcpiTableProtocolGuid AND gEfiAcpiSdtProtocolGuid
+