Message ID | 1478785950-24197-26-git-send-email-heyi.guo@linaro.org |
---|---|
State | Superseded |
Headers | show |
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 >
在 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 --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; +}
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