summaryrefslogtreecommitdiff
path: root/Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe
diff options
context:
space:
mode:
Diffstat (limited to 'Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe')
-rw-r--r--Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c269
-rw-r--r--Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.uni22
-rw-r--r--Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf62
-rw-r--r--Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformExtra.uni20
-rw-r--r--Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c137
-rw-r--r--Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.h16
6 files changed, 526 insertions, 0 deletions
diff --git a/Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c b/Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c
new file mode 100644
index 0000000000..c8b56e1bd1
--- /dev/null
+++ b/Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.c
@@ -0,0 +1,269 @@
+/** @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>
+#include "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
+ 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;
+ EFI_ACPI_DESCRIPTION_HEADER *TableHeader;
+
+ 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
+ //
+ 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
+ //
+ gBS->FreePool (CurrentTable);
+
+ if (EFI_ERROR(Status)) {
+ return EFI_ABORTED;
+ }
+
+ //
+ // Increment the instance
+ //
+ Instance++;
+ CurrentTable = NULL;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.uni b/Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatform.uni
new file mode 100644
index 0000000000..1275549bd0
--- /dev/null
+++ b/Silicon/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/Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf b/Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf
new file mode 100644
index 0000000000..e268a56bbd
--- /dev/null
+++ b/Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformDxe.inf
@@ -0,0 +1,62 @@
+## @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
+ Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+ UefiLib
+ DxeServicesLib
+ PcdLib
+ BaseMemoryLib
+ DebugLib
+ HobLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+
+[Protocols]
+ gEfiAcpiTableProtocolGuid ## CONSUMES
+
+[Guids]
+ gHisiEfiMemoryMapGuid
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiTableStorageFile ## CONSUMES
+
+[Depex]
+ gEfiAcpiTableProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ AcpiPlatformExtra.uni
diff --git a/Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformExtra.uni b/Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/AcpiPlatformExtra.uni
new file mode 100644
index 0000000000..4c21968f7a
--- /dev/null
+++ b/Silicon/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/Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c b/Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.c
new file mode 100644
index 0000000000..7d06fccc2b
--- /dev/null
+++ b/Silicon/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
+#define CORECOUNT(X) ((X) * CORE_NUM_PER_SOCKET)
+
+STATIC
+VOID
+RemoveUnusedMemoryNode (
+ IN OUT EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *Table,
+ IN UINTN MemoryNodeNum
+)
+{
+ UINTN CurrPtr, NewPtr;
+
+ if (MemoryNodeNum >= EFI_ACPI_MEMORY_AFFINITY_STRUCTURE_COUNT) {
+ return;
+ }
+
+ CurrPtr = (UINTN) &(Table->Memory[EFI_ACPI_MEMORY_AFFINITY_STRUCTURE_COUNT]);
+ NewPtr = (UINTN) &(Table->Memory[MemoryNodeNum]);
+
+ CopyMem ((VOID *)NewPtr, (VOID *)CurrPtr, (UINTN)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;
+ 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 (Index = CORECOUNT (Skt); Index < CORECOUNT (Skt + 1); Index++) {
+ Table->Gicc[Index].ProximityDomain = Skt * NODE_IN_SOCKET;
+ }
+ }
+ }
+
+ //remove invalid memory node
+ RemoveUnusedMemoryNode (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;
+}
diff --git a/Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.h b/Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.h
new file mode 100644
index 0000000000..45b3729b6a
--- /dev/null
+++ b/Silicon/Hisilicon/Drivers/HisiAcpiPlatformDxe/UpdateAcpiTable.h
@@ -0,0 +1,16 @@
+/** @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.
+**/
+
+EFI_STATUS
+UpdateAcpiTable (
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader
+);
+