Message ID | 1476796207-94336-19-git-send-email-heyi.guo@linaro.org |
---|---|
State | New |
Headers | show |
On Tue, Oct 18, 2016 at 09:10:02PM +0800, Heyi Guo wrote: > AcpiPlatformDxe in MdeModulePkg is overridden to support ACPI/SRAT > self update from real memory configuration on board. We probably don't have time to resolve this at this point, but I would be very interested in investigating what level of common helper libraries could be possible to have. Could you remind me of this once all the platforms have been migrated to Tianocore (let's say January)? Could you separate this into two patches - one importing the driver, and one adding your modifications? Regards, Leif > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Heyi Guo <heyi.guo@linaro.org> > Cc: Graeme Gregory <graeme.gregory@linaro.org> > --- > .../Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c | 299 +++++++++++++++++++++ > .../Drivers/HisiAcpiPlatformDxe/AcpiPlatform.uni | 22 ++ > .../HisiAcpiPlatformDxe/AcpiPlatformDxe.inf | 59 ++++ > .../HisiAcpiPlatformDxe/AcpiPlatformExtra.uni | 20 ++ > .../Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c | 127 +++++++++ > 5 files changed, 527 insertions(+) > create mode 100644 Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c > create mode 100644 Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.uni > create mode 100644 Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf > create mode 100644 Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformExtra.uni > 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 > new file mode 100644 > index 0000000..c915a89 > --- /dev/null > +++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c > @@ -0,0 +1,299 @@ > +/** @file > + Sample ACPI Platform Driver > + > + Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR> > + 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 <PiDxe.h> > + > +#include <Protocol/AcpiTable.h> > +#include <Protocol/FirmwareVolume2.h> > + > +#include <Library/BaseLib.h> > +#include <Library/UefiBootServicesTableLib.h> > +#include <Library/DebugLib.h> > +#include <Library/PcdLib.h> > + > +#include <IndustryStandard/Acpi.h> > + > +EFI_STATUS > +PlatformUpdateTables ( > + IN OUT EFI_ACPI_COMMON_HEADER **Table > + ); > + > +VOID > +UpdateAcpiTable ( > + IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader, > + IN OUT EFI_STATUS *CommonCodeReturnStatus > +); > + > +/** > + 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 > + storage file. > + > + @param Instance Return pointer to the first instance of the protocol > + > + @return EFI_SUCCESS The function completed successfully. > + @return EFI_NOT_FOUND The protocol could not be located. > + @return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol. > + > +**/ > +EFI_STATUS > +LocateFvInstanceWithTables ( > + OUT EFI_FIRMWARE_VOLUME2_PROTOCOL **Instance > + ) > +{ > + EFI_STATUS Status; > + EFI_HANDLE *HandleBuffer; > + UINTN NumberOfHandles; > + EFI_FV_FILETYPE FileType; > + UINT32 FvStatus; > + EFI_FV_FILE_ATTRIBUTES Attributes; > + UINTN Size; > + UINTN Index; > + EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance; > + > + FvStatus = 0; > + > + // > + // Locate protocol. > + // > + Status = gBS->LocateHandleBuffer ( > + ByProtocol, > + &gEfiFirmwareVolume2ProtocolGuid, > + NULL, > + &NumberOfHandles, > + &HandleBuffer > + ); > + if (EFI_ERROR (Status)) { > + // > + // Defined errors at this time are not found and out of resources. > + // > + return Status; > + } > + > + > + > + // > + // Looking for FV with ACPI storage file > + // > + > + for (Index = 0; Index < NumberOfHandles; Index++) { > + // > + // Get the protocol on this handle > + // This should not fail because of LocateHandleBuffer > + // > + Status = gBS->HandleProtocol ( > + HandleBuffer[Index], > + &gEfiFirmwareVolume2ProtocolGuid, > + (VOID**) &FvInstance > + ); > + ASSERT_EFI_ERROR (Status); > + > + // > + // See if it has the ACPI storage file > + // > + Status = FvInstance->ReadFile ( > + FvInstance, > + (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile), > + NULL, > + &Size, > + &FileType, > + &Attributes, > + &FvStatus > + ); > + > + // > + // If we found it, then we are done > + // > + if (Status == EFI_SUCCESS) { > + *Instance = FvInstance; > + break; > + } > + } > + > + // > + // Our exit status is determined by the success of the previous operations > + // If the protocol was found, Instance already points to it. > + // > + > + // > + // Free any allocated buffers > + // > + gBS->FreePool (HandleBuffer); > + > + return Status; > +} > + > + > +/** > + This function calculates and updates an UINT8 checksum. > + > + @param Buffer Pointer to buffer to checksum > + @param Size Number of bytes to checksum > + > +**/ > +VOID > +AcpiPlatformChecksum ( > + IN UINT8 *Buffer, > + IN UINTN Size > + ) > +{ > + UINTN ChecksumOffset; > + > + ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum); > + > + // > + // Set checksum to 0 first > + // > + Buffer[ChecksumOffset] = 0; > + > + // > + // Update checksum value > + // > + Buffer[ChecksumOffset] = CalculateCheckSum8(Buffer, Size); > +} > + > + > +/** > + Entrypoint of Acpi Platform driver. > + > + @param ImageHandle > + @param SystemTable > + > + @return EFI_SUCCESS > + @return EFI_LOAD_ERROR > + @return EFI_OUT_OF_RESOURCES > + > +**/ > +EFI_STATUS > +EFIAPI > +AcpiPlatformEntryPoint ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + EFI_STATUS Status; > + EFI_ACPI_TABLE_PROTOCOL *AcpiTable; > + EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol; > + INTN Instance; > + EFI_ACPI_COMMON_HEADER *CurrentTable; > + UINTN TableHandle; > + UINT32 FvStatus; > + UINTN TableSize; > + UINTN Size; > + EFI_STATUS TableStatus; > + > + Instance = 0; > + CurrentTable = NULL; > + TableHandle = 0; > + > + // > + // Find the AcpiTable protocol > + // > + Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable); > + if (EFI_ERROR (Status)) { > + return EFI_ABORTED; > + } > + > + // > + // Locate the firmware volume protocol > + // > + Status = LocateFvInstanceWithTables (&FwVol); > + if (EFI_ERROR (Status)) { > + return EFI_ABORTED; > + } > + // > + // Read tables from the storage file. > + // > + while (Status == EFI_SUCCESS) { > + > + Status = FwVol->ReadSection ( > + FwVol, > + (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile), > + EFI_SECTION_RAW, > + Instance, > + (VOID**) &CurrentTable, > + &Size, > + &FvStatus > + ); > + if (!EFI_ERROR(Status)) { > + // > + // Add the table > + // > + TableStatus = PlatformUpdateTables (&CurrentTable); > + if (TableStatus == EFI_SUCCESS) { > + // > + // 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 > + ); > + > + // > + // Free memory allocated by ReadSection > + // > + gBS->FreePool (CurrentTable); > + > + if (EFI_ERROR(Status)) { > + return EFI_ABORTED; > + } > + > + // > + // Increment the instance > + // > + Instance++; > + CurrentTable = NULL; > + } > + } > + } > +return EFI_SUCCESS; > +} > +/** > + This function will update any runtime platform specific information. > + @param Table The table to update > + > + @return EFI_SUCCESS The function completed successfully. > + > +**/ > +EFI_STATUS > +PlatformUpdateTables ( > + IN OUT EFI_ACPI_COMMON_HEADER **Table > + ) > +{ > + EFI_STATUS Status; > + EFI_ACPI_DESCRIPTION_HEADER *TableHeader; > + > + Status = EFI_SUCCESS; > + > + TableHeader = (EFI_ACPI_DESCRIPTION_HEADER*) (*Table); > + > + UpdateAcpiTable(TableHeader, &Status); > + > + return Status; > +} > + > diff --git a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.uni b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.uni > new file mode 100644 > index 0000000..1275549 > --- /dev/null > +++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.uni > @@ -0,0 +1,22 @@ > +// /** @file > +// Sample ACPI Platform Driver > +// > +// Sample ACPI Platform Driver > +// > +// Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR> > +// > +// 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. > +// > +// **/ > + > + > +#string STR_MODULE_ABSTRACT #language en-US "Sample ACPI Platform Driver" > + > +#string STR_MODULE_DESCRIPTION #language en-US "Sample ACPI Platform Driver" > + > diff --git a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf > new file mode 100644 > index 0000000..4caa7a4 > --- /dev/null > +++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf > @@ -0,0 +1,59 @@ > +## @file > +# Sample ACPI Platform Driver > +# > +# Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR> > +# 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. > +# > +## > + > +[Defines] > + INF_VERSION = 0x00010005 > + BASE_NAME = AcpiPlatform > + MODULE_UNI_FILE = AcpiPlatform.uni > + FILE_GUID = cb933912-df8f-4305-b1f9-7b44fa11395c > + MODULE_TYPE = DXE_DRIVER > + VERSION_STRING = 1.0 > + ENTRY_POINT = AcpiPlatformEntryPoint > + > +# > +# The following information is for reference only and not required by the build tools. > +# > +# VALID_ARCHITECTURES = IA32 X64 IPF EBC > +# > + > +[Sources] > + AcpiPlatform.c > + UpdateAcpiTable.c > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + OpenPlatformPkg/Chips/Hisilicon/HisiPkg.dec > + > +[LibraryClasses] > + UefiLib > + DxeServicesLib > + PcdLib > + BaseMemoryLib > + DebugLib > + UefiBootServicesTableLib > + UefiDriverEntryPoint > + HobLib > + > +[Protocols] > + gEfiAcpiTableProtocolGuid ## CONSUMES > +[Guids] > + gHisiEfiMemoryMapGuid > +[Pcd] > + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiTableStorageFile ## CONSUMES > + > +[Depex] > + gEfiAcpiTableProtocolGuid > + > +[UserExtensions.TianoCore."ExtraFiles"] > + AcpiPlatformExtra.uni > diff --git a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformExtra.uni b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformExtra.uni > new file mode 100644 > index 0000000..4c21968 > --- /dev/null > +++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformExtra.uni > @@ -0,0 +1,20 @@ > +// /** @file > +// AcpiPlatform Localized Strings and Content > +// > +// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR> > +// > +// 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. > +// > +// **/ > + > +#string STR_PROPERTIES_MODULE_NAME > +#language en-US > +"ACPI Platform Sample DXE Driver" > + > + > diff --git a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c > new file mode 100644 > index 0000000..702f959 > --- /dev/null > +++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c > @@ -0,0 +1,127 @@ > + > +#include <Library/BaseLib.h> > +#include <Library/DebugLib.h> > +#include <Library/UefiBootServicesTableLib.h> > +#include <Library/BaseMemoryLib.h> > +#include <Library/UefiLib.h> > +#include <IndustryStandard/Acpi61.h> > +#include <PlatformArch.h> > +#include <Library/OemMiscLib.h> > +#include <Library/AcpiNextLib.h> > +#include <Library/HobLib.h> > +#include <Library/HwMemInitLib.h> > + > +#define MaxMemoryNode 10 > +UINT8 MemoryNode = 0; > + > +EFI_STATUS > +RemoveInvalidMemoryNode ( > + IN OUT EFI_ACPI_DESCRIPTION_HEADER *Table, > + IN UINTN MemoryNodeNum > +) > +{ > + UINT8 *CurrPtr, *EndPtr, *NextValidPtr; > + UINT32 NeedRemoveLength; > + if (MemoryNodeNum >= MaxMemoryNode) > + { > + DEBUG((EFI_D_ERROR, "There are no invalid memory node\n")); > + return EFI_INVALID_PARAMETER; > + } > + CurrPtr = (UINT8*) &((EFI_ACPI_DESCRIPTION_HEADER*) (Table))[1]; > + CurrPtr = CurrPtr + 4 + 8; // revision + reserved > + NextValidPtr = CurrPtr + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[0].Length * MaxMemoryNode; > + EndPtr = (UINT8*) (Table); > + EndPtr = EndPtr + (Table)->Length; > + NeedRemoveLength = ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[0].Length * (MaxMemoryNode - MemoryNodeNum); > + > + CurrPtr = CurrPtr + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[0].Length * MemoryNodeNum; > + CopyMem (CurrPtr, NextValidPtr, (UINTN)EndPtr - (UINTN)NextValidPtr); //copy data to current ptr > + (Table)->Length -= NeedRemoveLength; > + > + return EFI_SUCCESS; > +} > + > +STATIC > +EFI_STATUS > +UpdateSrat ( > + IN OUT EFI_ACPI_DESCRIPTION_HEADER *Table > + ) > +{ > + UINT8 Skt = 0; > + UINT8 Ch = 0; > + VOID* HobList; > + GBL_DATA *Gbl_Data; > + UINTN Base; > + UINTN Size; > + UINT8 NodeId; > + UINT32 DieInterleaveEn; > + UINT8 i; > + > + DEBUG(( EFI_D_ERROR, "\nSRAT: Updating SRAT memory information!\n" )); > + > + HobList = GetHobList(); > + Gbl_Data = (GBL_DATA*)GetNextGuidHob(&gHisiEfiMemoryMapGuid, HobList); > + Gbl_Data = GET_GUID_HOB_DATA(Gbl_Data); > + for(Skt = 0; Skt < MAX_SOCKET; Skt++){ > + for(Ch = 0; Ch < MAX_NUM_PER_TYPE; Ch++){ > + NodeId = Gbl_Data->NumaInfo[Skt][Ch].NodeId; > + Base = Gbl_Data->NumaInfo[Skt][Ch].Base; > + Size = Gbl_Data->NumaInfo[Skt][Ch].Length; > + DieInterleaveEn = Gbl_Data->NumaInfo[Skt][Ch].DieInterleaveEn; > + DEBUG((EFI_D_INFO,"Skt %d Ch: %d NodeId = %d, Base = 0x%lx, Size = 0x%lx, DieInterLeaveEn = %d\n",Skt,Ch,NodeId,Base,Size,DieInterleaveEn)); > + if (Size > 0) > + { > + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[MemoryNode].ProximityDomain = NodeId; > + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[MemoryNode].AddressBaseLow = Base; > + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[MemoryNode].AddressBaseHigh = Base >> 32; > + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[MemoryNode].LengthLow = Size; > + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[MemoryNode].LengthHigh = Size >> 32; > + MemoryNode = MemoryNode + 1; > + } > + } > + } > + > + //update gicc structure > + if(DieInterleaveEn != 0) > + { > + DEBUG(( EFI_D_ERROR, "\nSRAT: Updating SRAT Gicc information!\n" )); > + for (i = 0; i < 32; i ++) > + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Gicc[i].ProximityDomain = 0; > + for (i = 32; i < 64; i ++) > + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Gicc[i].ProximityDomain = 2; > + } > + > + //remove invalid memory node > + (VOID)RemoveInvalidMemoryNode (Table, MemoryNode); > + > + return EFI_SUCCESS; > + > +} > + > +STATIC > +EFI_STATUS > +UpdateSlit ( > + IN OUT EFI_ACPI_DESCRIPTION_HEADER *Table > + ) > +{ > + return EFI_SUCCESS; > +} > + > +VOID > +UpdateAcpiTable ( > + IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader, > + IN OUT EFI_STATUS *CommonCodeReturnStatus > +) > +{ > + switch ((TableHeader)->Signature) { > + > + case EFI_ACPI_6_0_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE: > + *CommonCodeReturnStatus = UpdateSrat (TableHeader); > + break; > + > + case EFI_ACPI_6_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE: > + *CommonCodeReturnStatus = UpdateSlit (TableHeader); > + break; > + } > + return; > +} > -- > 1.9.1 >
在 10/27/2016 11:06 PM, Leif Lindholm 写道: > On Tue, Oct 18, 2016 at 09:10:02PM +0800, Heyi Guo wrote: >> AcpiPlatformDxe in MdeModulePkg is overridden to support ACPI/SRAT >> self update from real memory configuration on board. > We probably don't have time to resolve this at this point, but I would > be very interested in investigating what level of common helper > libraries could be possible to have. > > Could you remind me of this once all the platforms have been migrated > to Tianocore (let's say January)? Sure. Thanks. Heyi > > Could you separate this into two patches - one importing the driver, > and one adding your modifications? > > Regards, > > Leif > >> Contributed-under: TianoCore Contribution Agreement 1.0 >> Signed-off-by: Heyi Guo <heyi.guo@linaro.org> >> Cc: Graeme Gregory <graeme.gregory@linaro.org> >> --- >> .../Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c | 299 +++++++++++++++++++++ >> .../Drivers/HisiAcpiPlatformDxe/AcpiPlatform.uni | 22 ++ >> .../HisiAcpiPlatformDxe/AcpiPlatformDxe.inf | 59 ++++ >> .../HisiAcpiPlatformDxe/AcpiPlatformExtra.uni | 20 ++ >> .../Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c | 127 +++++++++ >> 5 files changed, 527 insertions(+) >> create mode 100644 Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c >> create mode 100644 Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.uni >> create mode 100644 Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf >> create mode 100644 Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformExtra.uni >> 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 >> new file mode 100644 >> index 0000000..c915a89 >> --- /dev/null >> +++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c >> @@ -0,0 +1,299 @@ >> +/** @file >> + Sample ACPI Platform Driver >> + >> + Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR> >> + 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 <PiDxe.h> >> + >> +#include <Protocol/AcpiTable.h> >> +#include <Protocol/FirmwareVolume2.h> >> + >> +#include <Library/BaseLib.h> >> +#include <Library/UefiBootServicesTableLib.h> >> +#include <Library/DebugLib.h> >> +#include <Library/PcdLib.h> >> + >> +#include <IndustryStandard/Acpi.h> >> + >> +EFI_STATUS >> +PlatformUpdateTables ( >> + IN OUT EFI_ACPI_COMMON_HEADER **Table >> + ); >> + >> +VOID >> +UpdateAcpiTable ( >> + IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader, >> + IN OUT EFI_STATUS *CommonCodeReturnStatus >> +); >> + >> +/** >> + 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 >> + storage file. >> + >> + @param Instance Return pointer to the first instance of the protocol >> + >> + @return EFI_SUCCESS The function completed successfully. >> + @return EFI_NOT_FOUND The protocol could not be located. >> + @return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol. >> + >> +**/ >> +EFI_STATUS >> +LocateFvInstanceWithTables ( >> + OUT EFI_FIRMWARE_VOLUME2_PROTOCOL **Instance >> + ) >> +{ >> + EFI_STATUS Status; >> + EFI_HANDLE *HandleBuffer; >> + UINTN NumberOfHandles; >> + EFI_FV_FILETYPE FileType; >> + UINT32 FvStatus; >> + EFI_FV_FILE_ATTRIBUTES Attributes; >> + UINTN Size; >> + UINTN Index; >> + EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance; >> + >> + FvStatus = 0; >> + >> + // >> + // Locate protocol. >> + // >> + Status = gBS->LocateHandleBuffer ( >> + ByProtocol, >> + &gEfiFirmwareVolume2ProtocolGuid, >> + NULL, >> + &NumberOfHandles, >> + &HandleBuffer >> + ); >> + if (EFI_ERROR (Status)) { >> + // >> + // Defined errors at this time are not found and out of resources. >> + // >> + return Status; >> + } >> + >> + >> + >> + // >> + // Looking for FV with ACPI storage file >> + // >> + >> + for (Index = 0; Index < NumberOfHandles; Index++) { >> + // >> + // Get the protocol on this handle >> + // This should not fail because of LocateHandleBuffer >> + // >> + Status = gBS->HandleProtocol ( >> + HandleBuffer[Index], >> + &gEfiFirmwareVolume2ProtocolGuid, >> + (VOID**) &FvInstance >> + ); >> + ASSERT_EFI_ERROR (Status); >> + >> + // >> + // See if it has the ACPI storage file >> + // >> + Status = FvInstance->ReadFile ( >> + FvInstance, >> + (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile), >> + NULL, >> + &Size, >> + &FileType, >> + &Attributes, >> + &FvStatus >> + ); >> + >> + // >> + // If we found it, then we are done >> + // >> + if (Status == EFI_SUCCESS) { >> + *Instance = FvInstance; >> + break; >> + } >> + } >> + >> + // >> + // Our exit status is determined by the success of the previous operations >> + // If the protocol was found, Instance already points to it. >> + // >> + >> + // >> + // Free any allocated buffers >> + // >> + gBS->FreePool (HandleBuffer); >> + >> + return Status; >> +} >> + >> + >> +/** >> + This function calculates and updates an UINT8 checksum. >> + >> + @param Buffer Pointer to buffer to checksum >> + @param Size Number of bytes to checksum >> + >> +**/ >> +VOID >> +AcpiPlatformChecksum ( >> + IN UINT8 *Buffer, >> + IN UINTN Size >> + ) >> +{ >> + UINTN ChecksumOffset; >> + >> + ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum); >> + >> + // >> + // Set checksum to 0 first >> + // >> + Buffer[ChecksumOffset] = 0; >> + >> + // >> + // Update checksum value >> + // >> + Buffer[ChecksumOffset] = CalculateCheckSum8(Buffer, Size); >> +} >> + >> + >> +/** >> + Entrypoint of Acpi Platform driver. >> + >> + @param ImageHandle >> + @param SystemTable >> + >> + @return EFI_SUCCESS >> + @return EFI_LOAD_ERROR >> + @return EFI_OUT_OF_RESOURCES >> + >> +**/ >> +EFI_STATUS >> +EFIAPI >> +AcpiPlatformEntryPoint ( >> + IN EFI_HANDLE ImageHandle, >> + IN EFI_SYSTEM_TABLE *SystemTable >> + ) >> +{ >> + EFI_STATUS Status; >> + EFI_ACPI_TABLE_PROTOCOL *AcpiTable; >> + EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol; >> + INTN Instance; >> + EFI_ACPI_COMMON_HEADER *CurrentTable; >> + UINTN TableHandle; >> + UINT32 FvStatus; >> + UINTN TableSize; >> + UINTN Size; >> + EFI_STATUS TableStatus; >> + >> + Instance = 0; >> + CurrentTable = NULL; >> + TableHandle = 0; >> + >> + // >> + // Find the AcpiTable protocol >> + // >> + Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable); >> + if (EFI_ERROR (Status)) { >> + return EFI_ABORTED; >> + } >> + >> + // >> + // Locate the firmware volume protocol >> + // >> + Status = LocateFvInstanceWithTables (&FwVol); >> + if (EFI_ERROR (Status)) { >> + return EFI_ABORTED; >> + } >> + // >> + // Read tables from the storage file. >> + // >> + while (Status == EFI_SUCCESS) { >> + >> + Status = FwVol->ReadSection ( >> + FwVol, >> + (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile), >> + EFI_SECTION_RAW, >> + Instance, >> + (VOID**) &CurrentTable, >> + &Size, >> + &FvStatus >> + ); >> + if (!EFI_ERROR(Status)) { >> + // >> + // Add the table >> + // >> + TableStatus = PlatformUpdateTables (&CurrentTable); >> + if (TableStatus == EFI_SUCCESS) { >> + // >> + // 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 >> + ); >> + >> + // >> + // Free memory allocated by ReadSection >> + // >> + gBS->FreePool (CurrentTable); >> + >> + if (EFI_ERROR(Status)) { >> + return EFI_ABORTED; >> + } >> + >> + // >> + // Increment the instance >> + // >> + Instance++; >> + CurrentTable = NULL; >> + } >> + } >> + } >> +return EFI_SUCCESS; >> +} >> +/** >> + This function will update any runtime platform specific information. >> + @param Table The table to update >> + >> + @return EFI_SUCCESS The function completed successfully. >> + >> +**/ >> +EFI_STATUS >> +PlatformUpdateTables ( >> + IN OUT EFI_ACPI_COMMON_HEADER **Table >> + ) >> +{ >> + EFI_STATUS Status; >> + EFI_ACPI_DESCRIPTION_HEADER *TableHeader; >> + >> + Status = EFI_SUCCESS; >> + >> + TableHeader = (EFI_ACPI_DESCRIPTION_HEADER*) (*Table); >> + >> + UpdateAcpiTable(TableHeader, &Status); >> + >> + return Status; >> +} >> + >> diff --git a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.uni b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.uni >> new file mode 100644 >> index 0000000..1275549 >> --- /dev/null >> +++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.uni >> @@ -0,0 +1,22 @@ >> +// /** @file >> +// Sample ACPI Platform Driver >> +// >> +// Sample ACPI Platform Driver >> +// >> +// Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR> >> +// >> +// 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. >> +// >> +// **/ >> + >> + >> +#string STR_MODULE_ABSTRACT #language en-US "Sample ACPI Platform Driver" >> + >> +#string STR_MODULE_DESCRIPTION #language en-US "Sample ACPI Platform Driver" >> + >> diff --git a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf >> new file mode 100644 >> index 0000000..4caa7a4 >> --- /dev/null >> +++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf >> @@ -0,0 +1,59 @@ >> +## @file >> +# Sample ACPI Platform Driver >> +# >> +# Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR> >> +# 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. >> +# >> +## >> + >> +[Defines] >> + INF_VERSION = 0x00010005 >> + BASE_NAME = AcpiPlatform >> + MODULE_UNI_FILE = AcpiPlatform.uni >> + FILE_GUID = cb933912-df8f-4305-b1f9-7b44fa11395c >> + MODULE_TYPE = DXE_DRIVER >> + VERSION_STRING = 1.0 >> + ENTRY_POINT = AcpiPlatformEntryPoint >> + >> +# >> +# The following information is for reference only and not required by the build tools. >> +# >> +# VALID_ARCHITECTURES = IA32 X64 IPF EBC >> +# >> + >> +[Sources] >> + AcpiPlatform.c >> + UpdateAcpiTable.c >> +[Packages] >> + MdePkg/MdePkg.dec >> + MdeModulePkg/MdeModulePkg.dec >> + OpenPlatformPkg/Chips/Hisilicon/HisiPkg.dec >> + >> +[LibraryClasses] >> + UefiLib >> + DxeServicesLib >> + PcdLib >> + BaseMemoryLib >> + DebugLib >> + UefiBootServicesTableLib >> + UefiDriverEntryPoint >> + HobLib >> + >> +[Protocols] >> + gEfiAcpiTableProtocolGuid ## CONSUMES >> +[Guids] >> + gHisiEfiMemoryMapGuid >> +[Pcd] >> + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiTableStorageFile ## CONSUMES >> + >> +[Depex] >> + gEfiAcpiTableProtocolGuid >> + >> +[UserExtensions.TianoCore."ExtraFiles"] >> + AcpiPlatformExtra.uni >> diff --git a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformExtra.uni b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformExtra.uni >> new file mode 100644 >> index 0000000..4c21968 >> --- /dev/null >> +++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformExtra.uni >> @@ -0,0 +1,20 @@ >> +// /** @file >> +// AcpiPlatform Localized Strings and Content >> +// >> +// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR> >> +// >> +// 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. >> +// >> +// **/ >> + >> +#string STR_PROPERTIES_MODULE_NAME >> +#language en-US >> +"ACPI Platform Sample DXE Driver" >> + >> + >> diff --git a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c >> new file mode 100644 >> index 0000000..702f959 >> --- /dev/null >> +++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c >> @@ -0,0 +1,127 @@ >> + >> +#include <Library/BaseLib.h> >> +#include <Library/DebugLib.h> >> +#include <Library/UefiBootServicesTableLib.h> >> +#include <Library/BaseMemoryLib.h> >> +#include <Library/UefiLib.h> >> +#include <IndustryStandard/Acpi61.h> >> +#include <PlatformArch.h> >> +#include <Library/OemMiscLib.h> >> +#include <Library/AcpiNextLib.h> >> +#include <Library/HobLib.h> >> +#include <Library/HwMemInitLib.h> >> + >> +#define MaxMemoryNode 10 >> +UINT8 MemoryNode = 0; >> + >> +EFI_STATUS >> +RemoveInvalidMemoryNode ( >> + IN OUT EFI_ACPI_DESCRIPTION_HEADER *Table, >> + IN UINTN MemoryNodeNum >> +) >> +{ >> + UINT8 *CurrPtr, *EndPtr, *NextValidPtr; >> + UINT32 NeedRemoveLength; >> + if (MemoryNodeNum >= MaxMemoryNode) >> + { >> + DEBUG((EFI_D_ERROR, "There are no invalid memory node\n")); >> + return EFI_INVALID_PARAMETER; >> + } >> + CurrPtr = (UINT8*) &((EFI_ACPI_DESCRIPTION_HEADER*) (Table))[1]; >> + CurrPtr = CurrPtr + 4 + 8; // revision + reserved >> + NextValidPtr = CurrPtr + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[0].Length * MaxMemoryNode; >> + EndPtr = (UINT8*) (Table); >> + EndPtr = EndPtr + (Table)->Length; >> + NeedRemoveLength = ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[0].Length * (MaxMemoryNode - MemoryNodeNum); >> + >> + CurrPtr = CurrPtr + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[0].Length * MemoryNodeNum; >> + CopyMem (CurrPtr, NextValidPtr, (UINTN)EndPtr - (UINTN)NextValidPtr); //copy data to current ptr >> + (Table)->Length -= NeedRemoveLength; >> + >> + return EFI_SUCCESS; >> +} >> + >> +STATIC >> +EFI_STATUS >> +UpdateSrat ( >> + IN OUT EFI_ACPI_DESCRIPTION_HEADER *Table >> + ) >> +{ >> + UINT8 Skt = 0; >> + UINT8 Ch = 0; >> + VOID* HobList; >> + GBL_DATA *Gbl_Data; >> + UINTN Base; >> + UINTN Size; >> + UINT8 NodeId; >> + UINT32 DieInterleaveEn; >> + UINT8 i; >> + >> + DEBUG(( EFI_D_ERROR, "\nSRAT: Updating SRAT memory information!\n" )); >> + >> + HobList = GetHobList(); >> + Gbl_Data = (GBL_DATA*)GetNextGuidHob(&gHisiEfiMemoryMapGuid, HobList); >> + Gbl_Data = GET_GUID_HOB_DATA(Gbl_Data); >> + for(Skt = 0; Skt < MAX_SOCKET; Skt++){ >> + for(Ch = 0; Ch < MAX_NUM_PER_TYPE; Ch++){ >> + NodeId = Gbl_Data->NumaInfo[Skt][Ch].NodeId; >> + Base = Gbl_Data->NumaInfo[Skt][Ch].Base; >> + Size = Gbl_Data->NumaInfo[Skt][Ch].Length; >> + DieInterleaveEn = Gbl_Data->NumaInfo[Skt][Ch].DieInterleaveEn; >> + DEBUG((EFI_D_INFO,"Skt %d Ch: %d NodeId = %d, Base = 0x%lx, Size = 0x%lx, DieInterLeaveEn = %d\n",Skt,Ch,NodeId,Base,Size,DieInterleaveEn)); >> + if (Size > 0) >> + { >> + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[MemoryNode].ProximityDomain = NodeId; >> + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[MemoryNode].AddressBaseLow = Base; >> + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[MemoryNode].AddressBaseHigh = Base >> 32; >> + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[MemoryNode].LengthLow = Size; >> + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[MemoryNode].LengthHigh = Size >> 32; >> + MemoryNode = MemoryNode + 1; >> + } >> + } >> + } >> + >> + //update gicc structure >> + if(DieInterleaveEn != 0) >> + { >> + DEBUG(( EFI_D_ERROR, "\nSRAT: Updating SRAT Gicc information!\n" )); >> + for (i = 0; i < 32; i ++) >> + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Gicc[i].ProximityDomain = 0; >> + for (i = 32; i < 64; i ++) >> + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Gicc[i].ProximityDomain = 2; >> + } >> + >> + //remove invalid memory node >> + (VOID)RemoveInvalidMemoryNode (Table, MemoryNode); >> + >> + return EFI_SUCCESS; >> + >> +} >> + >> +STATIC >> +EFI_STATUS >> +UpdateSlit ( >> + IN OUT EFI_ACPI_DESCRIPTION_HEADER *Table >> + ) >> +{ >> + return EFI_SUCCESS; >> +} >> + >> +VOID >> +UpdateAcpiTable ( >> + IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader, >> + IN OUT EFI_STATUS *CommonCodeReturnStatus >> +) >> +{ >> + switch ((TableHeader)->Signature) { >> + >> + case EFI_ACPI_6_0_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE: >> + *CommonCodeReturnStatus = UpdateSrat (TableHeader); >> + break; >> + >> + case EFI_ACPI_6_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE: >> + *CommonCodeReturnStatus = UpdateSlit (TableHeader); >> + break; >> + } >> + return; >> +} >> -- >> 1.9.1 >>
diff --git a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c new file mode 100644 index 0000000..c915a89 --- /dev/null +++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c @@ -0,0 +1,299 @@ +/** @file + Sample ACPI Platform Driver + + Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR> + 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 <PiDxe.h> + +#include <Protocol/AcpiTable.h> +#include <Protocol/FirmwareVolume2.h> + +#include <Library/BaseLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/DebugLib.h> +#include <Library/PcdLib.h> + +#include <IndustryStandard/Acpi.h> + +EFI_STATUS +PlatformUpdateTables ( + IN OUT EFI_ACPI_COMMON_HEADER **Table + ); + +VOID +UpdateAcpiTable ( + IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader, + IN OUT EFI_STATUS *CommonCodeReturnStatus +); + +/** + 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 + storage file. + + @param Instance Return pointer to the first instance of the protocol + + @return EFI_SUCCESS The function completed successfully. + @return EFI_NOT_FOUND The protocol could not be located. + @return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol. + +**/ +EFI_STATUS +LocateFvInstanceWithTables ( + OUT EFI_FIRMWARE_VOLUME2_PROTOCOL **Instance + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN NumberOfHandles; + EFI_FV_FILETYPE FileType; + UINT32 FvStatus; + EFI_FV_FILE_ATTRIBUTES Attributes; + UINTN Size; + UINTN Index; + EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance; + + FvStatus = 0; + + // + // Locate protocol. + // + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiFirmwareVolume2ProtocolGuid, + NULL, + &NumberOfHandles, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + // + // Defined errors at this time are not found and out of resources. + // + return Status; + } + + + + // + // Looking for FV with ACPI storage file + // + + for (Index = 0; Index < NumberOfHandles; Index++) { + // + // Get the protocol on this handle + // This should not fail because of LocateHandleBuffer + // + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiFirmwareVolume2ProtocolGuid, + (VOID**) &FvInstance + ); + ASSERT_EFI_ERROR (Status); + + // + // See if it has the ACPI storage file + // + Status = FvInstance->ReadFile ( + FvInstance, + (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile), + NULL, + &Size, + &FileType, + &Attributes, + &FvStatus + ); + + // + // If we found it, then we are done + // + if (Status == EFI_SUCCESS) { + *Instance = FvInstance; + break; + } + } + + // + // Our exit status is determined by the success of the previous operations + // If the protocol was found, Instance already points to it. + // + + // + // Free any allocated buffers + // + gBS->FreePool (HandleBuffer); + + return Status; +} + + +/** + This function calculates and updates an UINT8 checksum. + + @param Buffer Pointer to buffer to checksum + @param Size Number of bytes to checksum + +**/ +VOID +AcpiPlatformChecksum ( + IN UINT8 *Buffer, + IN UINTN Size + ) +{ + UINTN ChecksumOffset; + + ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum); + + // + // Set checksum to 0 first + // + Buffer[ChecksumOffset] = 0; + + // + // Update checksum value + // + Buffer[ChecksumOffset] = CalculateCheckSum8(Buffer, Size); +} + + +/** + Entrypoint of Acpi Platform driver. + + @param ImageHandle + @param SystemTable + + @return EFI_SUCCESS + @return EFI_LOAD_ERROR + @return EFI_OUT_OF_RESOURCES + +**/ +EFI_STATUS +EFIAPI +AcpiPlatformEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_ACPI_TABLE_PROTOCOL *AcpiTable; + EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol; + INTN Instance; + EFI_ACPI_COMMON_HEADER *CurrentTable; + UINTN TableHandle; + UINT32 FvStatus; + UINTN TableSize; + UINTN Size; + EFI_STATUS TableStatus; + + Instance = 0; + CurrentTable = NULL; + TableHandle = 0; + + // + // Find the AcpiTable protocol + // + Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + + // + // Locate the firmware volume protocol + // + Status = LocateFvInstanceWithTables (&FwVol); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + // + // Read tables from the storage file. + // + while (Status == EFI_SUCCESS) { + + Status = FwVol->ReadSection ( + FwVol, + (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile), + EFI_SECTION_RAW, + Instance, + (VOID**) &CurrentTable, + &Size, + &FvStatus + ); + if (!EFI_ERROR(Status)) { + // + // Add the table + // + TableStatus = PlatformUpdateTables (&CurrentTable); + if (TableStatus == EFI_SUCCESS) { + // + // 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 + ); + + // + // Free memory allocated by ReadSection + // + gBS->FreePool (CurrentTable); + + if (EFI_ERROR(Status)) { + return EFI_ABORTED; + } + + // + // Increment the instance + // + Instance++; + CurrentTable = NULL; + } + } + } +return EFI_SUCCESS; +} +/** + This function will update any runtime platform specific information. + @param Table The table to update + + @return EFI_SUCCESS The function completed successfully. + +**/ +EFI_STATUS +PlatformUpdateTables ( + IN OUT EFI_ACPI_COMMON_HEADER **Table + ) +{ + EFI_STATUS Status; + EFI_ACPI_DESCRIPTION_HEADER *TableHeader; + + Status = EFI_SUCCESS; + + TableHeader = (EFI_ACPI_DESCRIPTION_HEADER*) (*Table); + + UpdateAcpiTable(TableHeader, &Status); + + return Status; +} + diff --git a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.uni b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.uni new file mode 100644 index 0000000..1275549 --- /dev/null +++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.uni @@ -0,0 +1,22 @@ +// /** @file +// Sample ACPI Platform Driver +// +// Sample ACPI Platform Driver +// +// Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR> +// +// 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. +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Sample ACPI Platform Driver" + +#string STR_MODULE_DESCRIPTION #language en-US "Sample ACPI Platform Driver" + diff --git a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf new file mode 100644 index 0000000..4caa7a4 --- /dev/null +++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf @@ -0,0 +1,59 @@ +## @file +# Sample ACPI Platform Driver +# +# Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR> +# 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. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = AcpiPlatform + MODULE_UNI_FILE = AcpiPlatform.uni + FILE_GUID = cb933912-df8f-4305-b1f9-7b44fa11395c + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = AcpiPlatformEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + AcpiPlatform.c + UpdateAcpiTable.c +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + OpenPlatformPkg/Chips/Hisilicon/HisiPkg.dec + +[LibraryClasses] + UefiLib + DxeServicesLib + PcdLib + BaseMemoryLib + DebugLib + UefiBootServicesTableLib + UefiDriverEntryPoint + HobLib + +[Protocols] + gEfiAcpiTableProtocolGuid ## CONSUMES +[Guids] + gHisiEfiMemoryMapGuid +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiTableStorageFile ## CONSUMES + +[Depex] + gEfiAcpiTableProtocolGuid + +[UserExtensions.TianoCore."ExtraFiles"] + AcpiPlatformExtra.uni diff --git a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformExtra.uni b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformExtra.uni new file mode 100644 index 0000000..4c21968 --- /dev/null +++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformExtra.uni @@ -0,0 +1,20 @@ +// /** @file +// AcpiPlatform Localized Strings and Content +// +// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR> +// +// 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. +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"ACPI Platform Sample DXE Driver" + + diff --git a/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c new file mode 100644 index 0000000..702f959 --- /dev/null +++ b/Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c @@ -0,0 +1,127 @@ + +#include <Library/BaseLib.h> +#include <Library/DebugLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/UefiLib.h> +#include <IndustryStandard/Acpi61.h> +#include <PlatformArch.h> +#include <Library/OemMiscLib.h> +#include <Library/AcpiNextLib.h> +#include <Library/HobLib.h> +#include <Library/HwMemInitLib.h> + +#define MaxMemoryNode 10 +UINT8 MemoryNode = 0; + +EFI_STATUS +RemoveInvalidMemoryNode ( + IN OUT EFI_ACPI_DESCRIPTION_HEADER *Table, + IN UINTN MemoryNodeNum +) +{ + UINT8 *CurrPtr, *EndPtr, *NextValidPtr; + UINT32 NeedRemoveLength; + if (MemoryNodeNum >= MaxMemoryNode) + { + DEBUG((EFI_D_ERROR, "There are no invalid memory node\n")); + return EFI_INVALID_PARAMETER; + } + CurrPtr = (UINT8*) &((EFI_ACPI_DESCRIPTION_HEADER*) (Table))[1]; + CurrPtr = CurrPtr + 4 + 8; // revision + reserved + NextValidPtr = CurrPtr + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[0].Length * MaxMemoryNode; + EndPtr = (UINT8*) (Table); + EndPtr = EndPtr + (Table)->Length; + NeedRemoveLength = ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[0].Length * (MaxMemoryNode - MemoryNodeNum); + + CurrPtr = CurrPtr + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[0].Length * MemoryNodeNum; + CopyMem (CurrPtr, NextValidPtr, (UINTN)EndPtr - (UINTN)NextValidPtr); //copy data to current ptr + (Table)->Length -= NeedRemoveLength; + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +UpdateSrat ( + IN OUT EFI_ACPI_DESCRIPTION_HEADER *Table + ) +{ + UINT8 Skt = 0; + UINT8 Ch = 0; + VOID* HobList; + GBL_DATA *Gbl_Data; + UINTN Base; + UINTN Size; + UINT8 NodeId; + UINT32 DieInterleaveEn; + UINT8 i; + + DEBUG(( EFI_D_ERROR, "\nSRAT: Updating SRAT memory information!\n" )); + + HobList = GetHobList(); + Gbl_Data = (GBL_DATA*)GetNextGuidHob(&gHisiEfiMemoryMapGuid, HobList); + Gbl_Data = GET_GUID_HOB_DATA(Gbl_Data); + for(Skt = 0; Skt < MAX_SOCKET; Skt++){ + for(Ch = 0; Ch < MAX_NUM_PER_TYPE; Ch++){ + NodeId = Gbl_Data->NumaInfo[Skt][Ch].NodeId; + Base = Gbl_Data->NumaInfo[Skt][Ch].Base; + Size = Gbl_Data->NumaInfo[Skt][Ch].Length; + DieInterleaveEn = Gbl_Data->NumaInfo[Skt][Ch].DieInterleaveEn; + DEBUG((EFI_D_INFO,"Skt %d Ch: %d NodeId = %d, Base = 0x%lx, Size = 0x%lx, DieInterLeaveEn = %d\n",Skt,Ch,NodeId,Base,Size,DieInterleaveEn)); + if (Size > 0) + { + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[MemoryNode].ProximityDomain = NodeId; + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[MemoryNode].AddressBaseLow = Base; + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[MemoryNode].AddressBaseHigh = Base >> 32; + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[MemoryNode].LengthLow = Size; + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[MemoryNode].LengthHigh = Size >> 32; + MemoryNode = MemoryNode + 1; + } + } + } + + //update gicc structure + if(DieInterleaveEn != 0) + { + DEBUG(( EFI_D_ERROR, "\nSRAT: Updating SRAT Gicc information!\n" )); + for (i = 0; i < 32; i ++) + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Gicc[i].ProximityDomain = 0; + for (i = 32; i < 64; i ++) + ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Gicc[i].ProximityDomain = 2; + } + + //remove invalid memory node + (VOID)RemoveInvalidMemoryNode (Table, MemoryNode); + + return EFI_SUCCESS; + +} + +STATIC +EFI_STATUS +UpdateSlit ( + IN OUT EFI_ACPI_DESCRIPTION_HEADER *Table + ) +{ + return EFI_SUCCESS; +} + +VOID +UpdateAcpiTable ( + IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader, + IN OUT EFI_STATUS *CommonCodeReturnStatus +) +{ + switch ((TableHeader)->Signature) { + + case EFI_ACPI_6_0_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE: + *CommonCodeReturnStatus = UpdateSrat (TableHeader); + break; + + case EFI_ACPI_6_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE: + *CommonCodeReturnStatus = UpdateSlit (TableHeader); + break; + } + return; +}
AcpiPlatformDxe in MdeModulePkg is overridden to support ACPI/SRAT self update from real memory configuration on board. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Heyi Guo <heyi.guo@linaro.org> Cc: Graeme Gregory <graeme.gregory@linaro.org> --- .../Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c | 299 +++++++++++++++++++++ .../Drivers/HisiAcpiPlatformDxe/AcpiPlatform.uni | 22 ++ .../HisiAcpiPlatformDxe/AcpiPlatformDxe.inf | 59 ++++ .../HisiAcpiPlatformDxe/AcpiPlatformExtra.uni | 20 ++ .../Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c | 127 +++++++++ 5 files changed, 527 insertions(+) create mode 100644 Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c create mode 100644 Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.uni create mode 100644 Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf create mode 100644 Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformExtra.uni create mode 100644 Chips/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c