diff mbox

[Linaro-uefi,26/27] Hisilicon/ACPI: Update SRAT from real memory configuration

Message ID 1478785950-24197-26-git-send-email-heyi.guo@linaro.org
State Superseded
Headers show

Commit Message

gary guo Nov. 10, 2016, 1:52 p.m. UTC
we add updating ACPI table feature to update SRAT and SLIT
table for D05 platform.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
---
 .../Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c     |  53 +++++---
 .../HisiAcpiPlatformDxe/AcpiPlatformDxe.inf        |   6 +
 .../Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c  | 137 +++++++++++++++++++++
 3 files changed, 176 insertions(+), 20 deletions(-)
 create mode 100644 Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c

Comments

Leif Lindholm Nov. 14, 2016, 2:45 p.m. UTC | #1
On Thu, Nov 10, 2016 at 09:52:29PM +0800, Heyi Guo wrote:
> we add updating ACPI table feature to update SRAT and SLIT
> table for D05 platform.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
> ---
>  .../Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c     |  53 +++++---
>  .../HisiAcpiPlatformDxe/AcpiPlatformDxe.inf        |   6 +
>  .../Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c  | 137 +++++++++++++++++++++
>  3 files changed, 176 insertions(+), 20 deletions(-)
>  create mode 100644 Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c
> 
> diff --git a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c
> index 5b679fa..c1a31b5 100644
> --- a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c
> +++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c
> @@ -24,6 +24,11 @@
>  
>  #include <IndustryStandard/Acpi.h>
>  
> +EFI_STATUS
> +UpdateAcpiTable (
> +  IN OUT EFI_ACPI_DESCRIPTION_HEADER      *TableHeader
> +);
> +

Function declarations go in header files. In this case, please create
and include an UpdateAcpiTable.h.

>  /**
>    Locate the first instance of a protocol.  If the protocol requested is an
>    FV protocol, then it will return the first FV that contains the ACPI table
> @@ -180,6 +185,8 @@ AcpiPlatformEntryPoint (
>    UINT32                         FvStatus;
>    UINTN                          TableSize;
>    UINTN                          Size;
> +  EFI_STATUS                     TableStatus;
> +  EFI_ACPI_DESCRIPTION_HEADER    *TableHeader;
>  
>    Instance     = 0;
>    CurrentTable = NULL;
> @@ -218,26 +225,32 @@ AcpiPlatformEntryPoint (
>        //
>        // Add the table
>        //
> -      TableHandle = 0;
> -
> -      TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length;
> -      ASSERT (Size >= TableSize);
> -
> -      //
> -      // Checksum ACPI table
> -      //
> -      AcpiPlatformChecksum ((UINT8*)CurrentTable, TableSize);
> -
> -      //
> -      // Install ACPI table
> -      //
> -      Status = AcpiTable->InstallAcpiTable (
> -                            AcpiTable,
> -                            CurrentTable,
> -                            TableSize,
> -                            &TableHandle
> -                            );
> -
> +      TableHeader = (EFI_ACPI_DESCRIPTION_HEADER*) (CurrentTable);
> +      //Update specfic Acpi Table
> +      //If the Table is updated failed, doesn't install it,
> +      //go to find next section.
> +      TableStatus = UpdateAcpiTable(TableHeader);
> +      if (TableStatus == EFI_SUCCESS) {
> +        TableHandle = 0;
> +
> +        TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length;
> +        ASSERT (Size >= TableSize);
> +
> +        //
> +        // Checksum ACPI table
> +        //
> +        AcpiPlatformChecksum ((UINT8*)CurrentTable, TableSize);
> +
> +        //
> +        // Install ACPI table
> +        //
> +        Status = AcpiTable->InstallAcpiTable (
> +                              AcpiTable,
> +                              CurrentTable,
> +                              TableSize,
> +                              &TableHandle
> +                              );
> +      }
>        //
>        // Free memory allocated by ReadSection
>        //
> diff --git a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf
> index 80ff49b..35b4a0a 100644
> --- a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf
> +++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf
> @@ -29,10 +29,12 @@
>  
>  [Sources]
>    AcpiPlatform.c
> +  UpdateAcpiTable.c
>  
>  [Packages]
>    MdePkg/MdePkg.dec
>    MdeModulePkg/MdeModulePkg.dec
> +  OpenPlatformPkg/Chips/Hisilicon/HisiPkg.dec
>  
>  [LibraryClasses]
>    UefiLib
> @@ -42,10 +44,14 @@
>    DebugLib
>    UefiBootServicesTableLib
>    UefiDriverEntryPoint
> +  HobLib

Insert after DebugLib, so improve sorting.

>  
>  [Protocols]
>    gEfiAcpiTableProtocolGuid                     ## CONSUMES
>  
> +[Guids]
> +  gHisiEfiMemoryMapGuid
> +
>  [Pcd]
>    gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiTableStorageFile    ## CONSUMES
>  
> diff --git a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c
> new file mode 100644
> index 0000000..1d7797c
> --- /dev/null
> +++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c
> @@ -0,0 +1,137 @@
> +/** @file
> +  Copyright (c) 2016, Hisilicon 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.
> +**/
> +#include <PlatformArch.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <Library/AcpiNextLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/HwMemInitLib.h>
> +#include <Library/OemMiscLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +
> +#define CORE_NUM_PER_SOCKET  32
> +#define NODE_IN_SOCKET       2
> +
> +STATIC
> +VOID
> +RemoveInvalidMemoryNode (

This function appears to be named for how it is used rather than for
what it does. Could it be renamed RemoveMemoryNode()?

Or is it that it removes any unused nodes in the table?
If so, a better name would be RemoveUnusedMemoryNodes().

> +  IN OUT EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE  *Table,
> +  IN     UINTN                        MemoryNodeNum
> +)
> +{
> +  UINT8                   *CurrPtr, *NewPtr;

Don't use UINT8 * where you mean VOID * (or UINTN).
(Applies throughout function.)

> +
> +  if (MemoryNodeNum >= EFI_ACPI_MEMORY_AFFINITY_STRUCTURE_COUNT) {
> +    return;
> +  }
> +
> +  CurrPtr = (UINT8 *) &(Table->Memory[EFI_ACPI_MEMORY_AFFINITY_STRUCTURE_COUNT]);

I don't understand this bit.
What is it taking the address of, to copy data from?

> +  NewPtr = (UINT8 *) &(Table->Memory[MemoryNodeNum]);
> +
> +  CopyMem (NewPtr, CurrPtr, (UINT8 *)Table + Table->Header.Header.Length - CurrPtr);
> +
> +  Table->Header.Header.Length -= CurrPtr - NewPtr;
> +
> +  return;
> +}
> +
> +STATIC
> +EFI_STATUS
> +UpdateSrat (
> +  IN OUT EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *Table
> +  )
> +{
> +  UINT8               Skt = 0;
> +  UINTN               Index = 0;
> +  VOID                *HobList;
> +  GBL_DATA            *Gbl_Data;
> +  UINTN               Base;
> +  UINTN               Size;
> +  UINT8               NodeId;
> +  UINT32              ScclInterleaveEn;
> +  UINT8               i;

There is no performance or other benefit to using UINT8 for a generic
counter. UINT32 or UINTN.


> +  UINTN               MemoryNode = 0;
> +
> +  DEBUG((DEBUG_INFO, "SRAT: Updating SRAT memory information.\n"));
> +
> +  HobList = GetHobList();
> +  if (HobList == NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +  Gbl_Data = (GBL_DATA*)GetNextGuidHob(&gHisiEfiMemoryMapGuid, HobList);
> +  if (Gbl_Data == NULL) {
> +    DEBUG((DEBUG_ERROR, "Get next Guid HOb fail.\n"));
> +    return EFI_NOT_FOUND;
> +  }
> +  Gbl_Data = GET_GUID_HOB_DATA(Gbl_Data);
> +  for(Skt = 0; Skt < MAX_SOCKET; Skt++) {
> +    for(Index = 0; Index < MAX_NUM_PER_TYPE; Index++) {
> +      NodeId = Gbl_Data->NumaInfo[Skt][Index].NodeId;
> +      Base = Gbl_Data->NumaInfo[Skt][Index].Base;
> +      Size = Gbl_Data->NumaInfo[Skt][Index].Length;
> +      DEBUG((DEBUG_INFO, "Skt %d Index %d: NodeId = %d, Base = 0x%lx, Size = 0x%lx\n", Skt, Index, NodeId, Base, Size));
> +      if (Size > 0) {
> +        Table->Memory[MemoryNode].ProximityDomain = NodeId;
> +        Table->Memory[MemoryNode].AddressBaseLow = Base;
> +        Table->Memory[MemoryNode].AddressBaseHigh = Base >> 32;
> +        Table->Memory[MemoryNode].LengthLow = Size;
> +        Table->Memory[MemoryNode].LengthHigh = Size >> 32;
> +        MemoryNode = MemoryNode + 1;
> +      }
> +    }
> +    ScclInterleaveEn = Gbl_Data->NumaInfo[Skt][0].ScclInterleaveEn;
> +    DEBUG((DEBUG_INFO, "ScclInterleaveEn = %d\n", ScclInterleaveEn));
> +    //update gicc structure
> +    if (ScclInterleaveEn != 0) {
> +      DEBUG((DEBUG_INFO, "SRAT: Updating SRAT Gicc information.\n" ));

Drop space before )).

> +      for (i = Skt * CORE_NUM_PER_SOCKET; i < (Skt + 1) * CORE_NUM_PER_SOCKET; i++) {

Could benefit from a local macro such as
#define CORECOUNT(X) ((X) * CORE_NUM_PER_SOCKET)

Also, why is there even an 'i' here? Could we not just reuse Index?

> +        Table->Gicc[i].ProximityDomain = Skt * NODE_IN_SOCKET;
> +      }
> +    }
> +  }
> +
> +  //remove invalid memory node
> +  RemoveInvalidMemoryNode (Table, MemoryNode);

Why is this invalid?

> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +UpdateSlit (
> +  IN OUT EFI_ACPI_DESCRIPTION_HEADER  *Table
> +  )
> +{
> +  return  EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +UpdateAcpiTable (
> +  IN OUT EFI_ACPI_DESCRIPTION_HEADER      *TableHeader
> +)
> +{
> +  EFI_STATUS Status = EFI_SUCCESS;
> +
> +  switch (TableHeader->Signature) {
> +
> +  case EFI_ACPI_6_0_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE:
> +    Status = UpdateSrat ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) TableHeader);
> +    break;
> +
> +  case EFI_ACPI_6_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE:
> +    Status = UpdateSlit (TableHeader);
> +    break;
> +  }
> +  return Status;
> +}
> -- 
> 1.9.1
>
gary guo Nov. 18, 2016, 4:08 a.m. UTC | #2
在 11/14/2016 10:45 PM, Leif Lindholm 写道:
> On Thu, Nov 10, 2016 at 09:52:29PM +0800, Heyi Guo wrote:
>> we add updating ACPI table feature to update SRAT and SLIT
>> table for D05 platform.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
>> ---
>>   .../Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c     |  53 +++++---
>>   .../HisiAcpiPlatformDxe/AcpiPlatformDxe.inf        |   6 +
>>   .../Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c  | 137 +++++++++++++++++++++
>>   3 files changed, 176 insertions(+), 20 deletions(-)
>>   create mode 100644 Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c
>>
>> diff --git a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c
>> index 5b679fa..c1a31b5 100644
>> --- a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c
>> +++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c
>> @@ -24,6 +24,11 @@
>>   
>>   #include <IndustryStandard/Acpi.h>
>>   
>> +EFI_STATUS
>> +UpdateAcpiTable (
>> +  IN OUT EFI_ACPI_DESCRIPTION_HEADER      *TableHeader
>> +);
>> +
> Function declarations go in header files. In this case, please create
> and include an UpdateAcpiTable.h.
>
>>   /**
>>     Locate the first instance of a protocol.  If the protocol requested is an
>>     FV protocol, then it will return the first FV that contains the ACPI table
>> @@ -180,6 +185,8 @@ AcpiPlatformEntryPoint (
>>     UINT32                         FvStatus;
>>     UINTN                          TableSize;
>>     UINTN                          Size;
>> +  EFI_STATUS                     TableStatus;
>> +  EFI_ACPI_DESCRIPTION_HEADER    *TableHeader;
>>   
>>     Instance     = 0;
>>     CurrentTable = NULL;
>> @@ -218,26 +225,32 @@ AcpiPlatformEntryPoint (
>>         //
>>         // Add the table
>>         //
>> -      TableHandle = 0;
>> -
>> -      TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length;
>> -      ASSERT (Size >= TableSize);
>> -
>> -      //
>> -      // Checksum ACPI table
>> -      //
>> -      AcpiPlatformChecksum ((UINT8*)CurrentTable, TableSize);
>> -
>> -      //
>> -      // Install ACPI table
>> -      //
>> -      Status = AcpiTable->InstallAcpiTable (
>> -                            AcpiTable,
>> -                            CurrentTable,
>> -                            TableSize,
>> -                            &TableHandle
>> -                            );
>> -
>> +      TableHeader = (EFI_ACPI_DESCRIPTION_HEADER*) (CurrentTable);
>> +      //Update specfic Acpi Table
>> +      //If the Table is updated failed, doesn't install it,
>> +      //go to find next section.
>> +      TableStatus = UpdateAcpiTable(TableHeader);
>> +      if (TableStatus == EFI_SUCCESS) {
>> +        TableHandle = 0;
>> +
>> +        TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length;
>> +        ASSERT (Size >= TableSize);
>> +
>> +        //
>> +        // Checksum ACPI table
>> +        //
>> +        AcpiPlatformChecksum ((UINT8*)CurrentTable, TableSize);
>> +
>> +        //
>> +        // Install ACPI table
>> +        //
>> +        Status = AcpiTable->InstallAcpiTable (
>> +                              AcpiTable,
>> +                              CurrentTable,
>> +                              TableSize,
>> +                              &TableHandle
>> +                              );
>> +      }
>>         //
>>         // Free memory allocated by ReadSection
>>         //
>> diff --git a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf
>> index 80ff49b..35b4a0a 100644
>> --- a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf
>> +++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf
>> @@ -29,10 +29,12 @@
>>   
>>   [Sources]
>>     AcpiPlatform.c
>> +  UpdateAcpiTable.c
>>   
>>   [Packages]
>>     MdePkg/MdePkg.dec
>>     MdeModulePkg/MdeModulePkg.dec
>> +  OpenPlatformPkg/Chips/Hisilicon/HisiPkg.dec
>>   
>>   [LibraryClasses]
>>     UefiLib
>> @@ -42,10 +44,14 @@
>>     DebugLib
>>     UefiBootServicesTableLib
>>     UefiDriverEntryPoint
>> +  HobLib
> Insert after DebugLib, so improve sorting.
>
>>   
>>   [Protocols]
>>     gEfiAcpiTableProtocolGuid                     ## CONSUMES
>>   
>> +[Guids]
>> +  gHisiEfiMemoryMapGuid
>> +
>>   [Pcd]
>>     gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiTableStorageFile    ## CONSUMES
>>   
>> diff --git a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c
>> new file mode 100644
>> index 0000000..1d7797c
>> --- /dev/null
>> +++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c
>> @@ -0,0 +1,137 @@
>> +/** @file
>> +  Copyright (c) 2016, Hisilicon 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.
>> +**/
>> +#include <PlatformArch.h>
>> +#include <IndustryStandard/Acpi.h>
>> +#include <Library/AcpiNextLib.h>
>> +#include <Library/BaseLib.h>
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/HobLib.h>
>> +#include <Library/HwMemInitLib.h>
>> +#include <Library/OemMiscLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +#include <Library/UefiLib.h>
>> +
>> +#define CORE_NUM_PER_SOCKET  32
>> +#define NODE_IN_SOCKET       2
>> +
>> +STATIC
>> +VOID
>> +RemoveInvalidMemoryNode (
> This function appears to be named for how it is used rather than for
> what it does. Could it be renamed RemoveMemoryNode()?
>
> Or is it that it removes any unused nodes in the table?
> If so, a better name would be RemoveUnusedMemoryNodes().
    Hi Leif,
    There have some static Memory Nodes at Srat table, the nodes will be 
initialized during boot,
   and different DIMM Slots inserting may have different notes number 
used, so the nodes useless will
   be removed here, and we also need to copy the data next block to the 
end of memory nodes.

>
>> +  IN OUT EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE  *Table,
>> +  IN     UINTN                        MemoryNodeNum
>> +)
>> +{
>> +  UINT8                   *CurrPtr, *NewPtr;
> Don't use UINT8 * where you mean VOID * (or UINTN).
> (Applies throughout function.)
>
>> +
>> +  if (MemoryNodeNum >= EFI_ACPI_MEMORY_AFFINITY_STRUCTURE_COUNT) {
>> +    return;
>> +  }
>> +
>> +  CurrPtr = (UINT8 *) &(Table->Memory[EFI_ACPI_MEMORY_AFFINITY_STRUCTURE_COUNT]);
> I don't understand this bit.
> What is it taking the address of, to copy data from?
>
>> +  NewPtr = (UINT8 *) &(Table->Memory[MemoryNodeNum]);
>> +
>> +  CopyMem (NewPtr, CurrPtr, (UINT8 *)Table + Table->Header.Header.Length - CurrPtr);
>> +
>> +  Table->Header.Header.Length -= CurrPtr - NewPtr;
>> +
>> +  return;
>> +}
>> +
>> +STATIC
>> +EFI_STATUS
>> +UpdateSrat (
>> +  IN OUT EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *Table
>> +  )
>> +{
>> +  UINT8               Skt = 0;
>> +  UINTN               Index = 0;
>> +  VOID                *HobList;
>> +  GBL_DATA            *Gbl_Data;
>> +  UINTN               Base;
>> +  UINTN               Size;
>> +  UINT8               NodeId;
>> +  UINT32              ScclInterleaveEn;
>> +  UINT8               i;
> There is no performance or other benefit to using UINT8 for a generic
> counter. UINT32 or UINTN.
>
>
>> +  UINTN               MemoryNode = 0;
>> +
>> +  DEBUG((DEBUG_INFO, "SRAT: Updating SRAT memory information.\n"));
>> +
>> +  HobList = GetHobList();
>> +  if (HobList == NULL) {
>> +    return EFI_UNSUPPORTED;
>> +  }
>> +  Gbl_Data = (GBL_DATA*)GetNextGuidHob(&gHisiEfiMemoryMapGuid, HobList);
>> +  if (Gbl_Data == NULL) {
>> +    DEBUG((DEBUG_ERROR, "Get next Guid HOb fail.\n"));
>> +    return EFI_NOT_FOUND;
>> +  }
>> +  Gbl_Data = GET_GUID_HOB_DATA(Gbl_Data);
>> +  for(Skt = 0; Skt < MAX_SOCKET; Skt++) {
>> +    for(Index = 0; Index < MAX_NUM_PER_TYPE; Index++) {
>> +      NodeId = Gbl_Data->NumaInfo[Skt][Index].NodeId;
>> +      Base = Gbl_Data->NumaInfo[Skt][Index].Base;
>> +      Size = Gbl_Data->NumaInfo[Skt][Index].Length;
>> +      DEBUG((DEBUG_INFO, "Skt %d Index %d: NodeId = %d, Base = 0x%lx, Size = 0x%lx\n", Skt, Index, NodeId, Base, Size));
>> +      if (Size > 0) {
>> +        Table->Memory[MemoryNode].ProximityDomain = NodeId;
>> +        Table->Memory[MemoryNode].AddressBaseLow = Base;
>> +        Table->Memory[MemoryNode].AddressBaseHigh = Base >> 32;
>> +        Table->Memory[MemoryNode].LengthLow = Size;
>> +        Table->Memory[MemoryNode].LengthHigh = Size >> 32;
>> +        MemoryNode = MemoryNode + 1;
>> +      }
>> +    }
>> +    ScclInterleaveEn = Gbl_Data->NumaInfo[Skt][0].ScclInterleaveEn;
>> +    DEBUG((DEBUG_INFO, "ScclInterleaveEn = %d\n", ScclInterleaveEn));
>> +    //update gicc structure
>> +    if (ScclInterleaveEn != 0) {
>> +      DEBUG((DEBUG_INFO, "SRAT: Updating SRAT Gicc information.\n" ));
> Drop space before )).
>
>> +      for (i = Skt * CORE_NUM_PER_SOCKET; i < (Skt + 1) * CORE_NUM_PER_SOCKET; i++) {
> Could benefit from a local macro such as
> #define CORECOUNT(X) ((X) * CORE_NUM_PER_SOCKET)
>
> Also, why is there even an 'i' here? Could we not just reuse Index?
>
>> +        Table->Gicc[i].ProximityDomain = Skt * NODE_IN_SOCKET;
>> +      }
>> +    }
>> +  }
>> +
>> +  //remove invalid memory node
>> +  RemoveInvalidMemoryNode (Table, MemoryNode);
> Why is this invalid?
     the memory nodes which are not be initialized will be invalid, we 
have to remove them and copy the next block data
     to the end of memory nodes block.
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +STATIC
>> +EFI_STATUS
>> +UpdateSlit (
>> +  IN OUT EFI_ACPI_DESCRIPTION_HEADER  *Table
>> +  )
>> +{
>> +  return  EFI_SUCCESS;
>> +}
>> +
>> +EFI_STATUS
>> +UpdateAcpiTable (
>> +  IN OUT EFI_ACPI_DESCRIPTION_HEADER      *TableHeader
>> +)
>> +{
>> +  EFI_STATUS Status = EFI_SUCCESS;
>> +
>> +  switch (TableHeader->Signature) {
>> +
>> +  case EFI_ACPI_6_0_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE:
>> +    Status = UpdateSrat ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) TableHeader);
>> +    break;
>> +
>> +  case EFI_ACPI_6_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE:
>> +    Status = UpdateSlit (TableHeader);
>> +    break;
>> +  }
>> +  return Status;
>> +}
>> -- 
>> 1.9.1
>>
diff mbox

Patch

diff --git a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c
index 5b679fa..c1a31b5 100644
--- a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c
+++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c
@@ -24,6 +24,11 @@ 
 
 #include <IndustryStandard/Acpi.h>
 
+EFI_STATUS
+UpdateAcpiTable (
+  IN OUT EFI_ACPI_DESCRIPTION_HEADER      *TableHeader
+);
+
 /**
   Locate the first instance of a protocol.  If the protocol requested is an
   FV protocol, then it will return the first FV that contains the ACPI table
@@ -180,6 +185,8 @@  AcpiPlatformEntryPoint (
   UINT32                         FvStatus;
   UINTN                          TableSize;
   UINTN                          Size;
+  EFI_STATUS                     TableStatus;
+  EFI_ACPI_DESCRIPTION_HEADER    *TableHeader;
 
   Instance     = 0;
   CurrentTable = NULL;
@@ -218,26 +225,32 @@  AcpiPlatformEntryPoint (
       //
       // Add the table
       //
-      TableHandle = 0;
-
-      TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length;
-      ASSERT (Size >= TableSize);
-
-      //
-      // Checksum ACPI table
-      //
-      AcpiPlatformChecksum ((UINT8*)CurrentTable, TableSize);
-
-      //
-      // Install ACPI table
-      //
-      Status = AcpiTable->InstallAcpiTable (
-                            AcpiTable,
-                            CurrentTable,
-                            TableSize,
-                            &TableHandle
-                            );
-
+      TableHeader = (EFI_ACPI_DESCRIPTION_HEADER*) (CurrentTable);
+      //Update specfic Acpi Table
+      //If the Table is updated failed, doesn't install it,
+      //go to find next section.
+      TableStatus = UpdateAcpiTable(TableHeader);
+      if (TableStatus == EFI_SUCCESS) {
+        TableHandle = 0;
+
+        TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length;
+        ASSERT (Size >= TableSize);
+
+        //
+        // Checksum ACPI table
+        //
+        AcpiPlatformChecksum ((UINT8*)CurrentTable, TableSize);
+
+        //
+        // Install ACPI table
+        //
+        Status = AcpiTable->InstallAcpiTable (
+                              AcpiTable,
+                              CurrentTable,
+                              TableSize,
+                              &TableHandle
+                              );
+      }
       //
       // Free memory allocated by ReadSection
       //
diff --git a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf
index 80ff49b..35b4a0a 100644
--- a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf
+++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf
@@ -29,10 +29,12 @@ 
 
 [Sources]
   AcpiPlatform.c
+  UpdateAcpiTable.c
 
 [Packages]
   MdePkg/MdePkg.dec
   MdeModulePkg/MdeModulePkg.dec
+  OpenPlatformPkg/Chips/Hisilicon/HisiPkg.dec
 
 [LibraryClasses]
   UefiLib
@@ -42,10 +44,14 @@ 
   DebugLib
   UefiBootServicesTableLib
   UefiDriverEntryPoint
+  HobLib
 
 [Protocols]
   gEfiAcpiTableProtocolGuid                     ## CONSUMES
 
+[Guids]
+  gHisiEfiMemoryMapGuid
+
 [Pcd]
   gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiTableStorageFile    ## CONSUMES
 
diff --git a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c
new file mode 100644
index 0000000..1d7797c
--- /dev/null
+++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c
@@ -0,0 +1,137 @@ 
+/** @file
+  Copyright (c) 2016, Hisilicon 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.
+**/
+#include <PlatformArch.h>
+#include <IndustryStandard/Acpi.h>
+#include <Library/AcpiNextLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/HwMemInitLib.h>
+#include <Library/OemMiscLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#define CORE_NUM_PER_SOCKET  32
+#define NODE_IN_SOCKET       2
+
+STATIC
+VOID
+RemoveInvalidMemoryNode (
+  IN OUT EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE  *Table,
+  IN     UINTN                        MemoryNodeNum
+)
+{
+  UINT8                   *CurrPtr, *NewPtr;
+
+  if (MemoryNodeNum >= EFI_ACPI_MEMORY_AFFINITY_STRUCTURE_COUNT) {
+    return;
+  }
+
+  CurrPtr = (UINT8 *) &(Table->Memory[EFI_ACPI_MEMORY_AFFINITY_STRUCTURE_COUNT]);
+  NewPtr = (UINT8 *) &(Table->Memory[MemoryNodeNum]);
+
+  CopyMem (NewPtr, CurrPtr, (UINT8 *)Table + Table->Header.Header.Length - CurrPtr);
+
+  Table->Header.Header.Length -= CurrPtr - NewPtr;
+
+  return;
+}
+
+STATIC
+EFI_STATUS
+UpdateSrat (
+  IN OUT EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *Table
+  )
+{
+  UINT8               Skt = 0;
+  UINTN               Index = 0;
+  VOID                *HobList;
+  GBL_DATA            *Gbl_Data;
+  UINTN               Base;
+  UINTN               Size;
+  UINT8               NodeId;
+  UINT32              ScclInterleaveEn;
+  UINT8               i;
+  UINTN               MemoryNode = 0;
+
+  DEBUG((DEBUG_INFO, "SRAT: Updating SRAT memory information.\n"));
+
+  HobList = GetHobList();
+  if (HobList == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+  Gbl_Data = (GBL_DATA*)GetNextGuidHob(&gHisiEfiMemoryMapGuid, HobList);
+  if (Gbl_Data == NULL) {
+    DEBUG((DEBUG_ERROR, "Get next Guid HOb fail.\n"));
+    return EFI_NOT_FOUND;
+  }
+  Gbl_Data = GET_GUID_HOB_DATA(Gbl_Data);
+  for(Skt = 0; Skt < MAX_SOCKET; Skt++) {
+    for(Index = 0; Index < MAX_NUM_PER_TYPE; Index++) {
+      NodeId = Gbl_Data->NumaInfo[Skt][Index].NodeId;
+      Base = Gbl_Data->NumaInfo[Skt][Index].Base;
+      Size = Gbl_Data->NumaInfo[Skt][Index].Length;
+      DEBUG((DEBUG_INFO, "Skt %d Index %d: NodeId = %d, Base = 0x%lx, Size = 0x%lx\n", Skt, Index, NodeId, Base, Size));
+      if (Size > 0) {
+        Table->Memory[MemoryNode].ProximityDomain = NodeId;
+        Table->Memory[MemoryNode].AddressBaseLow = Base;
+        Table->Memory[MemoryNode].AddressBaseHigh = Base >> 32;
+        Table->Memory[MemoryNode].LengthLow = Size;
+        Table->Memory[MemoryNode].LengthHigh = Size >> 32;
+        MemoryNode = MemoryNode + 1;
+      }
+    }
+    ScclInterleaveEn = Gbl_Data->NumaInfo[Skt][0].ScclInterleaveEn;
+    DEBUG((DEBUG_INFO, "ScclInterleaveEn = %d\n", ScclInterleaveEn));
+    //update gicc structure
+    if (ScclInterleaveEn != 0) {
+      DEBUG((DEBUG_INFO, "SRAT: Updating SRAT Gicc information.\n" ));
+      for (i = Skt * CORE_NUM_PER_SOCKET; i < (Skt + 1) * CORE_NUM_PER_SOCKET; i++) {
+        Table->Gicc[i].ProximityDomain = Skt * NODE_IN_SOCKET;
+      }
+    }
+  }
+
+  //remove invalid memory node
+  RemoveInvalidMemoryNode (Table, MemoryNode);
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+UpdateSlit (
+  IN OUT EFI_ACPI_DESCRIPTION_HEADER  *Table
+  )
+{
+  return  EFI_SUCCESS;
+}
+
+EFI_STATUS
+UpdateAcpiTable (
+  IN OUT EFI_ACPI_DESCRIPTION_HEADER      *TableHeader
+)
+{
+  EFI_STATUS Status = EFI_SUCCESS;
+
+  switch (TableHeader->Signature) {
+
+  case EFI_ACPI_6_0_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE:
+    Status = UpdateSrat ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) TableHeader);
+    break;
+
+  case EFI_ACPI_6_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE:
+    Status = UpdateSlit (TableHeader);
+    break;
+  }
+  return Status;
+}