From nobody Sat May 18 21:45:23 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+87426+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+87426+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1646952113; cv=none; d=zohomail.com; s=zohoarc; b=bunZLSskU+8BooR5UfbB3lZN4fPyAcwrN0ZunkCd8hS6hJlM4/CxJBdMfAGpoJWF5NqeRUfwIDhWzfNgrGzBEC7cUk2uqxFDLb1BxJdMxf0r4a6Suipb4De/sPjpffJ/SgLrT0+Gwy05+0TEpv/3I2Fx6emzQpeWYMbrTvMnDBw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1646952113; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=Sdk2X1losltBHBZZTNhrHXEYF5yTYyelpTaSdPQlyiw=; b=eHyrnyRP94aVnkn3DWiEnHFu0fPXCFAFM2+cKlxSSB3mT+3SNXb5/5UZYfEZp11/CG7UmWeIKZsj6RSiYyhOyXw2yxg3774JXZHSTMvtwO27ZIGAJVgLQ5N04wkTmGtPCMAF5cRUPLJH+2NCtiw2l19rHzJlc5GmEsZVW4/5ESY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+87426+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1646952113537646.3085022981344; Thu, 10 Mar 2022 14:41:53 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id ICvMYY1788612xx6xqmcMxnM; Thu, 10 Mar 2022 14:41:53 -0800 X-Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mx.groups.io with SMTP id smtpd.web12.859.1646952111350461854 for ; Thu, 10 Mar 2022 14:41:52 -0800 X-IronPort-AV: E=McAfee;i="6200,9189,10282"; a="316121247" X-IronPort-AV: E=Sophos;i="5.90,171,1643702400"; d="scan'208";a="316121247" X-Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2022 14:41:34 -0800 X-IronPort-AV: E=Sophos;i="5.90,171,1643702400"; d="scan'208";a="644643357" X-Received: from iworam-desk.amr.corp.intel.com ([10.7.150.60]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2022 14:41:34 -0800 From: "Oram, Isaac W" To: devel@edk2.groups.io Cc: Nate DeSimone , Chasel Chiu Subject: [edk2-devel][edk2-platforms][PATCH V1 1/9] WhitleyOpenBoardPkg: Add definitions needed for AcpiPlatform driver Date: Thu, 10 Mar 2022 14:41:06 -0800 Message-Id: <4b0048531cbe38f4d7944fa7e12c69f8634de32e.1646951441.git.isaac.w.oram@intel.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,isaac.w.oram@intel.com X-Gm-Message-State: axlG0ZIj3MMSfgRiEptgVHsix1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1646952113; bh=6gd5d8uFjfq/wfNTp1Ky0E9SO1iGmo3RvtuXig8IfV8=; h=Cc:Date:From:Reply-To:Subject:To; b=F1q1gBbcMYxKmYzsMj6o68krvr8W+ahz2AkXC/upq80L1fBdBVD65u66jIK8JAU216h zLPuCEgnHrr//sE2ZSDqgbmWItRgF41BUaM47qCpavlwmbwf18cqWJNzyYiUmVuUUUwqQ oCaK6SyIbyWvGWzatt+ICQUg/2MFD1M+Yd0= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1646953017597100001 Content-Type: text/plain; charset="utf-8" Adds various definitions needed to move the AcpiPlatform driver from FvLateOpenBoard binary to open source. Cc: Nate DeSimone Cc: Chasel Chiu Signed-off-by: Isaac Oram Reviewed-by: Nate DeSimone --- Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciHostBridge/PciHostB= ridge.inf | 1 + Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciPlatform/PciPlatfor= m.inf | 1 + Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Madt.h = | 118 +++++ Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Slit.h = | 75 +++ Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Srat.h = | 53 ++ Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/amlresrc.h = | 542 ++++++++++++++++++++ Platform/Intel/WhitleyOpenBoardPkg/Include/Dsc/BuildOptions.dsc = | 6 +- Platform/Intel/WhitleyOpenBoardPkg/Include/Library/AcpiPlatformLib.h = | 107 ++++ Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformStatusCodes.h = | 364 +++++++++++++ Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaFpkConfigLib.h = | 55 ++ Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaSmbiosUpdateLib.h = | 275 ++++++++++ Platform/Intel/WhitleyOpenBoardPkg/Library/BoardInitLib/BoardInitDxeLib.in= f | 1 + 12 files changed, 1597 insertions(+), 1 deletion(-) diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciHostBri= dge/PciHostBridge.inf b/Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe= /PciHostBridge/PciHostBridge.inf index faea9726f7..80a4288895 100644 --- a/Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciHostBridge/Pci= HostBridge.inf +++ b/Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciHostBridge/Pci= HostBridge.inf @@ -34,6 +34,7 @@ WhitleySiliconPkg/CpRcPkg.dec WhitleySiliconPkg/Cpu/CpuRcPkg.dec WhitleyOpenBoardPkg/PlatformPkg.dec + UefiCpuPkg/UefiCpuPkg.dec =20 [LibraryClasses] UefiDriverEntryPoint diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciPlatfor= m/PciPlatform.inf b/Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/Pci= Platform/PciPlatform.inf index 4121ea8982..cf5148b135 100644 --- a/Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciPlatform/PciPl= atform.inf +++ b/Platform/Intel/WhitleyOpenBoardPkg/Features/Pci/Dxe/PciPlatform/PciPl= atform.inf @@ -32,6 +32,7 @@ WhitleySiliconPkg/CpRcPkg.dec WhitleySiliconPkg/Cpu/CpuRcPkg.dec WhitleyOpenBoardPkg/PlatformPkg.dec + UefiCpuPkg/UefiCpuPkg.dec =20 [LibraryClasses] UefiDriverEntryPoint diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Madt.h b/Platf= orm/Intel/WhitleyOpenBoardPkg/Include/Acpi/Madt.h new file mode 100644 index 0000000000..1860e1104d --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Madt.h @@ -0,0 +1,118 @@ +/** @file + This file describes the contents of the ACPI Multiple APIC Description + Table (MADT). Some additional ACPI values are defined in Acpi1_0.h and + Acpi2_0.h. + To make changes to the MADT, it is necessary to update the count for the + APIC structure being updated, and to modify table found in Madt.c. + + @copyright + Copyright 1996 - 2014 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _MADT_H +#define _MADT_H + +// +// Statements that include other files +// +#include +#include "Platform.h" + +// +// MADT Definitions +// +#define EFI_ACPI_OEM_MADT_REVISION 0x00000000 +// +// Multiple APIC Flags are defined in AcpiX.0.h +// +#define EFI_ACPI_6_2_MULTIPLE_APIC_FLAGS (EFI_ACPI_6_2_PCAT_COMPAT) + +// +// Local APIC address +// +#define EFI_ACPI_LOCAL_APIC_ADDRESS 0xFEE00000 +// +// Define the number of each table type. +// This is where the table layout is modified. +// +#define EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT MAX_CPU_NUM +#define EFI_ACPI_LOCAL_APIC_NMI_COUNT MAX_CPU_NUM +#define EFI_ACPI_PROCESSOR_LOCAL_X2APIC_COUNT MAX_CPU_NUM +#define EFI_ACPI_LOCAL_X2APIC_NMI_COUNT MAX_CPU_NUM +#define EFI_ACPI_IO_APIC_COUNT 32 + 1 // IIO I/O A= PIC (PCH) + I/O APIC (PC00-PC31) +#define EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT 2 +#define EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT 0 +#define EFI_ACPI_LOCAL_APIC_ADDRESS_OVERRIDE_COUNT 0 +#define EFI_ACPI_IO_SAPIC_COUNT 0 +#define EFI_ACPI_PROCESSOR_LOCAL_SAPIC_COUNT 0 +#define EFI_ACPI_PLATFORM_INTERRUPT_SOURCES_COUNT 0 + +// +// MADT structure +// +// +// Ensure proper structure formats +// +#pragma pack(1) +// +// ACPI 4.0 Table structure +// +typedef struct { + EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER Header; + +#if EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT > 0 // Type 0x00 + EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_STRUCTURE LocalApic[EFI_ACPI= _PROCESSOR_LOCAL_APIC_COUNT]; +#endif + +#if EFI_ACPI_IO_APIC_COUNT > 0 // Type 0x01 + EFI_ACPI_6_2_IO_APIC_STRUCTURE IoApic[EFI_ACPI_IO= _APIC_COUNT]; +#endif + +#if EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT > 0 // Type 0x02 + EFI_ACPI_6_2_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE Iso[EFI_ACPI_INTER= RUPT_SOURCE_OVERRIDE_COUNT]; +#endif + +#if EFI_ACPI_NON_MASKABLE_INTERRUPT_SOURCE_COUNT > 0 // Type 0x03 + EFI_ACPI_6_2_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE NmiSource[EFI_ACPI= _NON_MASKABLE_INTERRUPT_SOURCE_COUNT]; +#endif + +#if EFI_ACPI_LOCAL_APIC_NMI_COUNT > 0 // Type 0x04 + EFI_ACPI_6_2_LOCAL_APIC_NMI_STRUCTURE LocalApicNmi; +#endif + +#if EFI_ACPI_LOCAL_APIC_ADDRESS_OVERRIDE_COUNT > 0 // Type 0x05 + EFI_ACPI_6_2_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE LocalApicOverride[= EFI_ACPI_LOCAL_APIC_OVERRIDE_COUNT]; +#endif + +#if EFI_ACPI_IO_SAPIC_COUNT > 0 // Type 0x06 + EFI_ACPI_6_2_IO_SAPIC_STRUCTURE IoSapic[EFI_ACPI_I= O_SAPIC_COUNT]; +#endif + +#if EFI_ACPI_PROCESSOR_LOCAL_SAPIC_COUNT > 0 // Type 0x07 : Thi= s table changes in madt 2.0 + EFI_ACPI_6_2_PROCESSOR_LOCAL_SAPIC_STRUCTURE LocalSapic[EFI_ACP= I_PROCESSOR_LOCAL_SAPIC_COUNT]; +#endif + +#if EFI_ACPI_PLATFORM_INTERRUPT_SOURCES_COUNT > 0 // Type 0x08 + EFI_ACPI_6_2_PLATFORM_INTERRUPT_SOURCES_STRUCTURE PlatformInterruptS= ources[ + EFI_ACPI_PLATFORM_INTERRUPT_SOURCES_COUNT]; +#endif + +#if EFI_ACPI_PROCESSOR_LOCAL_X2APIC_COUNT > 0 //Type 0x09 + EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_STRUCTURE LocalX2Apic[EFI_ACPI_PROCE= SSOR_LOCAL_X2APIC_COUNT]; +#endif + +#if EFI_ACPI_LOCAL_X2APIC_NMI_COUNT > 0 //Type 0x0A + EFI_ACPI_6_2_LOCAL_X2APIC_NMI_STRUCTURE X2ApicNmi; +#endif + + +} EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE; + + + + +#pragma pack() + +#endif diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Slit.h b/Platf= orm/Intel/WhitleyOpenBoardPkg/Include/Acpi/Slit.h new file mode 100644 index 0000000000..bda37bc3cf --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Slit.h @@ -0,0 +1,75 @@ +/** @file + This file describes the contents of the ACPI System Locality Information + Table (SLIT). Some additional ACPI 3.0 values are defined in Acpi3_0.h. + All changes to the Slit contents should be done in this file. + + @copyright + Copyright 1999 - 2019 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _SLIT_H_ +#define _SLIT_H_ + +#include "MaxSocket.h" + +// +// SLIT Definitions, see TBD specification for details. +// + +#define EFI_ACPI_OEM_SLIT_REVISION 0x00000001 +// +// SLIT Revision (defined in spec) +// +#define EFI_ACPI_SLIT_PMEM_NODES_SOCKET_MAX_CNT 8 // Max number of PMEM n= odes per socket +#define EFI_ACPI_SLIT_NODES_SOCKET_MAX_CNT 4 // Max number of SNC no= des +#define EFI_ACPI_SLIT_DOMAINS_NODES_MAX_CNT 2 // Max number of Domins= per SNC node (1LM domain and 2LM domain) + +#define EFI_ACPI_SLIT_NODES_MAX_CNT \ + (MAX_SOCKET * ((EFI_ACPI_SLIT_NODES_SOCKET_MAX_CNT * EFI_ACPI_SLIT_DOMAI= NS_NODES_MAX_CNT) \ + + EFI_ACPI_SLIT_PMEM_NODES_SOCKET_MAX_CNT)) + +#define EFI_ACPI_SYSTEM_LOCALITIES_ENTRY_COUNT \ + (EFI_ACPI_SLIT_NODES_MAX_CNT * EFI_ACPI_SLIT_NODES_MAX_CNT) + +#define EFI_ACPI_SLIT_PMEM_INFO_CNT \ + (MAX_SOCKET * EFI_ACPI_SLIT_PMEM_NODES_SOCKET_MAX_CNT) + +#define PMEM_INVALID_SOCKET 0xFF + +#define PMEM_ZERO_HOP 10 +#define PMEM_ONE_ONE 17 +#define PMEM_ONE_HOP 28 +#define PMEM_TWO_HOP 38 + +#define ZERO_HOP 10 +#define ZERO_ONE 11 +#define ZERO_TWO 12 +#define ZERO_THREE 13 +#define ONE_HOP 20 +#define ONE_ONE 21 +#define ONE_TWO 22 +#define TWO_HOP 30 +#define THREE_HOP 40 +#define DISTANT_NODE_4S_EP 2 +#define DISTANT_NODE_4S_EP_COD (DISTANT_NODE_4S_EP * 2) + +typedef struct { + UINT8 Socket; + UINT8 Pmem; + UINT8 Valid; +} EFI_ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE_PMEM_INFO; + +typedef struct { + UINT8 Entry; +} ACPI_SYSTEM_LOCALITIES_STRUCTURE; + +typedef struct { + EFI_ACPI_6_2_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER Header; + ACPI_SYSTEM_LOCALITIES_STRUCTURE NumSli= t[0]; + +} ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE; + + +#endif diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Srat.h b/Platf= orm/Intel/WhitleyOpenBoardPkg/Include/Acpi/Srat.h new file mode 100644 index 0000000000..3f3a6545c2 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/Srat.h @@ -0,0 +1,53 @@ +/** @file + ACPI Static resource definition table implementation, defined at + http://microsoft.com/hwdev/design/srat.htm. + + @copyright + Copyright 1999 - 2019 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _SRAT_H_ +#define _SRAT_H_ + +// +// Statements that include other files +// +#include + +// +#define EFI_ACPI_OEM_SRAT_REVISION 0x00000002 // + +// +// TBD :Backward Compatibility per ACPI 3.0. Required by Hyper-V. OS's ok = so far as of 5/27/09 +// +#define EFI_ACPI_SRAT_RESERVED_FOR_BACKWARD_COMPATIBILITY 0x00000001 +// +// Define the number of each table type. +// This is where the table layout is modified. +// +#define PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE_COUNT MAX_CPU_NUM +#define MEMORY_AFFINITY_STRUCTURE_COUNT MC_MAX_NODE*= MAX_CRS_ENTRIES_PER_NODE +#define X2APIC_AFFINITY_STRUCTURE_COUNT MAX_CPU_NUM +// +// Statis Resource Affinity Table header definition. The table +// must be defined in a platform specific manner. +// +// +// Ensure proper structure formats +// +#pragma pack(1) + +typedef struct { + EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *SratHeader; + + EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE *Apic; + EFI_ACPI_6_2_MEMORY_AFFINITY_STRUCTURE *Memory; + EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE *x2Apic; + +} STATIC_RESOURCE_AFFINITY_TABLE; + +#pragma pack() + +#endif diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/amlresrc.h b/P= latform/Intel/WhitleyOpenBoardPkg/Include/Acpi/amlresrc.h new file mode 100644 index 0000000000..ddbca04903 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Acpi/amlresrc.h @@ -0,0 +1,542 @@ +/** @file + + @copyright + Copyright 1999 - 2017 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +/* acpisrc:StructDefs -- for acpisrc conversion */ + +#ifndef __AMLRESRC_H +#define __AMLRESRC_H + + +/* + * Resource descriptor tags, as defined in the ACPI specification. + * Used to symbolically reference fields within a descriptor. + */ +#define ACPI_RESTAG_ADDRESS "_ADR" +#define ACPI_RESTAG_ALIGNMENT "_ALN" +#define ACPI_RESTAG_ADDRESSSPACE "_ASI" +#define ACPI_RESTAG_ACCESSSIZE "_ASZ" +#define ACPI_RESTAG_TYPESPECIFICATTRIBUTES "_ATT" +#define ACPI_RESTAG_BASEADDRESS "_BAS" +#define ACPI_RESTAG_BUSMASTER "_BM_" /* Master(1), Slav= e(0) */ +#define ACPI_RESTAG_DEBOUNCETIME "_DBT" +#define ACPI_RESTAG_DECODE "_DEC" +#define ACPI_RESTAG_DEVICEPOLARITY "_DPL" +#define ACPI_RESTAG_DMA "_DMA" +#define ACPI_RESTAG_DMATYPE "_TYP" /* Compatible(0), = A(1), B(2), F(3) */ +#define ACPI_RESTAG_DRIVESTRENGTH "_DRS" +#define ACPI_RESTAG_ENDIANNESS "_END" +#define ACPI_RESTAG_FLOWCONTROL "_FLC" +#define ACPI_RESTAG_GRANULARITY "_GRA" +#define ACPI_RESTAG_INTERRUPT "_INT" +#define ACPI_RESTAG_INTERRUPTLEVEL "_LL_" /* ActiveLo(1), Ac= tiveHi(0) */ +#define ACPI_RESTAG_INTERRUPTSHARE "_SHR" /* Shareable(1), N= oShare(0) */ +#define ACPI_RESTAG_INTERRUPTTYPE "_HE_" /* Edge(1), Level(= 0) */ +#define ACPI_RESTAG_IORESTRICTION "_IOR" +#define ACPI_RESTAG_LENGTH "_LEN" +#define ACPI_RESTAG_LINE "_LIN" +#define ACPI_RESTAG_MEMATTRIBUTES "_MTP" /* Memory(0), Rese= rved(1), ACPI(2), NVS(3) */ +#define ACPI_RESTAG_MEMTYPE "_MEM" /* NonCache(0), Ca= cheable(1) Cache+combine(2), Cache+prefetch(3) */ +#define ACPI_RESTAG_MAXADDR "_MAX" +#define ACPI_RESTAG_MINADDR "_MIN" +#define ACPI_RESTAG_MAXTYPE "_MAF" +#define ACPI_RESTAG_MINTYPE "_MIF" +#define ACPI_RESTAG_MODE "_MOD" +#define ACPI_RESTAG_PARITY "_PAR" +#define ACPI_RESTAG_PHASE "_PHA" +#define ACPI_RESTAG_PIN "_PIN" +#define ACPI_RESTAG_PINCONFIG "_PPI" +#define ACPI_RESTAG_POLARITY "_POL" +#define ACPI_RESTAG_REGISTERBITOFFSET "_RBO" +#define ACPI_RESTAG_REGISTERBITWIDTH "_RBW" +#define ACPI_RESTAG_RANGETYPE "_RNG" +#define ACPI_RESTAG_READWRITETYPE "_RW_" /* ReadOnly(0), Wr= iteable (1) */ +#define ACPI_RESTAG_LENGTH_RX "_RXL" +#define ACPI_RESTAG_LENGTH_TX "_TXL" +#define ACPI_RESTAG_SLAVEMODE "_SLV" +#define ACPI_RESTAG_SPEED "_SPE" +#define ACPI_RESTAG_STOPBITS "_STB" +#define ACPI_RESTAG_TRANSLATION "_TRA" +#define ACPI_RESTAG_TRANSTYPE "_TRS" /* Sparse(1), Dens= e(0) */ +#define ACPI_RESTAG_TYPE "_TTP" /* Translation(1),= Static (0) */ +#define ACPI_RESTAG_XFERTYPE "_SIZ" /* 8(0), 8And16(1)= , 16(2) */ +#define ACPI_RESTAG_VENDORDATA "_VEN" + + +/* Default sizes for "small" resource descriptors */ + +#define ASL_RDESC_IRQ_SIZE 0x02 +#define ASL_RDESC_DMA_SIZE 0x02 +#define ASL_RDESC_ST_DEPEND_SIZE 0x00 +#define ASL_RDESC_END_DEPEND_SIZE 0x00 +#define ASL_RDESC_IO_SIZE 0x07 +#define ASL_RDESC_FIXED_IO_SIZE 0x03 +#define ASL_RDESC_FIXED_DMA_SIZE 0x05 +#define ASL_RDESC_END_TAG_SIZE 0x01 + + +typedef struct asl_resource_node +{ + UINT32 BufferLength; + VOID *Buffer; + struct asl_resource_node *Next; + +} ASL_RESOURCE_NODE; + + +/* Macros used to generate AML resource length fields */ + +#define ACPI_AML_SIZE_LARGE(r) (sizeof (r) - sizeof (AML_RESOURCE_LAR= GE_HEADER)) +#define ACPI_AML_SIZE_SMALL(r) (sizeof (r) - sizeof (AML_RESOURCE_SMA= LL_HEADER)) + +/* + * Resource descriptors defined in the ACPI specification. + * + * Packing/alignment must be BYTE because these descriptors + * are used to overlay the raw AML byte stream. + */ +#pragma pack(1) + +/* + * SMALL descriptors + */ +#define AML_RESOURCE_SMALL_HEADER_COMMON \ + UINT8 DescriptorType; + +typedef struct aml_resource_small_header +{ + AML_RESOURCE_SMALL_HEADER_COMMON + +} AML_RESOURCE_SMALL_HEADER; + + +typedef struct aml_resource_irq +{ + AML_RESOURCE_SMALL_HEADER_COMMON + UINT16 IrqMask; + UINT8 Flags; + +} AML_RESOURCE_IRQ; + + +typedef struct aml_resource_irq_noflags +{ + AML_RESOURCE_SMALL_HEADER_COMMON + UINT16 IrqMask; + +} AML_RESOURCE_IRQ_NOFLAGS; + + +typedef struct aml_resource_dma +{ + AML_RESOURCE_SMALL_HEADER_COMMON + UINT8 DmaChannelMask; + UINT8 Flags; + +} AML_RESOURCE_DMA; + + +typedef struct aml_resource_start_dependent +{ + AML_RESOURCE_SMALL_HEADER_COMMON + UINT8 Flags; + +} AML_RESOURCE_START_DEPENDENT; + + +typedef struct aml_resource_start_dependent_noprio +{ + AML_RESOURCE_SMALL_HEADER_COMMON + +} AML_RESOURCE_START_DEPENDENT_NOPRIO; + + +typedef struct aml_resource_end_dependent +{ + AML_RESOURCE_SMALL_HEADER_COMMON + +} AML_RESOURCE_END_DEPENDENT; + + +typedef struct aml_resource_io +{ + AML_RESOURCE_SMALL_HEADER_COMMON + UINT8 Flags; + UINT16 Minimum; + UINT16 Maximum; + UINT8 Alignment; + UINT8 AddressLength; + +} AML_RESOURCE_IO; + + +typedef struct aml_resource_fixed_io +{ + AML_RESOURCE_SMALL_HEADER_COMMON + UINT16 Address; + UINT8 AddressLength; + +} AML_RESOURCE_FIXED_IO; + + +typedef struct aml_resource_vendor_small +{ + AML_RESOURCE_SMALL_HEADER_COMMON + +} AML_RESOURCE_VENDOR_SMALL; + + +typedef struct aml_resource_end_tag +{ + AML_RESOURCE_SMALL_HEADER_COMMON + UINT8 Checksum; + +} AML_RESOURCE_END_TAG; + + +typedef struct aml_resource_fixed_dma +{ + AML_RESOURCE_SMALL_HEADER_COMMON + UINT16 RequestLines; + UINT16 Channels; + UINT8 Width; + +} AML_RESOURCE_FIXED_DMA; + + +/* + * LARGE descriptors + */ +#define AML_RESOURCE_LARGE_HEADER_COMMON \ + UINT8 DescriptorType;\ + UINT16 ResourceLength; + +typedef struct aml_resource_large_header +{ + AML_RESOURCE_LARGE_HEADER_COMMON + +} AML_RESOURCE_LARGE_HEADER; + + +/* General Flags for address space resource descriptors */ + +#define ACPI_RESOURCE_FLAG_DEC 2 +#define ACPI_RESOURCE_FLAG_MIF 4 +#define ACPI_RESOURCE_FLAG_MAF 8 + +typedef struct aml_resource_memory24 +{ + AML_RESOURCE_LARGE_HEADER_COMMON + UINT8 Flags; + UINT16 Minimum; + UINT16 Maximum; + UINT16 Alignment; + UINT16 AddressLength; + +} AML_RESOURCE_MEMORY24; + + +typedef struct aml_resource_vendor_large +{ + AML_RESOURCE_LARGE_HEADER_COMMON + +} AML_RESOURCE_VENDOR_LARGE; + + +typedef struct aml_resource_memory32 +{ + AML_RESOURCE_LARGE_HEADER_COMMON + UINT8 Flags; + UINT32 Minimum; + UINT32 Maximum; + UINT32 Alignment; + UINT32 AddressLength; + +} AML_RESOURCE_MEMORY32; + + +typedef struct aml_resource_fixed_memory32 +{ + AML_RESOURCE_LARGE_HEADER_COMMON + UINT8 Flags; + UINT32 Address; + UINT32 AddressLength; + +} AML_RESOURCE_FIXED_MEMORY32; + + +#define AML_RESOURCE_ADDRESS_COMMON \ + UINT8 ResourceType; \ + UINT8 Flags; \ + UINT8 SpecificFlags; + + +typedef struct aml_resource_address +{ + AML_RESOURCE_LARGE_HEADER_COMMON + AML_RESOURCE_ADDRESS_COMMON + +} AML_RESOURCE_ADDRESS; + + +typedef struct aml_resource_extended_address64 +{ + AML_RESOURCE_LARGE_HEADER_COMMON + AML_RESOURCE_ADDRESS_COMMON + UINT8 RevisionID; + UINT8 Reserved; + UINT64 Granularity; + UINT64 Minimum; + UINT64 Maximum; + UINT64 TranslationOffset; + UINT64 AddressLength; + UINT64 TypeSpecific; + +} AML_RESOURCE_EXTENDED_ADDRESS64; + +#define AML_RESOURCE_EXTENDED_ADDRESS_REVISION 1 /* ACPI 3.= 0 */ + + +typedef struct aml_resource_address64 +{ + AML_RESOURCE_LARGE_HEADER_COMMON + AML_RESOURCE_ADDRESS_COMMON + UINT64 Granularity; + UINT64 Minimum; + UINT64 Maximum; + UINT64 TranslationOffset; + UINT64 AddressLength; + +} AML_RESOURCE_ADDRESS64; + + +typedef struct aml_resource_address32 +{ + AML_RESOURCE_LARGE_HEADER_COMMON + AML_RESOURCE_ADDRESS_COMMON + UINT32 Granularity; + UINT32 Minimum; + UINT32 Maximum; + UINT32 TranslationOffset; + UINT32 AddressLength; + +} AML_RESOURCE_ADDRESS32; + + +typedef struct aml_resource_address16 +{ + AML_RESOURCE_LARGE_HEADER_COMMON + AML_RESOURCE_ADDRESS_COMMON + UINT16 Granularity; + UINT16 Minimum; + UINT16 Maximum; + UINT16 TranslationOffset; + UINT16 AddressLength; + +} AML_RESOURCE_ADDRESS16; + + +typedef struct aml_resource_extended_irq +{ + AML_RESOURCE_LARGE_HEADER_COMMON + UINT8 Flags; + UINT8 InterruptCount; + UINT32 Interrupts[1]; + /* ResSourceIndex, ResSource optional fields follow */ + +} AML_RESOURCE_EXTENDED_IRQ; + + +typedef struct aml_resource_generic_register +{ + AML_RESOURCE_LARGE_HEADER_COMMON + UINT8 AddressSpaceId; + UINT8 BitWidth; + UINT8 BitOffset; + UINT8 AccessSize; /* ACPI 3.0, was previousl= y Reserved */ + UINT64 Address; + +} AML_RESOURCE_GENERIC_REGISTER; + + +/* Common descriptor for GpioInt and GpioIo (ACPI 5.0) */ + +typedef struct aml_resource_gpio +{ + AML_RESOURCE_LARGE_HEADER_COMMON + UINT8 RevisionId; + UINT8 ConnectionType; + UINT16 Flags; + UINT16 IntFlags; + UINT8 PinConfig; + UINT16 DriveStrength; + UINT16 DebounceTimeout; + UINT16 PinTableOffset; + UINT8 ResSourceIndex; + UINT16 ResSourceOffset; + UINT16 VendorOffset; + UINT16 VendorLength; + /* + * Optional fields follow immediately: + * 1) PIN list (Words) + * 2) Resource Source String + * 3) Vendor Data bytes + */ + +} AML_RESOURCE_GPIO; + +#define AML_RESOURCE_GPIO_REVISION 1 /* ACPI 5.0 */ + +/* Values for ConnectionType above */ + +#define AML_RESOURCE_GPIO_TYPE_INT 0 +#define AML_RESOURCE_GPIO_TYPE_IO 1 +#define AML_RESOURCE_MAX_GPIOTYPE 1 + + +/* Common preamble for all serial descriptors (ACPI 5.0) */ + +#define AML_RESOURCE_SERIAL_COMMON \ + UINT8 RevisionId; \ + UINT8 ResSourceIndex; \ + UINT8 Type; \ + UINT8 Flags; \ + UINT16 TypeSpecificFlags; \ + UINT8 TypeRevisionId; \ + UINT16 TypeDataLength; \ + +/* Values for the type field above */ + +#define AML_RESOURCE_I2C_SERIALBUSTYPE 1 +#define AML_RESOURCE_SPI_SERIALBUSTYPE 2 +#define AML_RESOURCE_UART_SERIALBUSTYPE 3 +#define AML_RESOURCE_MAX_SERIALBUSTYPE 3 +#define AML_RESOURCE_VENDOR_SERIALBUSTYPE 192 /* Vendor defined is 0= xC0-0xFF (NOT SUPPORTED) */ + +typedef struct aml_resource_common_serialbus +{ + AML_RESOURCE_LARGE_HEADER_COMMON + AML_RESOURCE_SERIAL_COMMON + +} AML_RESOURCE_COMMON_SERIALBUS; + +typedef struct aml_resource_i2c_serialbus +{ + AML_RESOURCE_LARGE_HEADER_COMMON + AML_RESOURCE_SERIAL_COMMON + UINT32 ConnectionSpeed; + UINT16 SlaveAddress; + /* + * Optional fields follow immediately: + * 1) Vendor Data bytes + * 2) Resource Source String + */ + +} AML_RESOURCE_I2C_SERIALBUS; + +#define AML_RESOURCE_I2C_REVISION 1 /* ACPI 5.0 */ +#define AML_RESOURCE_I2C_TYPE_REVISION 1 /* ACPI 5.0 */ +#define AML_RESOURCE_I2C_MIN_DATA_LEN 6 + +typedef struct aml_resource_spi_serialbus +{ + AML_RESOURCE_LARGE_HEADER_COMMON + AML_RESOURCE_SERIAL_COMMON + UINT32 ConnectionSpeed; + UINT8 DataBitLength; + UINT8 ClockPhase; + UINT8 ClockPolarity; + UINT16 DeviceSelection; + /* + * Optional fields follow immediately: + * 1) Vendor Data bytes + * 2) Resource Source String + */ + +} AML_RESOURCE_SPI_SERIALBUS; + +#define AML_RESOURCE_SPI_REVISION 1 /* ACPI 5.0 */ +#define AML_RESOURCE_SPI_TYPE_REVISION 1 /* ACPI 5.0 */ +#define AML_RESOURCE_SPI_MIN_DATA_LEN 9 + + +typedef struct aml_resource_uart_serialbus +{ + AML_RESOURCE_LARGE_HEADER_COMMON + AML_RESOURCE_SERIAL_COMMON + UINT32 DefaultBaudRate; + UINT16 RxFifoSize; + UINT16 TxFifoSize; + UINT8 Parity; + UINT8 LinesEnabled; + /* + * Optional fields follow immediately: + * 1) Vendor Data bytes + * 2) Resource Source String + */ + +} AML_RESOURCE_UART_SERIALBUS; + +#define AML_RESOURCE_UART_REVISION 1 /* ACPI 5.0 */ +#define AML_RESOURCE_UART_TYPE_REVISION 1 /* ACPI 5.0 */ +#define AML_RESOURCE_UART_MIN_DATA_LEN 10 + + +/* restore default alignment */ + +#pragma pack() + +/* Union of all resource descriptors, so we can allocate the worst case */ + +typedef union aml_resource +{ + /* Descriptor headers */ + + UINT8 DescriptorType; + AML_RESOURCE_SMALL_HEADER SmallHeader; + AML_RESOURCE_LARGE_HEADER LargeHeader; + + /* Small resource descriptors */ + + AML_RESOURCE_IRQ Irq; + AML_RESOURCE_DMA Dma; + AML_RESOURCE_START_DEPENDENT StartDpf; + AML_RESOURCE_END_DEPENDENT EndDpf; + AML_RESOURCE_IO Io; + AML_RESOURCE_FIXED_IO FixedIo; + AML_RESOURCE_FIXED_DMA FixedDma; + AML_RESOURCE_VENDOR_SMALL VendorSmall; + AML_RESOURCE_END_TAG EndTag; + + /* Large resource descriptors */ + + AML_RESOURCE_MEMORY24 Memory24; + AML_RESOURCE_GENERIC_REGISTER GenericReg; + AML_RESOURCE_VENDOR_LARGE VendorLarge; + AML_RESOURCE_MEMORY32 Memory32; + AML_RESOURCE_FIXED_MEMORY32 FixedMemory32; + AML_RESOURCE_ADDRESS16 Address16; + AML_RESOURCE_ADDRESS32 Address32; + AML_RESOURCE_ADDRESS64 Address64; + AML_RESOURCE_EXTENDED_ADDRESS64 ExtAddress64; + AML_RESOURCE_EXTENDED_IRQ ExtendedIrq; + AML_RESOURCE_GPIO Gpio; + AML_RESOURCE_I2C_SERIALBUS I2cSerialBus; + AML_RESOURCE_SPI_SERIALBUS SpiSerialBus; + AML_RESOURCE_UART_SERIALBUS UartSerialBus; + AML_RESOURCE_COMMON_SERIALBUS CommonSerialBus; + + /* Utility overlays */ + + AML_RESOURCE_ADDRESS Address; + UINT32 DwordItem; + UINT16 WordItem; + UINT8 ByteItem; + +} AML_RESOURCE; + +#endif diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Dsc/BuildOptions.ds= c b/Platform/Intel/WhitleyOpenBoardPkg/Include/Dsc/BuildOptions.dsc index d806521abf..1a85a26e25 100644 --- a/Platform/Intel/WhitleyOpenBoardPkg/Include/Dsc/BuildOptions.dsc +++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Dsc/BuildOptions.dsc @@ -134,9 +134,13 @@ DEFINE EDKII_DSC_FEATURE_BUILD_OPTIONS =3D $(EDKII_DSC= _FEATURE_BUILD_OPTIONS) $(ME # # Override the VFR compile flags to speed the build time # - *_*_*_VFR_FLAGS =3D=3D -n =20 +# +# Disable remarks, enable warnings as errors, disable integer optimization, +# + *_*_*_ASL_FLAGS =3D -vr -we -oi + # # add to the build options for DXE/SMM drivers to remove the log message: # !!!!!!!! InsertImageRecord - Section Alignment(0x20) is not 4K !!!!!!!! diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/AcpiPlatfor= mLib.h b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/AcpiPlatformLib= .h new file mode 100644 index 0000000000..8ec25b8c16 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/AcpiPlatformLib.h @@ -0,0 +1,107 @@ +/** @file + + @copyright + Copyright 1996 - 2017 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _ACPI_PLATFORM_LIB_H_ +#define _ACPI_PLATFORM_LIB_H_ + +// +// Statements that include other header files +// +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + + +EFI_STATUS +AcpiPlatformHooksIsActiveTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ); + +/*++ + +Routine Description: + + Called for every ACPI table found in the BIOS flash. + Returns whether a table is active or not. Inactive tables + are not published in the ACPI table list. This hook can be + used to implement optional SSDT tables or enabling/disabling + specific functionality (e.g. SPCR table) based on a setup + switch or platform preference. In case of optional SSDT tables, + the platform flash will include all the SSDT tables but will + return EFI_SUCCESS only for those tables that need to be + published. + This hook can also be used to update the table data. The header + is updated by the common code. For example, if a platform wants + to use an SSDT table to export some platform settings to the + ACPI code, it needs to update the data inside that SSDT based + on platform preferences in this hook. + +Arguments: + + None + +Returns: + + Status - EFI_SUCCESS if the table is active + Status - EFI_UNSUPPORTED if the table is not active +*/ + +/** + + This function will update any runtime platform specific information. + This currently includes: + Setting OEM table values, ID, table ID, creator ID and creator revisio= n. + Enabling the proper processor entries in the APIC tables. + + @param Table - The table to update + + @retval EFI_SUCCESS - The function completed successfully. + +**/ +EFI_STATUS +PlatformUpdateTables ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ,IN OUT EFI_ACPI_TABLE_VERSION *Version + ); + +/** + Give the platform a chance to build tables. + + Some tables can be built from scratch more efficiently than being prebui= lt + and updated. This function builds any such tables for the platform. + + @retval EFI_SUCCESS Any platform tables were successfully built. +**/ +EFI_STATUS +PlatformBuildTables ( + VOID + ); + +/** + Platform hook to initialize Platform Specific ACPI Parameters + + @retval EFI_SUCCESS Platform specific parameters in mAcpiPara= meter + initialized successfully. + @retval EFI_INVALID_PARAMETER mAcpiParameter global was NULL. +**/ +EFI_STATUS +PlatformHookAfterAcpiParamInit ( + VOID + ); + +#endif diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformSta= tusCodes.h b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformSta= tusCodes.h new file mode 100644 index 0000000000..dbe7fa075e --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformStatusCode= s.h @@ -0,0 +1,364 @@ +/** @file + PostCode status code definition. + + @copyright + Copyright 2011 - 2020 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __PLATFORM_STATUS_CODES_INTERNAL_H__ +#define __PLATFORM_STATUS_CODES_INTERNAL_H__ + +#include + +// +//Error Code Operations +// +// ME related error definitions +#define EFI_COMPUTING_UNIT_ME_PROCESSOR (EFI_COMPUTING_UNIT | 0= x00800000) +#define EFI_CU_ME_SELFTEST_FAIL (EFI_OEM_SPECIFIC | 0x0= 0000000) + +//Chipset:EFI_COMPUTING_UNIT_CHIPSET +#define EFI_CU_CHIPSET_EC_NVVARIABLES_CLEARED (EFI_OEM_SPECIFIC | 0x0= 0000003) +#define EFI_CU_CHIPSET_EC_NVVARIABLES_CORRUPTED (EFI_OEM_SPECIFIC | 0x0= 0000004) +#define EFI_CU_CHIPSET_SOFT_RECOVERY_MODE (EFI_OEM_SPECIFIC | 0x0= 0000009) + +// TPM related error definations +#define EFI_COMPUTING_UNIT_TPM (EFI_COMPUTING_UNIT | 0x00810000) +#define EFI_CU_TPM_NOT_DETECTED (EFI_OEM_SPECIFIC | 0x00000000) +#define EFI_CU_TPM_TIMEOUT_FAILURE (EFI_OEM_SPECIFIC | 0x00000001) +#define EFI_CU_TPM_FAIL (EFI_OEM_SPECIFIC | 0x00000002) +#define EFI_CU_TPM_FAILED_SELFTEST (EFI_OEM_SPECIFIC | 0x00000003) + +//TXT related error definations +#define EFI_COMPUTING_UNIT_TXT (EFI_COMPUTING_UNIT | 0x00820000) +#define EFI_CU_TXT_ACM_ERROR (EFI_OEM_SPECIFIC | 0x00000004) + +//Subclass of Computing Unit Class:EFI_COMPUTING_UNIT_MEMORY +#define EFI_CU_MEMORY_EC_POPU_FAIL (EFI_OEM_SPECIFIC | 0x00000000) + +//Subclass of Computing Unit Class: EFI_COMPUTING_UNIT_HOST_PROCESSOR +#define EFI_CU_DISABLE_INFO (EFI_OEM_SPECIFIC | 0x00000017) + +//Software Subclass definitions:EFI_SOFTWARE_PEI_MODULE +#define EFI_SW_PEIM_EC_NO_RECOVERY_CAPSULE (EFI_OEM_SPECIFIC | 0x00000000) + +// +//Progress Code:Start from 0x8500 for OEM use +// + +#define EFI_SW_RS_PC_VARIABLE_INIT (EFI_OEM_SPECIFIC | 0= x00000501) +#define EFI_SW_DXE_BS_SETUP_INIT (EFI_OEM_SPECIFIC | 0= x00000502) +#define EFI_SW_DXE_BS_ACPI_INIT (EFI_OEM_SPECIFIC | 0= x00000503) +#define EFI_SW_DXE_BS_CSM_INIT (EFI_OEM_SPECIFIC | 0= x00000504) +#define EFI_SW_SMM_ACPI_ENABLE (EFI_OEM_SPECIFIC | 0= x00000505) +#define EFI_SW_RS_PC_VARIABLE_RECLAIM (EFI_OEM_SPECIFIC | 0= x00000506) +#define EFI_IOB_PCI_RES_ASSIGN (EFI_OEM_SPECIFIC | 0= x00000507) +#ifndef EFI_SW_PEI_PC_S3_STARTED +#define EFI_SW_PEI_PC_S3_STARTED (EFI_OEM_SPECIFIC | 0= x00000508) +#endif +#define EFI_SW_PEI_PC_S3_VIDEO_REPOST (EFI_OEM_SPECIFIC | 0= x00000509) +#define EFI_SW_RS_PC_POST_END_CLEAR_STATUS (EFI_OEM_SPECIFIC | 0= x0000050a) +#define EFI_SW_OEM_END_OF_DXE (EFI_OEM_SPECIFIC | 0= x0000050b) + +#define BOOT_CLEAR_STATUS (EFI_SOFTWARE_EFI_RUN= TIME_SERVICE | EFI_SW_RS_PC_POST_END_CLEAR_STATUS) +#define DXE_NVRAM_INIT (EFI_SOFTWARE_EFI_RUN= TIME_SERVICE | EFI_SW_RS_PC_VARIABLE_INIT) +#define DXE_SETUP_INIT (EFI_SOFTWARE_DXE_BS_= DRIVER | EFI_SW_DXE_BS_SETUP_INIT) +#define DXE_ACPI_INIT (EFI_SOFTWARE_DXE_BS_= DRIVER | EFI_SW_DXE_BS_ACPI_INIT) +#define DXE_CSM_INIT (EFI_SOFTWARE_DXE_BS_= DRIVER | EFI_SW_DXE_BS_CSM_INIT) +#define DXE_ACPI_ENABLE (EFI_SOFTWARE_SMM_DRI= VER | EFI_SW_SMM_ACPI_ENABLE) +#define DXE_NVRAM_CLEANUP (EFI_SOFTWARE_EFI_RUN= TIME_SERVICE | EFI_SW_RS_PC_VARIABLE_RECLAIM) +#define DXE_END_OF_DXE (EFI_SOFTWARE_UNSPECI= FIED | EFI_SW_OEM_END_OF_DXE) + +#define DXE_RTC_YEAR_IS_ERROR (EFI_SOFTWARE_SYSTEM_= ERROR | EFI_SW_EC_CMOS_DATE_TIME_ERROR) + + +typedef struct{ + EFI_STATUS_CODE_VALUE Value; + UINT32 Data; +} STATUS_CODE_TO_DATA_MAP; + +// +// Enable PEI/DXE status code +// +#define PEI_STATUS_CODE 1 +#define DXE_STATUS_CODE 1 + +#define STATUS_CODE_TYPE(Type) ((Type)&EFI_STATUS_CODE_TYPE= _MASK) +#define STATUS_CODE_CLASS(Value) ((Value)&EFI_STATUS_CODE_CLA= SS_MASK) + +//Progress/Error codes +#define PEI_CORE_STARTED (EFI_SOFTWARE_PEI_CORE | EFI= _SW_PEI_CORE_PC_ENTRY_POINT) +#define PEI_RESET_NOT_AVAILABLE (EFI_SOFTWARE_PEI_CORE | EFI= _SW_PS_EC_RESET_NOT_AVAILABLE) +#define PEI_DXEIPL_NOT_FOUND (EFI_SOFTWARE_PEI_CORE | EFI= _SW_PEI_CORE_EC_DXEIPL_NOT_FOUND) +#define PEI_DXE_CORE_NOT_FOUND (EFI_SOFTWARE_PEI_CORE | EFI= _SW_PEI_CORE_EC_DXE_CORRUPT) +#define PEI_S3_RESUME_ERROR (EFI_SOFTWARE_PEI_CORE | EF= I_SW_PEI_EC_S3_RESUME_FAILED) +#define PEI_RECOVERY_FAILED (EFI_SOFTWARE_PEI_CORE | EFI= _SW_PEI_EC_RECOVERY_FAILED) +#define DXE_CORE_STARTED (EFI_SOFTWARE_DXE_CORE | EFI= _SW_DXE_CORE_PC_ENTRY_POINT) + +#define DXE_EXIT_BOOT_SERVICES_END (EFI_SOFTWARE_EFI_BOOT_SERVI= CE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES) + +// Reported by CPU PEIM +#define PEI_CAR_CPU_INIT (EFI_COMPUTING_UNIT_HOST_PRO= CESSOR | EFI_CU_HP_PC_POWER_ON_INIT) + + +// Reported by SB PEIM +#define EFI_CU_CHIPSET_PLATFORM_TYPE_INIT 0x00000001 +#define EFI_CU_CHIPSET_PLATFORM_PEIM_INIT 0x00000002 +#define PEI_PLATFORM_TYPE_INIT (EFI_COMPUTING_UNIT_CHIPSET = | EFI_CU_CHIPSET_PLATFORM_TYPE_INIT) +#define PEI_PLATFORM_PEIM_INIT (EFI_COMPUTING_UNIT_CHIPSET = | EFI_CU_CHIPSET_PLATFORM_PEIM_INIT) + +//Reported by Memory Detection PEIM +#define PEI_MEMORY_SPD_READ (EFI_COMPUTING_UNIT_MEMORY |= EFI_CU_MEMORY_PC_SPD_READ) +#define PEI_MEMORY_PRESENCE_DETECT (EFI_COMPUTING_UNIT_MEMORY |= EFI_CU_MEMORY_PC_PRESENCE_DETECT) +#define PEI_MEMORY_TIMING (EFI_COMPUTING_UNIT_MEMORY |= EFI_CU_MEMORY_PC_TIMING) +#define PEI_MEMORY_CONFIGURING (EFI_COMPUTING_UNIT_MEMORY |= EFI_CU_MEMORY_PC_CONFIGURING) +#define PEI_MEMORY_OPTIMIZING (EFI_COMPUTING_UNIT_MEMORY |= EFI_CU_MEMORY_PC_OPTIMIZING) +#define PEI_MEMORY_INIT (EFI_COMPUTING_UNIT_MEMORY |= EFI_CU_MEMORY_PC_INIT) +#define PEI_MEMORY_TEST (EFI_COMPUTING_UNIT_MEMORY |= EFI_CU_MEMORY_PC_TEST) +#define PEI_MEMORY_INVALID_TYPE (EFI_COMPUTING_UNIT_MEMORY |= EFI_CU_MEMORY_EC_INVALID_TYPE) +#define PEI_MEMORY_INVALID_SPEED (EFI_COMPUTING_UNIT_MEMORY |= EFI_CU_MEMORY_EC_INVALID_SPEED) +#define PEI_MEMORY_SPD_FAIL (EFI_COMPUTING_UNIT_MEMORY |= EFI_CU_MEMORY_EC_SPD_FAIL) +#define PEI_MEMORY_INVALID_SIZE (EFI_COMPUTING_UNIT_MEMORY |= EFI_CU_MEMORY_EC_INVALID_SIZE) +#define PEI_MEMORY_MISMATCH (EFI_COMPUTING_UNIT_MEMORY |= EFI_CU_MEMORY_EC_MISMATCH) +#define PEI_MEMORY_S3_RESUME_FAILED (EFI_COMPUTING_UNIT_MEMORY |= EFI_CU_MEMORY_EC_S3_RESUME_FAIL) +#define PEI_MEMORY_NOT_DETECTED (EFI_COMPUTING_UNIT_MEMORY |= EFI_CU_MEMORY_EC_NONE_DETECTED) +#define PEI_MEMORY_NONE_USEFUL (EFI_COMPUTING_UNIT_MEMORY |= EFI_CU_MEMORY_EC_NONE_USEFUL) +#define PEI_MEMORY_ERROR (EFI_COMPUTING_UNIT_MEMORY |= EFI_CU_EC_NON_SPECIFIC) +#define PEI_MEMORY_INSTALLED (EFI_SOFTWARE_PEI_SERVICE |= EFI_SW_PS_PC_INSTALL_PEI_MEMORY) +#define PEI_MEMORY_NOT_INSTALLED (EFI_SOFTWARE_PEI_SERVICE |= EFI_SW_PEI_CORE_EC_MEMORY_NOT_INSTALLED) +#define PEI_MEMORY_INSTALLED_TWICE (EFI_SOFTWARE_PEI_SERVICE |= EFI_SW_PS_EC_MEMORY_INSTALLED_TWICE) + +//Reported by CPU PEIM +#define PEI_CPU_INIT (EFI_COMPUTING_UNIT_HOST_PRO= CESSOR | EFI_CU_PC_INIT_BEGIN) +#define PEI_CPU_CACHE_INIT (EFI_COMPUTING_UNIT_HOST_PRO= CESSOR | EFI_CU_HP_PC_CACHE_INIT) +#define PEI_CPU_BSP_SELECT (EFI_COMPUTING_UNIT_HOST_PRO= CESSOR | EFI_CU_HP_PC_BSP_SELECT) +#define PEI_CPU_AP_INIT (EFI_COMPUTING_UNIT_HOST_PRO= CESSOR | EFI_CU_HP_PC_AP_INIT) +#define PEI_CPU_SMM_INIT (EFI_COMPUTING_UNIT_HOST_PRO= CESSOR | EFI_CU_HP_PC_SMM_INIT) +#define PEI_CPU_INVALID_TYPE (EFI_COMPUTING_UNIT_HOST_PRO= CESSOR | EFI_CU_HP_EC_INVALID_TYPE) +#define PEI_CPU_INVALID_SPEED (EFI_COMPUTING_UNIT_HOST_PRO= CESSOR | EFI_CU_HP_EC_INVALID_SPEED) +#define PEI_CPU_MISMATCH (EFI_COMPUTING_UNIT_HOST_PRO= CESSOR | EFI_CU_HP_EC_MISMATCH) +#define PEI_CPU_SELF_TEST_FAILED (EFI_COMPUTING_UNIT_HOST_PRO= CESSOR | EFI_CU_HP_EC_SELF_TEST) +#define PEI_CPU_CACHE_ERROR (EFI_COMPUTING_UNIT_HOST_PRO= CESSOR | EFI_CU_HP_EC_CACHE) +#define PEI_CPU_MICROCODE_UPDATE_FAILED (EFI_COMPUTING_UNIT_HOST_PRO= CESSOR | EFI_CU_HP_EC_MICROCODE_UPDATE) +#define PEI_CPU_NO_MICROCODE (EFI_COMPUTING_UNIT_HOST_PRO= CESSOR | EFI_CU_HP_EC_NO_MICROCODE_UPDATE) +//If non of the errors above apply use this one +#define PEI_CPU_INTERNAL_ERROR (EFI_COMPUTING_UNIT_HOST_PRO= CESSOR | EFI_CU_HP_EC_INTERNAL) +//Generic CPU error. It should only be used if non of the errors above app= ly +#define PEI_CPU_ERROR (EFI_COMPUTING_UNIT_HOST_PRO= CESSOR | EFI_CU_EC_NON_SPECIFIC) + +// Reported by NB PEIM +#define PEI_MEM_NB_INIT (EFI_COMPUTING_UNIT_CHIPSET = | EFI_CHIPSET_PC_PEI_MEM_NB_INIT) +// Reported by SB PEIM +#define PEI_MEM_SB_INIT (EFI_COMPUTING_UNIT_CHIPSET = | EFI_CHIPSET_PC_PEI_MEM_SB_INIT) + +//Reported by PEIM which detected forced or auto recovery condition +#define PEI_RECOVERY_AUTO (EFI_SOFTWARE_PEI_MODULE | E= FI_SW_PEI_PC_RECOVERY_AUTO) +#define PEI_RECOVERY_USER (EFI_SOFTWARE_PEI_MODULE | E= FI_SW_PEI_PC_RECOVERY_USER) + +//Reported by DXE IPL +#define PEI_RECOVERY_PPI_NOT_FOUND (EFI_SOFTWARE_PEI_MODULE | E= FI_SW_PEI_EC_RECOVERY_PPI_NOT_FOUND) +#define PEI_S3_RESUME_PPI_NOT_FOUND (EFI_SOFTWARE_PEI_MODULE | E= FI_SW_PEI_EC_S3_RESUME_PPI_NOT_FOUND) +#define PEI_S3_RESUME_FAILED (EFI_SOFTWARE_PEI_MODULE | E= FI_SW_PEI_EC_S3_RESUME_FAILED) + +//Reported by Recovery PEIM +#define PEI_RECOVERY_STARTED (EFI_SOFTWARE_PEI_MODULE | E= FI_SW_PEI_PC_RECOVERY_BEGIN) +#define PEI_RECOVERY_CAPSULE_FOUND (EFI_SOFTWARE_PEI_MODULE | E= FI_SW_PEI_PC_CAPSULE_LOAD) +#define PEI_RECOVERY_NO_CAPSULE (EFI_SOFTWARE_PEI_MODULE | E= FI_SW_PEI_EC_NO_RECOVERY_CAPSULE) +#define PEI_RECOVERY_CAPSULE_LOADED (EFI_SOFTWARE_PEI_MODULE | E= FI_SW_PEI_PC_CAPSULE_START) +#define PEI_RECOVERY_INVALID_CAPSULE (EFI_SOFTWARE_PEI_MODULE | E= FI_SW_PEI_EC_INVALID_CAPSULE_DESCRIPTOR) + +//Reported by S3 Resume PEIM +#define PEI_S3_BOOT_SCRIPT (EFI_SOFTWARE_PEI_MODULE | E= FI_SW_PEI_PC_S3_BOOT_SCRIPT) +#define PEI_S3_OS_WAKE (EFI_SOFTWARE_PEI_MODULE | E= FI_SW_PEI_PC_OS_WAKE) +#define PEI_S3_BOOT_SCRIPT_ERROR (EFI_SOFTWARE_PEI_MODULE | E= FI_SW_PEI_EC_S3_BOOT_SCRIPT_ERROR) +#define PEI_S3_OS_WAKE_ERROR (EFI_SOFTWARE_PEI_MODULE | E= FI_SW_PEI_EC_S3_OS_WAKE_ERROR) +#define PEI_S3_STARTED (EFI_SOFTWARE_PEI_MODULE | E= FI_SW_PEI_PC_S3_STARTED) +#define PEI_S3_VIDEO_REPOST (EFI_SOFTWARE_PEI_MODULE | E= FI_SW_PEI_PC_S3_VIDEO_REPOST) + + +#define PEI_PEIM_STARTED (EFI_SOFTWARE_PEI_CORE | EFI= _SW_PC_INIT_BEGIN) +#define PEI_PEIM_ENDED (EFI_SOFTWARE_PEI_CORE | EFI= _SW_PC_INIT_END) + +//Reported by DXE IPL +#define PEI_DXE_IPL_STARTED (EFI_SOFTWARE_PEI_CORE | EFI= _SW_PEI_CORE_PC_HANDOFF_TO_NEXT) + +//Reported by PEIM which installs Reset PPI +#define PEI_RESET_SYSTEM (EFI_SOFTWARE_PEI_SERVICE | = EFI_SW_PS_PC_RESET_SYSTEM) + +//Reported by the PEIM or DXE driver which detected the error +#define GENERIC_MEMORY_CORRECTABLE_ERROR (EFI_COMPUTING_UNIT_MEMORY |= EFI_CU_MEMORY_EC_CORRECTABLE) +#define GENERIC_MEMORY_UNCORRECTABLE_ERROR (EFI_COMPUTING_UNIT_MEMORY |= EFI_CU_MEMORY_EC_UNCORRECTABLE) + +//Reported by Flash Update DXE driver +#define DXE_FLASH_UPDATE_FAILED (EFI_COMPUTING_UNIT_MEMORY |= EFI_CU_MEMORY_EC_UPDATE_FAIL) + +//Reported by the PEIM or DXE driver which detected the error +#define GENERIC_CPU_THERMAL_ERROR (EFI_COMPUTING_UNIT_HOST_PRO= CESSOR | EFI_CU_HP_EC_THERMAL) +#define GENERIC_CPU_LOW_VOLTAGE (EFI_COMPUTING_UNIT_HOST_PRO= CESSOR | EFI_CU_HP_EC_LOW_VOLTAGE) +#define GENERIC_CPU_HIGH_VOLTAGE (EFI_COMPUTING_UNIT_HOST_PRO= CESSOR | EFI_CU_HP_EC_HIGH_VOLTAGE) +#define GENERIC_CPU_CORRECTABLE_ERROR (EFI_COMPUTING_UNIT_HOST_PRO= CESSOR | EFI_CU_HP_EC_CORRECTABLE) +#define GENERIC_CPU_UNCORRECTABLE_ERROR (EFI_COMPUTING_UNIT_HOST_PRO= CESSOR | EFI_CU_HP_EC_UNCORRECTABLE) +#define GENERIC_BAD_DATE_TIME_ERROR (EFI_SOFTWARE_UNSPECIFIED | = EFI_SW_EC_BAD_DATE_TIME) +#define GENERIC_MEMORY_SIZE_DECREASE (EFI_COMPUTING_UNIT_MEMORY |= EFI_CU_MEMORY_EC_MISMATCH) + +//Reported by DXE Core +#define DXE_DRIVER_STARTED (EFI_SOFTWARE_EFI_DXE_SERVIC= E | EFI_SW_PC_INIT_BEGIN) +#define DXE_DRIVER_ENED (EFI_SOFTWARE_DXE_CORE | EFI= _SW_PC_INIT_END) +#define DXE_ARCH_PROTOCOLS_AVAILABLE (EFI_SOFTWARE_DXE_CORE | EFI= _SW_DXE_CORE_PC_ARCH_READY) +#define DXE_DRIVER_CONNECTED (EFI_SOFTWARE_DXE_CORE | EFI= _SW_DXE_CORE_PC_START_DRIVER) +#define DXE_ARCH_PROTOCOL_NOT_AVAILABLE (EFI_SOFTWARE_DXE_CORE | EFI= _SW_DXE_CORE_EC_NO_ARCH) + +//Reported by DXE CPU driver +#define DXE_CPU_SELF_TEST_FAILED (EFI_COMPUTING_UNIT_HOST_PRO= CESSOR | EFI_CU_HP_EC_SELF_TEST) + +//Reported by PCI Host Bridge driver +#define DXE_NB_HB_INIT (EFI_COMPUTING_UNIT_CHIPSET = | EFI_CHIPSET_PC_DXE_HB_INIT ) + +// Reported by NB Driver +#define DXE_NB_INIT (EFI_COMPUTING_UNIT_CHIPSET = | EFI_CHIPSET_PC_DXE_NB_INIT ) +#define DXE_NB_SMM_INIT (EFI_COMPUTING_UNIT_CHIPSET = | EFI_CHIPSET_PC_DXE_NB_SMM_INIT ) +#define DXE_NB_ERROR (EFI_COMPUTING_UNIT_CHIPSET = | EFI_CHIPSET_EC_DXE_NB_ERROR ) + +// Reported by SB Driver(s) +#define DXE_SBRUN_INIT (EFI_COMPUTING_UNIT_CHIPSET = | EFI_CHIPSET_PC_DXE_SB_RT_INIT ) +#define DXE_SB_INIT (EFI_COMPUTING_UNIT_CHIPSET = | EFI_CHIPSET_PC_DXE_SB_INIT ) +#define DXE_SB_SMM_INIT (EFI_COMPUTING_UNIT_CHIPSET = | EFI_CHIPSET_PC_DXE_SB_SMM_INIT ) +#define DXE_SB_DEVICES_INIT (EFI_COMPUTING_UNIT_CHIPSET = | EFI_CHIPSET_PC_DXE_SB_DEVICES_INIT ) +#define DXE_SB_BAD_BATTERY (EFI_COMPUTING_UNIT_CHIPSET = | EFI_CHIPSET_EC_BAD_BATTERY) +#define DXE_SB_ERROR (EFI_COMPUTING_UNIT_CHIPSET = | EFI_CHIPSET_EC_DXE_SB_ERROR ) + +#define EFI_SW_DXE_BS_PC_ACPI_INIT 0x00000005 +#ifndef EFI_SW_DXE_BS_PC_CSM_INIT +#define EFI_SW_DXE_BS_PC_CSM_INIT 0x00000006 +#endif + +//Reported by DXE Core +#define DXE_BDS_STARTED (EFI_SOFTWARE_DXE_CORE | EFI= _SW_DXE_CORE_PC_HANDOFF_TO_NEXT) + +//Reported by BDS +#define DXE_BDS_CONNECT_DRIVERS (EFI_SOFTWARE_DXE_BS_DRIVER = | EFI_SW_DXE_BS_PC_BEGIN_CONNECTING_DRIVERS) + +//Reported by Boot Manager +#define DXE_READY_TO_BOOT (EFI_SOFTWARE_DXE_BS_DRIVER = | EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT) + +//Reported by DXE Core +#define DXE_EXIT_BOOT_SERVICES (EFI_SOFTWARE_EFI_BOOT_SERVI= CE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES) +#define DXE_EXIT_BOOT_SERVICES_EVENT (EFI_SOFTWARE_DXE_BS_DRIVER = | EFI_SW_DXE_BS_PC_EXIT_BOOT_SERVICES_EVENT) + +//Reported by driver that installs Runtime AP +#define RT_SET_VIRTUAL_ADDRESS_MAP_BEGIN (EFI_SOFTWARE_EFI_RUNTIME_SE= RVICE | EFI_SW_RS_PC_SET_VIRTUAL_ADDRESS_MAP) +#define RT_SET_VIRTUAL_ADDRESS_MAP_END (EFI_SOFTWARE_DXE_BS_DRIVER = | EFI_SW_DXE_BS_PC_VIRTUAL_ADDRESS_CHANGE_EVENT) + +//Reported by CSM +#define DXE_LEGACY_OPROM_INIT (EFI_SOFTWARE_DXE_BS_DRIVER = | EFI_SW_DXE_BS_PC_LEGACY_OPROM_INIT) +#define DXE_LEGACY_BOOT (EFI_SOFTWARE_DXE_BS_DRIVER = | EFI_SW_DXE_BS_PC_LEGACY_BOOT_EVENT) +#define DXE_LEGACY_OPROM_NO_SPACE (EFI_SOFTWARE_DXE_BS_DRIVER = | EFI_SW_DXE_BS_EC_LEGACY_OPROM_NO_SPACE) + +//Reported by SETUP +#define DXE_SETUP_START (EFI_SOFTWARE_DXE_BS_DRIVER = | EFI_SW_PC_USER_SETUP) +#define DXE_SETUP_INPUT_WAIT (EFI_SOFTWARE_DXE_BS_DRIVER = | EFI_SW_PC_INPUT_WAIT) +#define DXE_INVALID_PASSWORD (EFI_SOFTWARE_DXE_BS_DRIVER = | EFI_SW_DXE_BS_EC_INVALID_PASSWORD) +#define DXE_INVALID_IDE_PASSWORD (EFI_SOFTWARE_DXE_BS_DRIVER = | EFI_SW_DXE_BS_EC_INVALID_IDE_PASSWORD) +#define DXE_BOOT_OPTION_LOAD_ERROR (EFI_SOFTWARE_DXE_BS_DRIVER = | EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR) +#define DXE_BOOT_OPTION_FAILED (EFI_SOFTWARE_DXE_BS_DRIVER = | EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED) + +//Reported by a Driver that installs Reset AP +#define DXE_RESET_SYSTEM (EFI_SOFTWARE_EFI_RUNTIME_SE= RVICE | EFI_SW_RS_PC_RESET_SYSTEM) +#define DXE_RESET_NOT_AVAILABLE (EFI_SOFTWARE_EFI_RUNTIME_SE= RVICE | EFI_SW_PS_EC_RESET_NOT_AVAILABLE) + +// Reported by PCI bus driver +#define DXE_PCI_BUS_BEGIN (EFI_IO_BUS_PCI | EFI_IOB_PC= _INIT) +#define DXE_PCI_BUS_ENUM (EFI_IO_BUS_PCI | EFI_IOB_PC= I_BUS_ENUM) +#define DXE_PCI_BUS_HPC_INIT (EFI_IO_BUS_PCI | EFI_IOB_PC= I_HPC_INIT) +#define DXE_PCI_BUS_REQUEST_RESOURCES (EFI_IO_BUS_PCI | EFI_IOB_PC= I_RES_ALLOC) +#define DXE_PCI_BUS_ASSIGN_RESOURCES (EFI_IO_BUS_PCI | EFI_IOB_PC= _ENABLE) +#define DXE_PCI_BUS_HOTPLUG (EFI_IO_BUS_PCI | EFI_IOB_PC= _HOTPLUG) +#define DXE_PCI_BUS_OUT_OF_RESOURCES (EFI_IO_BUS_PCI | EFI_IOB_EC= _RESOURCE_CONFLICT) + +// Reported by USB bus driver +#define DXE_USB_BEGIN (EFI_IO_BUS_USB | EFI_IOB_PC= _INIT) +#define DXE_USB_RESET (EFI_IO_BUS_USB | EFI_IOB_PC= _RESET) +#define DXE_USB_DETECT (EFI_IO_BUS_USB | EFI_IOB_PC= _DETECT) +#define DXE_USB_ENABLE (EFI_IO_BUS_USB | EFI_IOB_PC= _ENABLE) +#define DXE_USB_HOTPLUG (EFI_IO_BUS_USB | EFI_IOB_PC= _HOTPLUG) + +//Reported by IDE bus driver +#define DXE_IDE_BEGIN (EFI_IO_BUS_ATA_ATAPI | EFI_= IOB_PC_INIT) +#define DXE_IDE_RESET (EFI_IO_BUS_ATA_ATAPI | EFI_= IOB_PC_RESET) +#define DXE_IDE_DETECT (EFI_IO_BUS_ATA_ATAPI | EFI_= IOB_PC_DETECT) +#define DXE_IDE_ENABLE (EFI_IO_BUS_ATA_ATAPI | EFI_= IOB_PC_ENABLE) +#define DXE_IDE_SMART_ERROR (EFI_IO_BUS_ATA_ATAPI | EFI_= IOB_ATA_BUS_SMART_OVERTHRESHOLD) +#define DXE_IDE_CONTROLLER_ERROR (EFI_IO_BUS_ATA_ATAPI | EFI_= IOB_EC_CONTROLLER_ERROR) +#define DXE_IDE_DEVICE_FAILURE (EFI_IO_BUS_ATA_ATAPI | EFI_= IOB_EC_INTERFACE_ERROR) + +// Reported by SCSI bus driver +#define DXE_SCSI_BEGIN (EFI_IO_BUS_SCSI | EFI_IOB_P= C_INIT) +#define DXE_SCSI_RESET (EFI_IO_BUS_SCSI | EFI_IOB_P= C_RESET) +#define DXE_SCSI_DETECT (EFI_IO_BUS_SCSI | EFI_IOB_P= C_DETECT) +#define DXE_SCSI_ENABLE (EFI_IO_BUS_SCSI | EFI_IOB_P= C_ENABLE) + +// Reported by Super I/O driver +#define DXE_SIO_INIT (EFI_IO_BUS_LPC | EFI_IOB_PC= _INIT) + +// Reported by Keyboard driver +#define DXE_KEYBOARD_INIT (EFI_PERIPHERAL_KEYBOARD | E= FI_P_PC_INIT) +#define DXE_KEYBOARD_RESET (EFI_PERIPHERAL_KEYBOARD | E= FI_P_PC_RESET) +#define DXE_KEYBOARD_DISABLE (EFI_PERIPHERAL_KEYBOARD | E= FI_P_PC_DISABLE) +#define DXE_KEYBOARD_DETECT (EFI_PERIPHERAL_KEYBOARD | E= FI_P_PC_PRESENCE_DETECT) +#define DXE_KEYBOARD_ENABLE (EFI_PERIPHERAL_KEYBOARD | E= FI_P_PC_ENABLE) +#define DXE_KEYBOARD_CLEAR_BUFFER (EFI_PERIPHERAL_KEYBOARD | E= FI_P_KEYBOARD_PC_CLEAR_BUFFER) +#define DXE_KEYBOARD_SELF_TEST (EFI_PERIPHERAL_KEYBOARD | E= FI_P_KEYBOARD_PC_SELF_TEST) + +// Reported by Mouse driver +#define DXE_MOUSE_INIT (EFI_PERIPHERAL_MOUSE | EFI_= P_PC_INIT) +#define DXE_MOUSE_RESET (EFI_PERIPHERAL_MOUSE | EFI_= P_PC_RESET) +#define DXE_MOUSE_DISABLE (EFI_PERIPHERAL_MOUSE | EFI_= P_PC_DISABLE) +#define DXE_MOUSE_DETECT (EFI_PERIPHERAL_MOUSE | EFI_= P_PC_PRESENCE_DETECT) +#define DXE_MOUSE_ENABLE (EFI_PERIPHERAL_MOUSE | EFI_= P_PC_ENABLE) + +// Reported by Mass Storage drivers +#define DXE_FIXED_MEDIA_INIT (EFI_PERIPHERAL_FIXED_MEDIA = | EFI_P_PC_INIT) +#define DXE_FIXED_MEDIA_RESET (EFI_PERIPHERAL_FIXED_MEDIA = | EFI_P_PC_RESET) +#define DXE_FIXED_MEDIA_DISABLE (EFI_PERIPHERAL_FIXED_MEDIA = | EFI_P_PC_DISABLE) +#define DXE_FIXED_MEDIA_DETECT (EFI_PERIPHERAL_FIXED_MEDIA = | EFI_P_PC_PRESENCE_DETECT) +#define DXE_FIXED_MEDIA_ENABLE (EFI_PERIPHERAL_FIXED_MEDIA = | EFI_P_PC_ENABLE) +#define DXE_REMOVABLE_MEDIA_INIT (EFI_PERIPHERAL_REMOVABLE_ME= DIA | EFI_P_PC_INIT) +#define DXE_REMOVABLE_MEDIA_RESET (EFI_PERIPHERAL_REMOVABLE_ME= DIA | EFI_P_PC_RESET) +#define DXE_REMOVABLE_MEDIA_DISABLE (EFI_PERIPHERAL_REMOVABLE_ME= DIA | EFI_P_PC_DISABLE) +#define DXE_REMOVABLE_MEDIA_DETECT (EFI_PERIPHERAL_REMOVABLE_ME= DIA | EFI_P_PC_PRESENCE_DETECT) +#define DXE_REMOVABLE_MEDIA_ENABLE (EFI_PERIPHERAL_REMOVABLE_ME= DIA | EFI_P_PC_ENABLE) +#define DXE_REMOVABLE_MEDIA_DETECTED (EFI_PERIPHERAL_REMOVABLE_ME= DIA | EFI_P_PC_DETECTED) +#define DXE_REMOVABLE_MEDIA_DISABLED (EFI_PERIPHERAL_REMOVABLE_ME= DIA | EFI_P_EC_DISABLED) +// +// Reset/Sleep conditions specific to CRK that map to a port80 code. +// +#define CRK_DXE_RESET 8 // Action qualifier. (bi= ts 2:0) of error code =3D=3D PCH_RESET_TYPE when sleep =3D=3D 1. +// +// Progress code reflects a legitimate HW forced transition to S5 via GPIO= activated PWRBTN. +#define PWRBTN_SHUTDOWN (EFI_SOFTWARE_SMM_DRIVER | E= FI_SUBCLASS_SPECIFIC | 7) + +// If sleep bit and progress type: ProgressCode(2:0) =3D=3D 7 and represen= t legitimate SW request for S5 transition. +// If sleep bit and error type: ProgressCode(2:0) =3D=3D state of the f= ield represented by the sleep request prior to mapping to S5. +#define SLEEP_SHUTDOWN (EFI_SOFTWARE_SMM_DRIVER | E= FI_OEM_SPECIFIC | 7) + +// If sleep bit and error type: ProgressCode(2:0) =3D=3D PCH_RESET_TYPE= request forced to transition to S5. +#define DXE_RESET_ERROR (EFI_SOFTWARE_DXE_RT_DRIVER = | EFI_OEM_SPECIFIC | CRK_DXE_RESET) + +// Reported by BDS +#define DXE_CON_OUT_CONNECT (EFI_PERIPHERAL_LOCAL_CONSOL= E | EFI_P_PC_INIT) +#define DXE_CON_IN_CONNECT (EFI_PERIPHERAL_KEYBOARD | E= FI_P_PC_INIT) +#define DXE_NO_CON_OUT (EFI_PERIPHERAL_LOCAL_CONSOL= E | EFI_P_EC_NOT_DETECTED) +#define DXE_NO_CON_IN (EFI_PERIPHERAL_KEYBOARD | E= FI_P_EC_NOT_DETECTED) + +#define DXE_CMOS_CLR_REQUEST (EFI_SOFTWARE_AL | EFI_SW_EC= _CFG_CLR_REQUEST) +#define DXE_WATCHDOG_TIMER_EXPIRED (EFI_COMPUTING_UNIT_HOST_PRO= CESSOR | EFI_CU_HP_EC_TIMER_EXPIRED) + +#define EFI_IOB_PCI_EXP_VGA_ILLEAGL (EFI_SUBCLASS_SPECIFIC | 0x0= 0000005) + +#define EFI_CU_QPI_ERROR (EFI_OEM_SPECIFIC | 0x000000= 05) +#define EFI_CU_QPI_LINK_DOWN (EFI_COMPUTING_UNIT | 0x000A= 0000) + + +#endif diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaFpkConfi= gLib.h b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaFpkConfigLib= .h new file mode 100644 index 0000000000..bdd42b2d69 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaFpkConfigLib.h @@ -0,0 +1,55 @@ +/** @file + UBA FPK configuration library header + + @copyright + Copyright 2016 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _UBA_FPK_CONFIG_LIB_H +#define _UBA_FPK_CONFIG_LIB_H + +#include +#include +#include + +#define PLATFORM_FPK_CONFIG_SIGNATURE SIGNATURE_32 ('P', 'F', 'P', 'K') +#define PLATFORM_FPK_CONFIG_VERSION 01 + +// {38F0930C-E7FB-49CC-B88E-D9909EB65D77} +#define PLATFORM_FPK_CONFIG_DATA_GUID \ +{ 0x38f0930c, 0xe7fb, 0x49cc, { 0xb8, 0x8e, 0xd9, 0x90, 0x9e, 0xb6, 0x5d, = 0x77 } } + +typedef enum { + PortMappedToFunc0, + PortMappedToFunc1, + PortMappedToFunc2, + PortMappedToFunc3, + PortNotMapped +} PLATFORM_FPK_PORT_MAP; + +typedef struct _PLATFORM_FPK_CONFIG_STRUCT { + UINT32 Signature; + UINT32 Version; + PLATFORM_FPK_PORT_MAP *PortToFuncMapPtr; + UINTN PortToFuncMapSize; + GPIO_PAD PciDisNGpioPad; + GPIO_PAD LanDisNGpioPad; +} PLATFORM_FPK_CONFIG_STRUCT; + +/** + Retrieves FPK config struct from UBA database + + @retval EFI_SUCCESS Config struct is retrieved. + @retval EFI_NOT_FOUND UBA protocol, platform or data not found. + @retval EFI_INVALID_PARAMETER If PlatformFpkConfigStruct is NULL. +**/ +EFI_STATUS +FpkConfigGetConfigStruct ( + OUT PLATFORM_FPK_CONFIG_STRUCT *PlatformFpkConfigStruct + ); + +STATIC EFI_GUID gPlatformFpkConfigDataGuid =3D PLATFORM_FPK_CONFIG_DATA_GU= ID; + +#endif // !_UBA_FPK_CONFIG_LIB_H diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaSmbiosUp= dateLib.h b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaSmbiosUpd= ateLib.h new file mode 100644 index 0000000000..9ea87b62df --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/UbaSmbiosUpdateLib= .h @@ -0,0 +1,275 @@ +/** @file + UBA smbios Update Library Header File. + + @copyright + Copyright 2012 - 2015 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _UBA_SMBIOS_UPDATE_LIB_ +#define _UBA_SMBIOS_UPDATE_LIB_ + +#include +#include +#include + + +typedef enum +{ + SmbiosDelayUpdate, + SmbiosNormalUpdate, +} SmbiosUpdateType; + + +#define PLATFORM_SMBIOS_UPDATE_SIGNATURE SIGNATURE_32 ('P', 'S', 'M', 'B') +#define PLATFORM_SMBIOS_UPDATE_VERSION 01 + +// {AAC6CAFD-42C6-440a-B958-9FD4C84B50EA} +STATIC EFI_GUID gPlatformSmbiosConfigDataGuid =3D +{ 0xaac6cafd, 0x42c6, 0x440a, { 0xb9, 0x58, 0x9f, 0xd4, 0xc8, 0x4b, 0x50, = 0xea } }; + + +/** + Callback function for SMBIOS dynamic update. + + @param Smbios The SMBIOS data buffer pointer. + @param BufferSize The SMBIOS data buffer size allocated fo= r you. + @param Instance Instance number for this type. + + @retval EFI_INVALID_PARAMETER Check your register data if the call ret= urn this error. + @retval EFI_NOT_FOUND The data process have error occur. + @retval EFI_SUCCESS Data have been updated successfully. + +**/ +typedef +EFI_STATUS +(*SMBIOS_UPDATE_CALLBACK) ( + VOID +); + +typedef struct { + UINT32 Signature; + UINT32 Version; + + UINT32 PlatformType; + SmbiosUpdateType UpdateType; // DelayUpdate or NormalUpdate + SMBIOS_UPDATE_CALLBACK CallUpdate; +} SMBIOS_UPDATE_DATA; + +/** + Provide the RegData and register a callback for dynamic update SMBIOS da= ta. + + @param RegData Callback register data. + + @retval EFI_NOT_FOUND Data log protocol not found. + @retval EFI_OUT_OF_RESOURCES Data was not logged due to lack of syste= m resources. + @retval EFI_SUCCESS Data have been updated successfully. + +**/ +EFI_STATUS +PlatformRegisterSmbiosUpdate ( + IN SMBIOS_UPDATE_DATA *RegData +); + +/** + Update a String for a filled SMBIOS data structure, the structure must b= e filled + before update string. + This function update a string indicated by StringNumber to the tail of S= MBIOS + structure. + + @param Smbios SMBIOS structure data buffer pointer. + @param BufferSize SMBIOS structure data buffer size. + @param StringNumber The string index number of SMBIOS struct= ure. + @param String String want to update. + + @retval EFI_OUT_OF_RESOURCES No enough memory for this action. + @retval EFI_SUCCESS String updated successfully. + +**/ +EFI_STATUS +PlatformSmbiosUpdateString ( + IN OUT SMBIOS_STRUCTURE_POINTER Smbios, + IN UINTN BufferSize, + IN UINTN StringNumber, + IN CHAR16 *String +); + +/** + Get SMBIOS data structure length, include the string in tail. + + @param Smbios SMBIOS structure data buffer pointer. + @param TypeSize SMBIOS structure size. + + @retval EFI_INVALID_PARAMETER Input paramter invalid. + @retval EFI_SUCCESS Caculate data structure size successfull= y. + +**/ +EFI_STATUS +PlatformSmbiosGetTypeLength ( + IN OUT SMBIOS_STRUCTURE_POINTER Smbios, + IN OUT UINTN *TypeSize +); + +/** + Add a new SMBIOS structure into SMBIOS database. + + @param Smbios SMBIOS structure data buffer pointer. + + @retval EFI_NOT_FOUND SMBIOS protocol not installed. + @retval EFI_SUCCESS Add data structure successfully. + +**/ +EFI_STATUS +PlatformSmbiosAddNew ( + IN SMBIOS_STRUCTURE_POINTER SmbiosPtr +); + +/** + Get the number of instance of SMBIOS type structure in SMBIOS database. + return 0 means no instance for this type now. + + @param Type SMBIOS type. + + @retval Count Number of instance. + +**/ +UINTN +PlatformSmbiosGetInstanceCount ( + IN UINT8 Type +); + +/** + Get SMBIOS type data structure in SMBIOS database. + + This function give you a pointer of SMBIOS structure directly in the dat= abase, you can update + the value in formated structure area and it's take affect immediately, b= ut never directly or + call PlatformSmbiosUpdateString to edit the string in this buffer, + use PlatformSmbiosGetEditCopy->PlatformSmbiosUpdateType instead. + + One of the SmbiosPtr or Handle must be valid value. + + @param Type SMBIOS type. + @param Instance The instance of this type. + @param SmbiosPtr Optional parameter, on input, pass a poi= nter of SMBIOS_STRUCTURE_POINTER + to this function. + On output, return the SMBIOS data pointe= r in SmbiosPtr. + @param Handle Optional parameter, on input, pass a poi= nter of Handle. + On output, return the SMBIOS data handle= value + + @retval EFI_INVALID_PARAMETER Both the SmbiosPtr and Handle is NULL. + @retval EFI_NOT_FOUND SMBIOS protocol not installed. + @retval EFI_SUCCESS Get structure data successfully. + +**/ +EFI_STATUS +PlatformSmbiosGetInstance ( + IN UINT8 Type, + IN UINTN Instance, + IN OUT SMBIOS_STRUCTURE_POINTER *SmbiosPtr, + IN OUT UINT16 *Handle +); + +/** + Get a copy of SMBIOS type structure data in SMBIOS database. + Must allocate memory large enough first, then call this function to get = the copy. + + @param Type SMBIOS type. + @param Instance The instance of this type. + @param SmbiosPtr A valid buffer pointer which SMBIOS data= will copy to this buffer. + + @retval EFI_NOT_FOUND SMBIOS protocol not installed. + @retval EFI_SUCCESS Get structure data successfully. + +**/ +EFI_STATUS +PlatformSmbiosGetEditCopy ( + IN UINT8 Type, + IN UINTN Instance, + IN OUT SMBIOS_STRUCTURE_POINTER SmbiosPtr +); + +/** + Update a string which in SMBIOS database. + The data structure which string belong to must installed before. + + @param Type SMBIOS type. + @param Instance The instance of this type. + @param StringNumber The string number. + @param String The string want to update. + + @retval EFI_NOT_FOUND SMBIOS protocol not installed. + @retval EFI_SUCCESS Update data successfully. + +**/ +EFI_STATUS +PlatformSmbiosUpdateInstalledString ( + IN UINT8 Type, + IN UINTN Instance, + IN UINTN StringNumber, + IN CHAR16 *String +); + +/** + Remove a SMBIOS instance in SMBIOS database. + + @param Type SMBIOS type. + @param Instance The instance of this type. + + @retval EFI_NOT_FOUND SMBIOS protocol not installed. + @retval EFI_SUCCESS Remove data successfully. + +**/ +EFI_STATUS +PlatformSmbiosRemoveType ( + IN UINT8 Type, + IN UINTN Instance +); + +/** + Remove all the instance of specific SMBIOS type in SMBIOS database. + + @param Type SMBIOS type. + + @retval EFI_NOT_FOUND SMBIOS protocol not installed. + @retval EFI_SUCCESS Remove data successfully. + +**/ +EFI_STATUS +PlatformSmbiosRemoveAll ( + IN UINT8 Type +); + +/** + Update SMBIOS data structure in database with new structure data. + + @param Type SMBIOS type. + @param Instance The instance of this type. + @param SmbiosPtr A valid buffer pointer which new SMBIOS = data stored. + + @retval EFI_NOT_FOUND SMBIOS protocol not installed. + @retval EFI_SUCCESS Update data successfully. + +**/ +EFI_STATUS +PlatformSmbiosUpdateType ( + IN UINT8 Type, + IN UINTN Instance, + IN SMBIOS_STRUCTURE_POINTER SmbiosPtr +); + +/** + Function provide to DXE driver, which initial the dynamic update. + + @param NULL + + @retval EFI_NOT_FOUND Required protocol not found. + @retval EFI_SUCCESS Init successfully. + +**/ +EFI_STATUS +PlatformInitSmbiosUpdate ( + VOID +); + +#endif //_UBA_SMBIOS_UPDATE_LIB_ diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/BoardInitLib/BoardI= nitDxeLib.inf b/Platform/Intel/WhitleyOpenBoardPkg/Library/BoardInitLib/Boa= rdInitDxeLib.inf index 219512566c..57ec872e33 100644 --- a/Platform/Intel/WhitleyOpenBoardPkg/Library/BoardInitLib/BoardInitDxeL= ib.inf +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/BoardInitLib/BoardInitDxeL= ib.inf @@ -27,6 +27,7 @@ WhitleySiliconPkg/SiliconPkg.dec WhitleySiliconPkg/CpRcPkg.dec WhitleyOpenBoardPkg/PlatformPkg.dec + UefiCpuPkg/UefiCpuPkg.dec =20 [LibraryClasses] IoLib --=20 2.27.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#87426): https://edk2.groups.io/g/devel/message/87426 Mute This Topic: https://groups.io/mt/89698848/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat May 18 21:45:23 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+87425+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+87425+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1646952111994156.6534581024298; Thu, 10 Mar 2022 14:41:51 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id aEYlYY1788612xalbAcS9rvR; Thu, 10 Mar 2022 14:41:52 -0800 X-Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mx.groups.io with SMTP id smtpd.web08.849.1646952110863190430 for ; Thu, 10 Mar 2022 14:41:51 -0800 X-IronPort-AV: E=McAfee;i="6200,9189,10282"; a="316121248" X-IronPort-AV: E=Sophos;i="5.90,171,1643702400"; d="scan'208";a="316121248" X-Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2022 14:41:34 -0800 X-IronPort-AV: E=Sophos;i="5.90,171,1643702400"; d="scan'208";a="644643360" X-Received: from iworam-desk.amr.corp.intel.com ([10.7.150.60]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2022 14:41:34 -0800 From: "Oram, Isaac W" To: devel@edk2.groups.io Cc: Nate DeSimone , Chasel Chiu Subject: [edk2-devel][edk2-platforms][PATCH V1 2/9] WhitleySiliconPkg: Add definitions used in ACPI subsystem Date: Thu, 10 Mar 2022 14:41:07 -0800 Message-Id: <3f91b423e4adbf82843d7a6266ab8fb4e665fe4a.1646951441.git.isaac.w.oram@intel.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,isaac.w.oram@intel.com X-Gm-Message-State: VNdtA7AmMu7UJokPljzDSYXHx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1646952112; bh=OjmFVeTzjsby6ennzrOz2iBnPbuXc29E3NOrAi4x3bs=; h=Cc:Date:From:Reply-To:Subject:To; b=BVzgY5UYETSkR/PtW7kCiDhCdQ3ecmw3bninYGjiyGiUqUuM+oRNAI0kdxyb8Y1ETVd rGL7e16GX/ylfb2VHyUpgnFWg5fauEiV6HzrqTeEYgNaByjDyAHoL0d7VfVa706+FKsom P6otD2FMNxCwjufyZuyAP50P/QDBJbqEFAo= X-ZohoMail-DKIM: fail (Signature date is -1 seconds in the future.) X-ZM-MESSAGEID: 1646952113545100001 Content-Type: text/plain; charset="utf-8" Needed to convert FvLateOpenBoard ACPI binary drivers to open source. Cc: Nate DeSimone Cc: Chasel Chiu Signed-off-by: Isaac Oram Reviewed-by: Nate DeSimone --- Silicon/Intel/WhitleySiliconPkg/CpRcPkg.dec = | 3 + Silicon/Intel/WhitleySiliconPkg/Cpu/Include/CpuDataStruct.h = | 7 + Silicon/Intel/WhitleySiliconPkg/Cpu/Include/Library/CpuConfigLib.h = | 82 ++++ Silicon/Intel/WhitleySiliconPkg/Include/BackCompatible.h = | 3 + Silicon/Intel/WhitleySiliconPkg/Include/BdatSchema.h = | 301 ++++++++++++ Silicon/Intel/WhitleySiliconPkg/Include/Guid/MemoryMapData.h = | 2 + Silicon/Intel/WhitleySiliconPkg/Include/IioRegs.h = | 74 ++- Silicon/Intel/WhitleySiliconPkg/Include/Library/EnhancedWarningLogLib.h = | 494 ++++++++++++++++++++ Silicon/Intel/WhitleySiliconPkg/Include/Library/SpdAccessLib.h = | 32 ++ Silicon/Intel/WhitleySiliconPkg/Include/MemCommon.h = | 7 + Silicon/Intel/WhitleySiliconPkg/Include/Platform.h = | 7 + Silicon/Intel/WhitleySiliconPkg/Include/Ppi/MemoryPolicyPpi.h = | 2 +- Silicon/Intel/WhitleySiliconPkg/Include/Protocol/AcpiPlatformProtocol.h = | 51 ++ Silicon/Intel/WhitleySiliconPkg/Include/Protocol/CpuCsrAccess.h = | 254 ++++++++++ Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibraryProtocol.= h | 43 +- Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibraryProtocol2= .h | 255 ++++++++++ Silicon/Intel/WhitleySiliconPkg/Include/Protocol/NfitTableUpdateProtocol.h= | 27 ++ Silicon/Intel/WhitleySiliconPkg/Include/Protocol/SmbiosMemInfo.h = | 87 ++++ Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/Mem= Regs.h | 2 + Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/Mrc= CommonTypes.h | 25 + Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Include/Sys= Host.h | 34 +- Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Platform/MemDefa= ults.h | 7 + Silicon/Intel/WhitleySiliconPkg/Pch/SouthClusterLbg/Include/PchInfoHob.h = | 50 ++ Silicon/Intel/WhitleySiliconPkg/WhitleySiliconPkg.dec = | 1 + 24 files changed, 1783 insertions(+), 67 deletions(-) diff --git a/Silicon/Intel/WhitleySiliconPkg/CpRcPkg.dec b/Silicon/Intel/Wh= itleySiliconPkg/CpRcPkg.dec index 902abd30f8..2ccdbffa35 100644 --- a/Silicon/Intel/WhitleySiliconPkg/CpRcPkg.dec +++ b/Silicon/Intel/WhitleySiliconPkg/CpRcPkg.dec @@ -82,6 +82,9 @@ gRcSimBiosIdFileGuid =3D { 0xf0c51ad5, 0x44f0, 0x4622, { 0x95= , 0x15, 0xe2, 0x7, 0x71, 0xf0, 0xe0, 0xf2 }} gSystemTopologyGuid =3D { 0x743e5992, 0xf2a0, 0x4c9f, { 0xa5= , 0xf5, 0x3b, 0x24, 0xad, 0xe8, 0x7f, 0x4d }} =20 +[Protocols] + gEfiCpuCsrAccessGuid =3D { 0x0067835f, 0x9a50, 0x433a, { 0x8c= , 0xbb, 0x85, 0x20, 0x78, 0x19, 0x78, 0x14 }} + [PPIs] ## Include/Ppi/MemorySetupPolicyPpi.h gMemoryPolicyPpiGuid =3D { 0x731b6dbc, 0x18ac, 0x4cc3, { 0x9= e, 0xe2, 0x9e, 0x5f, 0x33, 0x39, 0x68, 0x81 }} diff --git a/Silicon/Intel/WhitleySiliconPkg/Cpu/Include/CpuDataStruct.h b/= Silicon/Intel/WhitleySiliconPkg/Cpu/Include/CpuDataStruct.h index aaabf032f9..e1416a0d1c 100644 --- a/Silicon/Intel/WhitleySiliconPkg/Cpu/Include/CpuDataStruct.h +++ b/Silicon/Intel/WhitleySiliconPkg/Cpu/Include/CpuDataStruct.h @@ -24,4 +24,11 @@ // #define CONFIG_TDP_TOTAL_LEVEL 5 =20 +typedef struct { + UINT32 RegEax; + UINT32 RegEbx; + UINT32 RegEcx; + UINT32 RegEdx; +} EFI_CPUID_REGISTER; + #endif diff --git a/Silicon/Intel/WhitleySiliconPkg/Cpu/Include/Library/CpuConfigL= ib.h b/Silicon/Intel/WhitleySiliconPkg/Cpu/Include/Library/CpuConfigLib.h index 298fe08624..805f2ac6c8 100644 --- a/Silicon/Intel/WhitleySiliconPkg/Cpu/Include/Library/CpuConfigLib.h +++ b/Silicon/Intel/WhitleySiliconPkg/Cpu/Include/Library/CpuConfigLib.h @@ -19,6 +19,88 @@ #define C0_ENABLE 0x00 #define C6_ENABLE 0x03 =20 +// +// Structure for collected CPUID data. +// +typedef struct { + EFI_CPUID_REGISTER *CpuIdLeaf; + UINTN NumberOfBasicCpuidLeafs; + UINTN NumberOfExtendedCpuidLeafs; + UINTN NumberOfCacheAndTlbCpuidLeafs; + UINTN NumberOfDeterministicCacheParametersCpuidLeaf= s; + UINTN NumberOfExtendedTopologyEnumerationLeafs; +} CPU_CPUID_DATA; + +typedef struct { + UINTN Ratio; + UINTN Vid; + UINTN Power; + UINTN TransitionLatency; + UINTN BusMasterLatency; +} FVID_ENTRY; + +typedef struct { + VOID *MicrocodeData; + UINTN MicrocodeSize; + UINT32 ProcessorId; +} MICROCODE_INFO; + +// +// Miscellaneous processor data +// +typedef struct { + // + // Local Apic Data + // + UINT32 InitialApicID; ///< Initial APIC ID + UINT32 ApicID; ///< Current APIC ID + EFI_PHYSICAL_ADDRESS ApicBase; + UINT32 ApicVersion; + // + // Frequency data + // + UINTN IntendedFsbFrequency; + UINTN ActualFsbFrequency; + UINTN MaxCoreToBusRatio; + UINTN MinCoreToBusRatio; + UINTN MaxTurboRatio; + UINTN PackageTdp; + UINTN NumberOfPStates; + FVID_ENTRY *FvidTable; + UINTN GreaterNumberOfPStates; // Greater Than 16 p= -state support + FVID_ENTRY *GreaterFvidTable; // Greater Than 16 p= -state support + // + // Other data + // + UINT32 MicrocodeRevision; + UINT64 EnabledThreadCountMsr; + MICROCODE_INFO MicrocodeInfo; + UINT64 MiscEnablesMsr; +} CPU_MISC_DATA; + +// +// Structure for all collected processor data +// +typedef struct { + CPU_CPUID_DATA CpuidData; + EFI_CPU_PHYSICAL_LOCATION ProcessorLocation; + CPU_MISC_DATA CpuMiscData; + UINT8 PackageIdBitOffset; + BOOLEAN PackageBsp; +} CPU_COLLECTED_DATA; + +// +// Definition of Processor Configuration Context Buffer +// +typedef struct { + UINTN NumberOfProcessors; + UINTN BspNumber; + CPU_COLLECTED_DATA *CollectedDataBuffer; + CPU_REGISTER_TABLE *PreSmmInitRegisterTable; + CPU_REGISTER_TABLE *RegisterTable; + BOOLEAN RegisterTableSaved; +} CPU_CONFIG_CONTEXT_BUFFER; + // // Structure conveying socket ID configuration information. // diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/BackCompatible.h b/Sil= icon/Intel/WhitleySiliconPkg/Include/BackCompatible.h index 0e9fbde11f..88d7e02dcf 100644 --- a/Silicon/Intel/WhitleySiliconPkg/Include/BackCompatible.h +++ b/Silicon/Intel/WhitleySiliconPkg/Include/BackCompatible.h @@ -12,6 +12,9 @@ =20 #define R_ACPI_LV2 0x14 =20 +#define R_IOPORT_CMOS_STANDARD_INDEX 0x70 +#define R_IOPORT_CMOS_STANDARD_DATA 0x71 + #define R_IOPORT_CMOS_UPPER_INDEX 0x72 #define R_IOPORT_CMOS_UPPER_DATA 0x73 =20 diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/BdatSchema.h b/Silicon= /Intel/WhitleySiliconPkg/Include/BdatSchema.h new file mode 100644 index 0000000000..0b80015c65 --- /dev/null +++ b/Silicon/Intel/WhitleySiliconPkg/Include/BdatSchema.h @@ -0,0 +1,301 @@ +/** @file + + @copyright + Copyright 2006 - 2020 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _bdat_h +#define _bdat_h + +// +// Memory location that don't care was set to 0xFF +// +#define DO_NOT_CARE 0xFF + +#pragma pack(1) + +typedef struct bdatSchemaHeader { + EFI_GUID SchemaId; + UINT32 DataSize; + UINT16 Crc16; +} BDAT_SCHEMA_HEADER_STRUCTURE; + +// +// SPD data schema related definition +// + +// +// Memory SPD Data Header +// +typedef struct { + EFI_GUID MemSpdGuid; // GUID that uniquely identifies the memory SPD = data revision + UINT32 Size; // Total size in bytes including the header and = all SPD data + UINT32 Crc; // 32-bit CRC generated over the whole size minu= s this crc field + // Note: UEFI 32-bit CRC implementation (Calcula= teCrc32) + // Consumers can ignore CRC check if not needed. + UINT32 Reserved; // Reserved for future use, must be initialized = to 0 +} MEM_SPD_RAW_DATA_HEADER; + +// +// Memory SPD Raw Data +// +typedef struct { + MEM_SPD_RAW_DATA_HEADER Header; + + // + // This is a dynamic region, where SPD data entries are filled out. + // +} MEM_SPD_DATA_STRUCTURE; + +typedef struct { + BDAT_SCHEMA_HEADER_STRUCTURE SchemaHeader; + MEM_SPD_DATA_STRUCTURE SpdData; +} BDAT_MEM_SPD_STRUCTURE; + +// +// List of all entry types supported by this revision of memory SPD data s= tructure +// +typedef enum { + MemSpdDataType0 =3D 0, + + MemSpdDataTypeMax, + MemSpdDataTypeDelim =3D MAX_INT32 +} MEM_SPD_DATA_TYPE; + +// +// Generic entry header for all memory SPD raw data entries +// +typedef struct { + MEM_SPD_DATA_TYPE Type; + UINT16 Size; // Entries will be packed by byte in co= ntiguous space. Size of the entry includes the header. +} MEM_SPD_DATA_ENTRY_HEADER; + +// +// Structure to specify SPD dimm memory location +// +typedef struct { + UINT8 Socket; + UINT8 Channel; + UINT8 Dimm; +} MEM_SPD_DATA_ENTRY_MEMORY_LOCATION; + +// +// Type 0: SPD RDIMM/LRDIMM DDR4 +// The NumberOfBytes are 512 for DDR4. +// +typedef struct { + MEM_SPD_DATA_ENTRY_HEADER Header; + MEM_SPD_DATA_ENTRY_MEMORY_LOCATION MemoryLocation; + UINT16 NumberOfBytes; + // + // This is a dynamic region, where SPD data are filled out. + // The total number of bytes of the SPD data must match NumberOfBytes + // +} MEM_SPD_ENTRY_TYPE0; + +// +// Memory training data schema related definition +// + +// +// Memory training Data Header +// +typedef struct { + EFI_GUID MemDataGuid; // GUID that uniquely identifies the memory trai= ning data revision + UINT32 Size; // Total size in bytes including the header and = all memory training data + UINT32 Crc; // 32-bit CRC generated over the whole size minu= s this crc field + // Note: UEFI 32-bit CRC implementation (Calcula= teCrc32) + // Consumers can ignore CRC check if not needed. + UINT32 Reserved; // Reserved for future use, must be initialized = to 0 +} MEM_TRAINING_DATA_HEADER; + +// +// Memory SPD Raw Data +// +typedef struct { + MEM_TRAINING_DATA_HEADER Header; + + // + // This is a dynamic region, where memory training data entries are fill= ed out. + // +} MEM_TRAINING_DATA_STRUCTURE; + +typedef struct { + BDAT_SCHEMA_HEADER_STRUCTURE SchemaHeader; + MEM_TRAINING_DATA_STRUCTURE Data; +} BDAT_MEM_TRAINING_STRUCTURE; + +// +// List of all entry types supported by this revision of memory training d= ata structure +// +typedef enum { + MemTrainingDataCapability =3D 0, + MemTrainingDataIoGroup =3D 1, + MemTrainingDataDram =3D 2, + MemTrainingDataRcd =3D 3, + MemTrainingDataIoSignal =3D 4, + MemTrainingDataIoLatency =3D 5, + + MemTrainingDataTypeMax, + MemTrainingDataTypeDelim =3D MAX_INT32 +} MEM_TRAINING_DATA_TYPE; + +// +// Generic entry header for all memory training data entries +// +typedef struct { + MEM_TRAINING_DATA_TYPE Type; + UINT16 Size; // Entries will be packed by byte = in contiguous space. Size of the entry includes the header. +} MEM_TRAINING_DATA_ENTRY_HEADER; + +// +// Structure to specify memory training data location +// +typedef struct { + UINT8 Socket; + UINT8 Channel; + UINT8 SubChannel; + UINT8 Dimm; // 0xFF =3D n/a + UINT8 Rank; // 0xFF =3D n/a +} MEM_TRAINING_DATA_ENTRY_MEMORY_LOCATION; + +// +// List of memory training data scope +// +typedef enum { + PerBitMemTrainData =3D 0, + PerStrobeMemTrainData =3D 1, + PerRankMemTrainData =3D 2, + PerSubChannelMemTrainData =3D 3, + PerChannelMemTrainData =3D 4, + + MemTrainDataScopeMax, + MemTrainDataScopDelim =3D MAX_INT32 +} MEM_TRAINING_DATA_SCOPE; + +// +// Type 0: Define the capability. This info can be helpful for +// the code to display the training data. +// + +typedef struct { + MEM_TRAINING_DATA_ENTRY_HEADER Header; + UINT8 EccEnable; + UINT8 MaxSocket; + UINT8 MaxChannel; + UINT8 MaxSubChannel; // It = is 1 if there is no sub-channel + UINT8 MaxDimm; + UINT8 MaxRank; + UINT8 MaxStrobePerSubChannel; // It = is the MaxStrobe of the chanenl if there is no sub-channel + UINT8 MaxBitsPerSubChannel; // It = is the MaxBits of the chanenl if there is no sub-channel +} MEM_TRAINING_DATA_ENTRY_TYPE0; + +// +// Type 1: General training data that commonly accessed by GetSet API via = Group +// + +typedef struct { + MEM_TRAINING_DATA_ENTRY_HEADER Header; + MEM_TRAINING_DATA_ENTRY_MEMORY_LOCATION MemoryLocation; + MRC_LT Level; + MRC_GT Group; + MEM_TRAINING_DATA_SCOPE Scope; // If Scope i= s PerSubChannelMemTrainData or PerChannelMemTrainData, the training + // is applica= ble to whole SubChannel or Channel regardless the Dimm or Rank. + // The Memory= Loaction.Dimm and MemoryLoaction.Rank should be ignored. + UINT8 NumberOfElements; + UINT8 SizeOfElement; // Number of = bytes of each training data element. + // 1: UINT8 + // 2: UINT16 + // 4: UINT32 + // + // This is a dynamic region, where training data are filled out. + // The total number of bytes of the training data must be equal to + // NumberOfElements * SizeOfElement + // +} MEM_TRAINING_DATA_ENTRY_TYPE1; + +// +// Type 2: DRAM mode register data +// + +typedef struct { + MEM_TRAINING_DATA_ENTRY_HEADER Header; + MEM_TRAINING_DATA_ENTRY_MEMORY_LOCATION MemoryLocation; + UINT8 NumberOfModeRegisters; + UINT8 NumberOfDrams; + + // + // This is a dynamic region, where DRAM mode register data are filled ou= t. + // Each mode register data is one byte. The total number of bytes of the= data must be equal to + // NumberOfModeRegisters * NumberOfDrams. The data is indexed as [ModeRe= gister][Dram] + // +} MEM_TRAINING_DATA_ENTRY_TYPE2; + +// +// Type 3: RCD data +// + +typedef struct { + MEM_TRAINING_DATA_ENTRY_HEADER Header; + MEM_TRAINING_DATA_ENTRY_MEMORY_LOCATION MemoryLocation; + UINT8 NumberOfRegisters; + + // + // This is a dynamic region, where RCD RW register data are filled out. + // Each RW register data is one byte. The total number of bytes of the d= ata must be equal to + // NumberOfRegisters. + // +} MEM_TRAINING_DATA_ENTRY_TYPE3; + +// +// Type 4: IO Signal training data +// +typedef struct { + MRC_GT Signal; + INT16 Value; +} SIGNAL_DATA; + +typedef struct { + MEM_TRAINING_DATA_ENTRY_HEADER Header; + MEM_TRAINING_DATA_ENTRY_MEMORY_LOCATION MemoryLocation; + MRC_LT Level; + MEM_TRAINING_DATA_SCOPE Scope; // If Scope i= s PerSubChannelMemTrainData or PerChannelMemTrainData, the training + // is applica= ble to whole SubChannel or Channel regardless the Dimm or Rank. + // The Memory= Loaction.Dimm and MemoryLoaction.Rank should be ignored. + UINT8 NumberOfSignals; // Number of = SIGNAL_DATA struct + // + // This is a dynamic region, where signal training data are filled out. + // Each signal training data element is defined by a SIGNAL_DATA struct. + // The total number of bytes of the training data must be equal to + // NumberOfSignals * sizeof (SIGNAL_DATA) + // +} MEM_TRAINING_DATA_ENTRY_TYPE4; + +// +// Type 5: IO latency, Round trip and IO Comp training data +// + +typedef struct { + MEM_TRAINING_DATA_ENTRY_HEADER Header; + MEM_TRAINING_DATA_ENTRY_MEMORY_LOCATION MemoryLocation; + MEM_TRAINING_DATA_SCOPE Scope; // If Scope i= s PerSubChannelMemTrainData or PerChannelMemTrainData, the training + // is applica= ble to whole SubChannel or Channel regardless the Dimm or Rank. + // The Memory= Loaction.Dimm and MemoryLoaction.Rank should be ignored. + UINT8 IoLatency; + UINT8 RoundTrip; + UINT8 IoComp; +} MEM_TRAINING_DATA_ENTRY_TYPE5; + +// +// Memory training data HOB header +// This header contains the actual size of the training data in the HOB. T= he HOB data size is +// always mutiples of 8. +// +typedef struct { + UINT32 Size; +} MEM_TRAINING_DATA_HOB_HEADER; + +#pragma pack() +#endif // _bdat_h diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/Guid/MemoryMapData.h b= /Silicon/Intel/WhitleySiliconPkg/Include/Guid/MemoryMapData.h index 1512b90881..73f303594a 100644 --- a/Silicon/Intel/WhitleySiliconPkg/Include/Guid/MemoryMapData.h +++ b/Silicon/Intel/WhitleySiliconPkg/Include/Guid/MemoryMapData.h @@ -13,6 +13,8 @@ #include "SysHost.h" #include "PartialMirrorGuid.h" =20 +#define MEM_IMCCH_TO_SKTCH(Imc, Ch) ((Imc) * MAX_MC_CH + (Ch)) + #define RESERVED_2 2 #define RESERVED_4 4 =20 diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/IioRegs.h b/Silicon/In= tel/WhitleySiliconPkg/Include/IioRegs.h index 98f759be81..37a1e627da 100644 --- a/Silicon/Intel/WhitleySiliconPkg/Include/IioRegs.h +++ b/Silicon/Intel/WhitleySiliconPkg/Include/IioRegs.h @@ -124,32 +124,54 @@ //------------------------------------------------------------------------= ----------- // Port Index definition for ICX-SP //------------------------------------------------------------------------= ------------ +#define PCIE_PORT_0_DEV_0 0x03 +#define PCIE_PORT_0_FUNC_0 0x00 =20 -// IOU0 -#define PORT_1A_INDEX_1 1 -#define PORT_1B_INDEX_1 2 -#define PORT_1C_INDEX_1 3 -#define PORT_1D_INDEX_1 4 -// IOU1 -#define PORT_2A_INDEX_2 5 -#define PORT_2B_INDEX_2 6 -#define PORT_2C_INDEX_2 7 -#define PORT_2D_INDEX_2 8 -// IOU2 -#define PORT_3A_INDEX_3 9 -#define PORT_3B_INDEX_3 10 -#define PORT_3C_INDEX_3 11 -#define PORT_3D_INDEX_3 12 -// IOU3 -#define PORT_4A_INDEX_4 13 -#define PORT_4B_INDEX_4 14 -#define PORT_4C_INDEX_4 15 -#define PORT_4D_INDEX_4 16 -// IOU4 -#define PORT_5A_INDEX_5 17 -#define PORT_5B_INDEX_5 18 -#define PORT_5C_INDEX_5 19 -#define PORT_5D_INDEX_5 20 +#define PCIE_PORT_1A_DEV_1 0x02 +#define PCIE_PORT_1A_FUNC_1 0x00 +#define PCIE_PORT_1B_DEV_1 0x03 +#define PCIE_PORT_1C_DEV_1 0x04 +#define PCIE_PORT_1D_DEV_1 0x05 +#define PCIE_PORT_1A_FUNC_1 0x00 +#define PCIE_PORT_1B_FUNC_1 0x00 +#define PCIE_PORT_1C_FUNC_1 0x00 +#define PCIE_PORT_1D_FUNC_1 0x00 + +#define PCIE_PORT_2A_DEV_2 0x02 +#define PCIE_PORT_2B_DEV_2 0x03 +#define PCIE_PORT_2C_DEV_2 0x04 +#define PCIE_PORT_2D_DEV_2 0x05 +#define PCIE_PORT_2A_FUNC_2 0x00 +#define PCIE_PORT_2B_FUNC_2 0x00 +#define PCIE_PORT_2C_FUNC_2 0x00 +#define PCIE_PORT_2D_FUNC_2 0x00 + +#define PCIE_PORT_3A_DEV_3 0x02 +#define PCIE_PORT_3B_DEV_3 0x03 +#define PCIE_PORT_3C_DEV_3 0x04 +#define PCIE_PORT_3D_DEV_3 0x05 +#define PCIE_PORT_3A_FUNC_3 0x00 +#define PCIE_PORT_3B_FUNC_3 0x00 +#define PCIE_PORT_3C_FUNC_3 0x00 +#define PCIE_PORT_3D_FUNC_3 0x00 + +#define PCIE_PORT_4A_DEV_4 0x02 +#define PCIE_PORT_4B_DEV_4 0x03 +#define PCIE_PORT_4C_DEV_4 0x04 +#define PCIE_PORT_4D_DEV_4 0x05 +#define PCIE_PORT_4A_FUNC_4 0x00 +#define PCIE_PORT_4B_FUNC_4 0x00 +#define PCIE_PORT_4C_FUNC_4 0x00 +#define PCIE_PORT_4D_FUNC_4 0x00 + +#define PCIE_PORT_5A_DEV_5 0x02 +#define PCIE_PORT_5B_DEV_5 0x03 +#define PCIE_PORT_5C_DEV_5 0x04 +#define PCIE_PORT_5D_DEV_5 0x05 +#define PCIE_PORT_5A_FUNC_5 0x00 +#define PCIE_PORT_5B_FUNC_5 0x00 +#define PCIE_PORT_5C_FUNC_5 0x00 +#define PCIE_PORT_5D_FUNC_5 0x00 =20 // // Port Config Mode @@ -158,6 +180,8 @@ #define VMD_OWNERSHIP 3 #define PCIEAIC_OCL_OWNERSHIP 4 =20 +#define DMI_BUS_NUM 0 + #define NUMBER_TRACE_HUB_PER_SOCKET 1 =20 // diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/Library/EnhancedWarnin= gLogLib.h b/Silicon/Intel/WhitleySiliconPkg/Include/Library/EnhancedWarning= LogLib.h new file mode 100644 index 0000000000..211dc48c86 --- /dev/null +++ b/Silicon/Intel/WhitleySiliconPkg/Include/Library/EnhancedWarningLogLib= .h @@ -0,0 +1,494 @@ +/** @file + Interface header file for the Enhanced warning log library class. + + @copyright + Copyright 2018 - 2021 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _ENHANCED_WARNING_LOG_LIB_ +#define _ENHANCED_WARNING_LOG_LIB_ + +#include +#include + +#pragma pack(1) + +/// +/// Enhanced Warning Log Identification GUID +/// This GUID is used for HOB, UEFI variables, or UEFI Configuration Table= as needed by platform implementations +/// {D8E05800-005E-4462-AA3D-9C6B4704920B} +/// +#define EWL_ID_GUID { 0xd8e05800, 0x5e, 0x4462, { 0xaa, 0x3d, 0x9c, 0x6b, = 0x47, 0x4, 0x92, 0xb } }; + +/// +/// Enhanced Warning Log Revision GUID +/// Rev 1: {75713370-3805-46B0-9FED-60F282486CFC} +/// +#define EWL_REVISION1_GUID { 0x75713370, 0x3805, 0x46b0, { 0x9f, 0xed, 0x6= 0, 0xf2, 0x82, 0x48, 0x6c, 0xfc } }; + +/// +/// Enhanced Warning Log Header +/// +typedef struct { + EFI_GUID EwlGuid; /// GUID that uniquely identifies the EWL revisi= on + UINT32 Size; /// Total size in bytes including the header and= buffer + UINT32 FreeOffset; /// Offset of the beginning of the free space fr= om byte 0 + /// of the buffer immediately following this str= ucture + /// Can be used to determine if buffer has suffi= cient space for next entry + UINT32 Crc; /// 32-bit CRC generated over the whole size min= us this crc field + /// Note: UEFI 32-bit CRC implementation (Calcul= ateCrc32) (References [7]) + /// Consumers can ignore CRC check if not needed. + UINT32 Reserved; /// Reserved for future use, must be initialized= to 0 +} EWL_HEADER; + +/// +/// List of all entry types supported by this revision of EWL +/// +typedef enum { + EwlType0 =3D 0, + EwlType1 =3D 1, + EwlType2 =3D 2, + EwlType3 =3D 3, + EwlType4 =3D 4, + EwlType5 =3D 5, + EwlType6 =3D 6, + EwlType7 =3D 7, + EwlType8 =3D 8, + EwlType9 =3D 9, + EwlType10 =3D 10, + EwlType11 =3D 11, + EwlType12 =3D 12, + EwlType13 =3D 13, + EwlType14 =3D 14, + EwlType15 =3D 15, + EwlType16 =3D 16, + EwlType17 =3D 17, + EwlType18 =3D 18, + EwlType19 =3D 19, + EwlType20 =3D 20, + EwlType21 =3D 21, + EwlType22 =3D 22, + EwlType23 =3D 23, + EwlType24 =3D 24, + EwlType25 =3D 25, + EwlType26 =3D 26, + EwlType27 =3D 27, + EwlType28 =3D 28, + EwlType29 =3D 29, + EwlTypeMax, + EwlTypeOem =3D 0x8000, + EwlTypeDelim =3D MAX_INT32 + } EWL_TYPE; + +/// +/// EWL severities +/// +typedef enum { + EwlSeverityInfo, + EwlSeverityWarning, + EwlSeverityFatal, + EwlSeverityMax, + EwlSeverityDelim =3D MAX_INT32 + } EWL_SEVERITY; + +/// +/// EWL Size\Type Structure for error checking +/// +typedef struct { + EWL_TYPE Type; + UINT16 Size; +} EWL_SIZE_CHECK; + +/// +/// Generic entry header for parsing the log +/// +typedef struct { + EWL_TYPE Type; + UINT16 Size; /// Entries will be packed by byte in contiguous= space + EWL_SEVERITY Severity; /// Warning, error, informational, this may be e= xtended in the future +} EWL_ENTRY_HEADER; + +/// +/// Legacy content provides context of the warning +/// +typedef struct { + UINT8 MajorCheckpoint; // EWL Spec - Appendix B + UINT8 MinorCheckpoint; + UINT8 MajorWarningCode; // EWL Spec - Appendix A + UINT8 MinorWarningCode; +} EWL_ENTRY_CONTEXT; + +/// +/// Legacy content to specify memory location +/// +typedef struct { + UINT8 Socket; /// 0xFF =3D n/a + UINT8 Channel; /// 0xFF =3D n/a + UINT8 Dimm; /// 0xFF =3D n/a + UINT8 Rank; /// 0xFF =3D n/a +} EWL_ENTRY_MEMORY_LOCATION; + +/// +/// Type 1 =3D Legacy memory warning log content plus checkpoint +/// +typedef struct { + EWL_ENTRY_HEADER Header; + EWL_ENTRY_CONTEXT Context; + EWL_ENTRY_MEMORY_LOCATION MemoryLocation; +} EWL_ENTRY_TYPE1; + +/// +/// Type 2 =3D Enhanced type for data IO errors per device, per bit. +/// Primarily associated with MRC training failures. Checkpoint informat= ion provides additional +/// details to identify associated training step. +/// +typedef struct { + EWL_ENTRY_HEADER Header; + EWL_ENTRY_CONTEXT Context; + EWL_ENTRY_MEMORY_LOCATION MemoryLocation; + UINT8 Strobe; /// 0xFF =3D n/a; include mapping= of Dqs to Dq bits + UINT8 Bit; /// 0xFF =3D n/a; Dq bit# within = strobe group + MRC_LT Level; /// MrcGtDelim =3D n/a; Check BIO= S SSA spec (References [1]) + MRC_GT Group; /// MrcGtDelim =3D n/a; Check BIO= S SSA spec (References [1]) + UINT8 EyeSize; /// 0xFF =3D n/a +} EWL_ENTRY_TYPE2; + +/// +/// Type 3 =3D Enhanced type for command, control IO errors +/// Primarily associated with MRC training failures. Checkpoint informat= ion provides additional +/// details to identify associated training step. +/// +typedef struct { + EWL_ENTRY_HEADER Header; + EWL_ENTRY_CONTEXT Context; + EWL_ENTRY_MEMORY_LOCATION MemoryLocation; + MRC_LT Level; /// MrcGtDelim =3D n/a; Check BI= OS SSA spec (References [1]) + MRC_GT Group; /// MrcGtDelim =3D n/a; Check BI= OS SSA spec (References [1]) + GSM_CSN Signal; /// GsmCsnDelim =3D n/a + UINT8 EyeSize; /// 0xFF =3D n/a +} EWL_ENTRY_TYPE3; + +/// +/// Requisite definitions for Type 4 +/// +/// Advanced Memtest Types +/// +typedef enum { + AdvMtMax =3D 20, + AdvMtDelim =3D MAX_INT32 + } ADV_MT_TYPE; + +/// +/// Advanced Memtest Error log structure based on processor specific CSR d= efinitions +/// +typedef struct { + UINT32 Dat0S; + UINT32 Dat1S; + UINT32 Dat2S; + UINT32 Dat3S; + UINT32 EccS; + UINT32 Chunk; + UINT32 Column; + UINT32 ColumnExt; + UINT32 Row; + UINT32 RowExt; + UINT32 Bank; + UINT32 Rank; + UINT32 Subrank; +} EWL_ADV_MT_STATUS; + +/// +/// Type 4 =3D Enhanced type for DRAM Advanced Memtest errors +/// +typedef struct { + EWL_ENTRY_HEADER Header; + EWL_ENTRY_CONTEXT Context; + EWL_ENTRY_MEMORY_LOCATION MemoryLocation; + ADV_MT_TYPE MemtestType; + EWL_ADV_MT_STATUS AdvMemtestErrorInfo; + UINT32 Count; +} EWL_ENTRY_TYPE4; + +/// +/// Type 5 =3D Legacy Memtest accumulated DQ errors +/// +typedef struct { + EWL_ENTRY_HEADER Header; + EWL_ENTRY_CONTEXT Context; + EWL_ENTRY_MEMORY_LOCATION MemoryLocation; + UINT8 SubRank; + UINT8 BankAddress; + UINT8 DqBytes[9]; /// Byte 0 =3D DQ[7:0], byte 1 = =3D DQ[15:8], etc. +} EWL_ENTRY_TYPE5; + +/// +/// Type 6 =3D Legacy UPI/KTIRC warning log content plus checkpoint +/// +typedef struct { + EWL_ENTRY_HEADER Header; + EWL_ENTRY_CONTEXT Context; + UINT8 SocketMask; /// Bitmask of CPU Sockets affected;= 0xFF =3D SystemWide + UINT8 SocketType; /// 0 =3D CPU Socket, 1 =3D FPGA, 0x= FF =3D System Wide Warning + UINT8 Port; /// 0xFF =3D n/a; bitmask of affecte= d port(s) +} EWL_ENTRY_TYPE6; + +/// +/// Type 7 =3D CPU BIST failures +/// +typedef struct{ + EWL_ENTRY_HEADER Header; + EWL_ENTRY_CONTEXT Context; + UINT8 Socket; /// Socket number, 0 based + UINT32 Core; /// Core number, 0 based +} EWL_ENTRY_TYPE7; + +/// +/// IIO Link Error log structure primary based on PCIE Specification 3.0 (= References [8]) +/// +typedef struct { + UINT8 Socket; /// Socket number, 0 based + UINT8 Stack; /// 0-4, 0 =3D Cstack, 1-3 =3D = Pstack, 4 MCP-stack (Only SKX-F) + UINT8 Port; /// 0-3 + UINT8 LtssmMainState; /// Link state + UINT8 LtssmSubState; /// Check Appendix C to review = states definitions + UINT32 DidVid; /// [31:16] DeviceID, [15:0] Ve= ndorID of the device + /// attached to the Root Port +} EWL_IIO_LINK_DESCRIPTION; + +/// +/// Type 8 =3D IIO Link Degraded width +/// +typedef struct { + EWL_ENTRY_HEADER Header; + EWL_ENTRY_CONTEXT Context; + EWL_IIO_LINK_DESCRIPTION LinkDescription; + UINT8 ExpectedLinkWidth; /// Check register "Link Ca= pabilities Register" over + UINT8 ActualLinkWidth; /// PCIE Specification 3.0 = (References [8]) +} EWL_ENTRY_TYPE8; + +/// +/// Type 9 =3D IIO Link Degraded speed +/// +typedef struct { + EWL_ENTRY_HEADER Header; + EWL_ENTRY_CONTEXT Context; + EWL_IIO_LINK_DESCRIPTION LinkDescription; + UINT8 ExpectedLinkSpeed; /// Check register "Link Ca= pabilities Register" over + UINT8 ActualLinkSpeed; /// PCIE Specification 3.0 = (References [8]) +} EWL_ENTRY_TYPE9; + +/// +/// Type 10 =3D Dq Swizzle Discovery errors +/// Error if 0 or greater than 1 bit set in SwizzledDqLanes per strobe +/// +typedef struct { + EWL_ENTRY_HEADER Header; + EWL_ENTRY_CONTEXT Context; + EWL_ENTRY_MEMORY_LOCATION MemoryLocation; + UINT8 SwizzlePattern; /// DQ pattern sent from dev= ice + UINT8 SwizzledDqLanes; /// DQ pattern received at H= ost + UINT8 LanesPerStrobe; /// 4 or 8 + UINT8 Strobe; /// DQS number to identify d= evice +} EWL_ENTRY_TYPE10; + +/// +/// Type 13 =3D NVMDIMM Training Failure +/// Reported when a training issue is encountered +/// Includes additional details on the NVMDIMM SPD and FW revisions +/// +typedef struct { + EWL_ENTRY_HEADER Header; + EWL_ENTRY_CONTEXT Context; + EWL_ENTRY_MEMORY_LOCATION MemoryLocation; + UINT16 RevisionNvmdimmFw; + UINT8 RevisionNvmdimmSpd; +} EWL_ENTRY_TYPE13; + +/// +/// Type 17 =3D ME communication failures +/// Failure to communicate with Manageability Engine +/// +typedef struct { + EWL_ENTRY_HEADER Header; + EWL_ENTRY_CONTEXT Context; + UINT32 Revision; /// ME API Revision + UINT32 Mefs1; /// ME Firmware Status 1 (HECI-1 = HFS) + UINT32 Mefs2; /// ME Firmware Status 2 (HECI-1 = GS_SHDW) + UINT8 HeciDevice; /// HECI device (1, 2, or 3) + UINT8 MeAddress; /// HECI address of ME entity + UINT8 SendStatus; /// Status of send operation + UINT8 ReceiveStatus; /// Status of receive operation + UINT64 Request; /// First 8 bytes of request mess= age + UINT32 Response; /// First 4 bytes of response mes= sage +} EWL_ENTRY_TYPE17; + +/// +/// To get more information about Machine-Check Architecture please check = Chapter 15 from Vol. 3B +/// of the Intel(R) 64 and IA-32 Architectures Software Developer's Manua= l (References [6]) for a +/// general review. +/// +/// Type 20 =3D CPU Machine Check Errors +/// +typedef struct { + EWL_ENTRY_HEADER Header; + EWL_ENTRY_CONTEXT Context; + UINT32 CpuId; /// Refer to CPUID(EAX =3D 1) ins= truction to get Type, Family, + /// Model, and Stepping ID from = (References [6]) + UINT8 Socket; /// Socket number, 0 based + UINT32 Core; /// Core number, 0 based + UINT32 McBankNum; /// Please refer to mcBankTable + UINT32 McBankStatus; /// Check register IA32_MCi_STATU= S MSRs (References [6]&[5]) + UINT32 McBankAddr; /// Check register IA32_MCi_ADDR = MSRs (References [6]&[5]) + UINT32 McBankMisc; /// Check register IA32_MCi_MISC = MSRs (References [6]&[5]) +} EWL_ENTRY_TYPE20; + +/// +/// Requisite definitions for Type 21 +/// +/// Reasons for Topology degradation +/// +typedef enum { + Undefined =3D 0, + LinkFail =3D 1, + InvalidTopology =3D 2, + FeatureVsTopology =3D 3, + DegradeReasonMax, + DegradeReasonDelim =3D MAX_INT32 + } TOPOLOGY_DEGRADE_REASON; + +/// +/// Type 21: Warning for tracking changes to KTI/UPI topology +/// +/// Topology will be represented with a UINT64 bit array +/// 0 indicates absent or inactive link +/// 1 indicates active KTI/UPI link +/// +/// Link Bit array member variables follow this format +/// Each nibble corresponds to a socket: +/// Each socket has MAX_FW_KTI_PORTS bits +/// [(8*MAX_FW_KTI_PORTS - 1):7*MAX_FW_KTI_PORTS] - link bit mask for sock= et 7 +/// [(7*MAX_FW_KTI_PORTS - 1):6*MAX_FW_KTI_PORTS] - link bit mask for sock= et 6 +/// .... +/// [(2*MAX_FW_KTI_PORTS - 1): MAX_FW_KTI_PORTS] - link bit mask for sock= et 1 +/// [(MAX_FW_KTI_PORTS - 1) : 0] - link bit mask for sock= et 0 +/// +/// Bit 0 indicates an active link on port socket 0 port 0 +/// Bit 1 indicates an active link on port socket 0 port 1 +/// and so on. + +typedef struct { + EWL_ENTRY_HEADER Header; + TOPOLOGY_DEGRADE_REASON Reason; + UINT64 DegradedFrom; /// Link Bit Array + UINT64 NewTopology; /// Link Bit Array +} EWL_ENTRY_TYPE21; + +/// +/// To get more information about Machine-Check Architecture please check = Chapter 15 from Vol. 3B +/// of the Intel 64 and IA-32 Architectures Software Developer's Manual (= References [6]) for a +/// general review. +/// +/// Type 22 =3D CPU Machine Check Errors. 2nd Version. +/// +typedef struct { + EWL_ENTRY_HEADER Header; + EWL_ENTRY_CONTEXT Context; + UINT32 CpuId; /// Refer to CPUID(EAX=3D1) instr= uction to get Type, Family, + /// Model, and Stepping ID from = (References [6]) + UINT8 Socket; /// Socket number, 0 based + UINT32 Core; /// Core number, 0 based + UINT32 McBankNum; /// Please refer to mcBankTable + UINT64 McBankStatus; /// Check register IA32_MCi_STATU= S MSRs (References [6]&[5]) + UINT64 McBankAddr; /// Check register IA32_MCi_ADDR = MSRs (References [6]&[5]) + UINT64 McBankMisc; /// Check register IA32_MCi_MISC = MSRs (References [6]&[5]) +} EWL_ENTRY_TYPE22; + +// +// Memory Boot Health check Warning log. +// +typedef struct { + EWL_ENTRY_HEADER Header; + EWL_ENTRY_CONTEXT Context; + EWL_ENTRY_MEMORY_LOCATION MemoryLocation; + MRC_GT Group; /// MrcGtDelim =3D n/a; + INT16 Offset; /// Signal offset size that cause= d the error +} EWL_ENTRY_TYPE25; + +// +// Memory Power Management Errors +// +typedef struct { + EWL_ENTRY_HEADER Header; + EWL_ENTRY_CONTEXT Context; + EWL_ENTRY_MEMORY_LOCATION MemoryLocation; +} EWL_ENTRY_TYPE26; + +/// +/// Type 27 =3D NVMDIMM Media Log +/// Reported NVMDIMM Media log +/// +typedef struct { + EWL_ENTRY_HEADER Header; + EWL_ENTRY_CONTEXT Context; + EWL_ENTRY_MEMORY_LOCATION MemoryLocation; + UINT64 TimeStamp; + UINT64 DPA; + UINT64 PDA; + UINT8 Range; + UINT8 ErrorType; + UINT8 ErrorFlag; + UINT8 TransacationType; + UINT16 SequenceNumber; + UINT16 Rsvd; +} EWL_ENTRY_TYPE27; + +/// +/// Type 28 =3D NVMDIMM Thermal Log +/// Reported NVMDIMM Thermal log +/// +typedef struct { + EWL_ENTRY_HEADER Header; + EWL_ENTRY_CONTEXT Context; + EWL_ENTRY_MEMORY_LOCATION MemoryLocation; + UINT64 TimeStamp; + UINT32 HostReportedTempData; + UINT16 SequenceNumber; + UINT16 Rsvd; +} EWL_ENTRY_TYPE28; + +// +// RMT minimum margin check warning log. +// +typedef struct { + EWL_ENTRY_HEADER Header; + EWL_ENTRY_CONTEXT Context; + EWL_ENTRY_MEMORY_LOCATION MemoryLocation; + MRC_GT Group; + INT16 NegativeMargin; + INT16 PositiveMargin; + INT16 MinimumMargin; +} EWL_ENTRY_TYPE29; + +#pragma pack() + +/// +/// Enhanced Warning Log Spec defined data log structure +/// +typedef struct { + EWL_HEADER Header; /// The size will vary by implementation and= should not be assumed + UINT8 Buffer[4 * 1024]; /// The spec requirement is that the buffe= r follow the header +} EWL_PUBLIC_DATA; + +/// +/// EWL private data structure. This is going to be implementation depend= ent +/// When we separate OEM hooks via a PPI, we can remove this +/// +typedef struct { + UINT32 bufSizeOverflow; // Number of bytes that could not be= added to buffer + UINT32 numEntries; // Number of entries currently logged + EWL_PUBLIC_DATA status; // Spec defined EWL +} EWL_PRIVATE_DATA; + +#endif // #ifndef _ENHANCED_WARNING_LOG_LIB_ diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/Library/SpdAccessLib.h= b/Silicon/Intel/WhitleySiliconPkg/Include/Library/SpdAccessLib.h new file mode 100644 index 0000000000..4b15795665 --- /dev/null +++ b/Silicon/Intel/WhitleySiliconPkg/Include/Library/SpdAccessLib.h @@ -0,0 +1,32 @@ +/** @file + The SPD Access Library API provides the necessary functions to initiate = SPD + read/write transactions. + + This API is designed to function as an interface between an agent that n= eeds + to read/write to a DIMM SPD and a lower level library (such as an SMBus = library) + which handles the actual transactions. The read/write functions accept = DIMM + location information as well as the SPD byte offset and should then hand= le + the steps necessary to initiate (for example) a SMBus transaction to do = the + reading/writing. Functions are also provided to initialize any data/set= up + steps needed before attempting a read/write transaction and to communica= te to + the library that DIMM detection is complete providing a way for the libr= ary + to know that it can check for a DIMM's presence bofore initiating a tran= saction. + + @copyright + Copyright 2018 - 2020 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _SPD_ACCESS_LIB_H_ +#define _SPD_ACCESS_LIB_H_ + +// +// DDR Technology supported +// +typedef enum { + Ddr4Type =3D 0, // DDR4 Technology support + DdrMaxType // Enum limit to check valid value +} DDR_TECHNOLOGY_TYPE; + +#endif // #ifndef _SPD_ACCESS_LIB_H_ diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/MemCommon.h b/Silicon/= Intel/WhitleySiliconPkg/Include/MemCommon.h index 6958b1431b..af9f0b0734 100644 --- a/Silicon/Intel/WhitleySiliconPkg/Include/MemCommon.h +++ b/Silicon/Intel/WhitleySiliconPkg/Include/MemCommon.h @@ -38,4 +38,11 @@ typedef enum { TYPE_MAX_MMIO_BAR } MMIO_BARS; =20 +// +// Memory parameters and SPD JEDEC definitions +// +#define MAX_SPD_BYTE_DDR4 512 // Number of bytes in Serial EEPROM on DDR4 + +#define MAX_SPD_BYTE_DDR MAX_SPD_BYTE_DDR4 + #endif //#ifndef __MEM_COMMON_H__ diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/Platform.h b/Silicon/I= ntel/WhitleySiliconPkg/Include/Platform.h index b8ed188f16..e3cc80acde 100644 --- a/Silicon/Intel/WhitleySiliconPkg/Include/Platform.h +++ b/Silicon/Intel/WhitleySiliconPkg/Include/Platform.h @@ -224,6 +224,8 @@ =20 #define PCH_TCO_BASE_ADDRESS PcdGet16 (PcdTcoBaseAddress) =20 +#define PM_BASE_ADDRESS PCH_ACPI_BASE_ADDRESS + #define SIO_GPIO_BASE_ADDRESS 0x0800 =20 // @@ -240,6 +242,8 @@ #define CMOS_PLATFORM_ID_LO 0x18 // Second bank CMO= S location of Platform ID #define CMOS_PLATFORM_ID_HI 0x19 // =20 +#define HPET_BLOCK_ADDRESS 0x0FED00000 + #define PCI_BUS_NUMBER_PCH_HPET 0x0 #define PCI_DEVICE_NUMBER_PCH_HPET 0x1F =20 @@ -250,6 +254,9 @@ =20 #define PCI_FUNCTION_NUMBER_PCH_IOAPIC 0x0 =20 +#define SW_SMI_OS_REQUEST 0x83 // OS transition request. +#define MEM_ADDR_SHFT_VAL 26 // For 64 MB granularity + // // AHCI port offset values // diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/Ppi/MemoryPolicyPpi.h = b/Silicon/Intel/WhitleySiliconPkg/Include/Ppi/MemoryPolicyPpi.h index 6c5ca06bc1..38b90713f7 100644 --- a/Silicon/Intel/WhitleySiliconPkg/Include/Ppi/MemoryPolicyPpi.h +++ b/Silicon/Intel/WhitleySiliconPkg/Include/Ppi/MemoryPolicyPpi.h @@ -999,7 +999,7 @@ struct memSetup { /// @brief /// Pirnt length of SPD data.
/// @details - /// 0 - AUTO(512 for DDR4, 1024 for DDR5).
+ /// 0 - AUTO(512 for DDR4).
/// 256.
/// 512.
/// diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/AcpiPlatformP= rotocol.h b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/AcpiPlatformPr= otocol.h new file mode 100644 index 0000000000..d7f1adca4d --- /dev/null +++ b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/AcpiPlatformProtocol= .h @@ -0,0 +1,51 @@ +/** @file + EFI ACPI Platform Protocol + + @copyright + Copyright 2018 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _ACPI_PLATFORM_PROTOCOL_H +#define _ACPI_PLATFORM_PROTOCOL_H + +#include + +/// +/// ACPI Platform protocol provided for DXE phase +/// +typedef struct _ACPI_PLATFORM_PROTOCOL ACPI_PLATFORM_PROTOCOL; + +typedef EFI_ACPI_6_2_MEMORY_AFFINITY_STRUCTURE ACPI_MEMORY_AFFINITY_DATA; +#define ACPI_MEMORY_NONVOLATILE EFI_ACPI_6_2_MEMORY_NONVOLATILE + +/** + Function retrieves selected data of ACPI SRAT Memory Affinity Structures + (please note that data will not be available until SRAT table installati= on) + + @param[out] *MemAffData ACPI Memory Affinity Data + @param[out] *MemAffDataLength ACPI Memory Affinity Data Length + + @retval EFI_SUCCESS ACPI Memory Affinity Data retrieved succ= essfully + @retval EFI_NOT_FOUND ACPI Memory Affinity Data not found (SRA= T ACPI table was not published) + @retval EFI_INVALID_PARAMETER One or more of input arguments is NULL +**/ +typedef +EFI_STATUS +(EFIAPI *GET_ACPI_MEMORY_AFFINITY_DATA) ( + OUT ACPI_MEMORY_AFFINITY_DATA **MemAffData, + OUT UINTN *MemAffDataLength + ); + + +/** + ACPI Platform protocol provided for DXE phase +**/ +struct _ACPI_PLATFORM_PROTOCOL { + GET_ACPI_MEMORY_AFFINITY_DATA GetAcpiMemoryAffinityData; +}; + +extern EFI_GUID gAcpiPlatformProtocolGuid; + +#endif // _ACPI_PLATFORM_PROTOCOL_H diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/CpuCsrAccess.= h b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/CpuCsrAccess.h new file mode 100644 index 0000000000..4ace32de62 --- /dev/null +++ b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/CpuCsrAccess.h @@ -0,0 +1,254 @@ +/** @file + Header file for IOX access APIs. + + @copyright + Copyright 2007 - 2019 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _CPU_CSR_ACCESS_H_ +#define _CPU_CSR_ACCESS_H_ + +extern EFI_GUID gEfiCpuCsrAccessGuid; + +/** + + Computes address of CPU Uncore & IIO PCI configuration space using the M= MIO mechanism + + @param[in] SocId - CPU Socket Node number + @param[in] BoxInst - Box Instance, 0 based + @param[in] Offset - Register offset; values come from the auto gener= ated header file + @param[in, out] Size - Ptr to register size in bytes (may be updated if= pseudo-offset) + + @retval Address + +**/ + +typedef +UINT64 +(EFIAPI *GET_CPU_CSR_ADDRESS) ( + IN UINT8 SocId, + IN UINT8 BoxInst, + IN UINT32 Offset, + IN OUT UINT8 *Size + ); + +/** + + Reads CPU Uncore & IIO PCI configuration space using the MMIO mechanism + + @param[in] SocId - CPU Socket Node number + @param[in] BoxInst - Box Instance, 0 based + @param[in] Offset - Register offset; values come from the auto generat= ed header file + + @retval Register value + +**/ + +typedef +UINT32 +(EFIAPI *READ_CPU_CSR) ( + IN UINT8 SocId, + IN UINT8 BoxInst, + IN UINT32 Offset + ); + +/** + + Writes CPU Uncore & IIO PCI configuration space using the MMIO mechanism + + @param[in] SocId - CPU Socket Node number + @param[in] BoxInst - Box Instance, 0 based + @param[in] Offset - Register offset; values come from the auto genera= ted header file + @param[in] Data - Register data to be written + + @retval None + +**/ + +typedef +VOID +(EFIAPI *WRITE_CPU_CSR) ( + IN UINT8 SocId, + IN UINT8 BoxInst, + IN UINT32 Offset, + IN UINT32 Data + ); + +/** + + Reads CPU Memory Controller configuration space using the MMIO mechanism + + @param[in] SocId - Socket ID + @param[in] McId - Memory controller ID + @param[in] Offset - Register offset; values come from the auto gen= erated header file + + @retval Register value + +**/ + +typedef +UINT32 +(EFIAPI *READ_MC_CPU_CSR) ( + IN UINT8 SocId, + IN UINT8 McId, + IN UINT32 Offset + ); + +/** + + Writes CPU Memory Controller configuration space using the MMIO mechanism + + @param[in] SocId - Socket ID + @param[in] McId - Memory controller ID + @param[in] RegOffset - Register offset; values come from the auto gen= erated header file + @param[in] Data - Register data to be written + + @retval None + +**/ + +typedef +VOID +(EFIAPI *WRITE_MC_CPU_CSR) ( + IN UINT8 SocId, + IN UINT8 McId, + IN UINT32 RegOffset, + IN UINT32 Data + ); + +/** + + Get CPU Memory Controller configuration space address used by MMIO mecha= nism + + @param[in] SocId - Socket ID + @param[in] McId - Memory controller ID + @param[in] Offset - Register offset; values come from the auto gen= erated header file + + @retval MC Register MMCFG address + +**/ + +typedef +UINTN +(EFIAPI *GET_MC_CPU_ADDR) ( + IN UINT8 SocId, + IN UINT8 McId, + IN UINT32 RegOffset + ); + +/** + + Reads PCI configuration space using the MMIO mechanism + + @param[in] Socket - Socket + @param[in] Reg - "Reg" uses the format in the Bus_Dev_Func_CFG.H files + + @retval Value in requested reg + +**/ + +typedef +UINT32 +(EFIAPI *READ_PCI_CSR) ( + IN UINT8 Socket, + IN UINT32 Reg + ); + +/** + + Writes specified data to PCI configuration space using the MMIO mechanism + + @param[in] Socket - Socket + @param[in] Reg - "Reg" uses the format in the Bus_Dev_Func_CFG.H files + @param[in] Data - Value to write + + @retval VOID + +**/ + +typedef +VOID +(EFIAPI *WRITE_PCI_CSR) ( + IN UINT8 Socket, + IN UINT32 Reg, + IN UINT32 Data + ); + +/** + + Get PCI configuration space address used MMIO mechanism + + @param[in] Socket - Socket + @param[in] Reg - "Reg" uses the format in the Bus_Dev_Func_CFG.H files + + @retval Address of requested reg + +**/ + +typedef +UINT32 +(EFIAPI *GET_PCI_CSR_ADDR) ( + IN UINT8 Socket, + IN UINT32 Reg + ); + +/** + + Writes the given command to BIOS to PCU Mailbox Interface CSR register + + @param[in] Socket - CPU Socket number + @param[in] Command - Pcu mailbox command to write + @param[in] Data - Pcu mailbox data + + @retval error code from the Pcu mailbox (0 =3D NO ERROR) + +**/ + +typedef +UINT64 +(EFIAPI *BIOS_2_VCODE_MAILBOX_WRITE) ( + IN UINT8 Socket, + IN UINT32 Command, + IN UINT32 Data + ); + +/** + + Writes the checkpoint code to the checkpoint CSR and breaks if match wit= h debug breakpoint + @param[in] Socket - Socket to write + @param[in] majorCode - Major Checkpoint code to write + @param[in] minorCode - Minor Checkpoint code to write + @param[in] data - Data specific to the minor checkpoint is written = to + low word of the checkpoint CSR + + @retval VOID + +**/ + +typedef +VOID +(EFIAPI *BREAK_AT_CHECK_POINT) ( + IN UINT8 Socket, + IN UINT8 MajorCode, + IN UINT8 MinorCode, + IN UINT16 Data + ); + +typedef struct _EFI_CPU_CSR_ACCESS_PROTOCOL { + GET_CPU_CSR_ADDRESS GetCpuCsrAddress; + READ_CPU_CSR ReadCpuCsr; + WRITE_CPU_CSR WriteCpuCsr; + BIOS_2_VCODE_MAILBOX_WRITE Bios2VcodeMailBoxWrite; + READ_MC_CPU_CSR ReadMcCpuCsr; + WRITE_MC_CPU_CSR WriteMcCpuCsr; + GET_MC_CPU_ADDR GetMcCpuCsrAddress; + READ_PCI_CSR ReadPciCsr; + WRITE_PCI_CSR WritePciCsr; + GET_PCI_CSR_ADDR GetPciCsrAddress; + BREAK_AT_CHECK_POINT BreakAtCheckpoint; +} EFI_CPU_CSR_ACCESS_PROTOCOL; + +#endif // _CPU_CSR_ACCESS_H_ + diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibr= aryProtocol.h b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiL= ibraryProtocol.h index df8317937f..b9531dbf75 100644 --- a/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibraryProt= ocol.h +++ b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibraryProt= ocol.h @@ -1,5 +1,5 @@ /** @file - Dynamic link silicon library service access Protocol + Dynamic link silicon library service access Protocol for earlier boot fu= nctions =20 This protocol abstracts silicon static library accesses via a protocol =20 @@ -19,6 +19,9 @@ #include #include #include +#include +#include +#include =20 #define DYNAMIC_SI_LIBARY_PROTOCOL_GUID \ { 0xb235fbed, 0x3b25, 0x4cb3, { 0x98, 0x9c, 0x8c, 0xe7, 0xec, 0x49, 0x8b= , 0x7e } } @@ -30,13 +33,6 @@ // Functions // =20 -typedef -EFI_STATUS -(EFIAPI *DXE_SET_GPIO_OUTPUT_VALUE) ( - IN UINT32 GPioPad, - IN UINT32 Value - ); - typedef BOOLEAN (EFIAPI *DXE_IsCpuAndRevision) ( @@ -79,6 +75,27 @@ VOID IN UINT32 DidVid ); =20 +typedef +EFI_STATUS +(EFIAPI *DXE_GpioGetInputValue) ( + IN GPIO_PAD GpioPad, + OUT UINT32 *InputVal + ); + +typedef +EFI_STATUS +(EFIAPI *DXE_SET_GPIO_OUTPUT_VALUE) ( + IN UINT32 GPioPad, + IN UINT32 Value + ); + +typedef +EFI_STATUS +(EFIAPI *DXE_GpioSetPadConfig) ( + IN GPIO_PAD GpioPad, + IN GPIO_CONFIG *GpioData + ); + typedef CHAR8* (EFIAPI *DXE_PchGetSeriesStr) ( @@ -210,6 +227,13 @@ UINT32 VOID ); =20 +typedef +VOID +(EFIAPI *DXE_WriteScratchpad5) ( + UINT8 Socket, + UINT32 Value + ); + // // UBA specific silicon abstraction protocol // @@ -223,7 +247,9 @@ typedef struct { DXE_MmPciBase MmPciBase; DXE_GetSysCpuCsrAccessVar GetSysCpuCsrAccessVar; DXE_IioPciHookBeforeEnumeration IioPciHookBeforeEnumeration; + DXE_GpioGetInputValue GpioGetInputValue; DXE_SET_GPIO_OUTPUT_VALUE GpioSetOutputValue; + DXE_GpioSetPadConfig GpioSetPadConfig; DXE_PchGetSeriesStr PchGetSeriesStr; DXE_PchGetSteppingStr PchGetSteppingStr; DXE_PchGetSkuStr PchGetSkuStr; @@ -245,6 +271,7 @@ typedef struct { DXE_ProgramImr2Regs ProgramImr2Regs; DXE_CheckAndPopulateIedTraceMemory CheckAndPopulateIedTraceMemory; DXE_ReadScratchpad7 ReadScratchpad7; + DXE_WriteScratchpad5 WriteScratchpad5; } DYNAMIC_SI_LIBARY_PROTOCOL; =20 extern EFI_GUID gDynamicSiLibraryProtocolGuid; diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibr= aryProtocol2.h b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSi= LibraryProtocol2.h new file mode 100644 index 0000000000..5f984aa391 --- /dev/null +++ b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/DynamicSiLibraryProt= ocol2.h @@ -0,0 +1,255 @@ +/** @file + Dynamic link silicon library service access Protocol for later boot func= tions + + This protocol abstracts silicon static library accesses via a protocol + + @copyright + Copyright 2021 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _DYNAMIC_SI_LIBARY_PROTOCOL2_H_ +#define _DYNAMIC_SI_LIBARY_PROTOCOL2_H_ + +#include +#include +#include +#include +#include + +#define DYNAMIC_SI_LIBARY_PROTOCOL2_GUID { 0x98bdd399, 0x9349, 0x4131, { 0= x87, 0x60, 0x90, 0xaf, 0x68, 0x01, 0x21, 0xee } } + +#define DYNAMIC_SI_LIBARY_PROTOCOL2_SIGNATURE SIGNATURE_32('D', 'S', 'L',= '2') +#define DYNAMIC_SI_LIBARY_PROTOCOL2_VERSION 0x01 + +// +// Functions +// + +typedef +UINT32 +(EFIAPI *DXE_GetVtdBar) ( + IN UINT8 SocId, + IN UINT8 StackId + ); + +typedef +UINT8 +(EFIAPI *DXE_GetMaxPortPerSocket) ( + IN UINT8 SocId + ); + +typedef +UINT8 +(EFIAPI *DXE_GetStackPerPort) ( + IN UINT8 SocId, + IN UINT8 PortIndex + ); + +typedef +UINT8 +(EFIAPI *DXE_GetSocketPortBusNum) ( + IN UINT8 SocId, + IN UINT8 PortIndex + ); + +typedef +BOOLEAN +(EFIAPI *DXE_IioNtbIsEnabled) ( + IN UINT8 IioIndex, + IN UINT8 IioPort, + OUT UINT8 *DevNoPtr, + OUT UINT8 *FuncNoPtr + ); + +typedef +BOOLEAN +(EFIAPI *DXE_IioVmdPortIsEnabled) ( + IN UINT8 IioIndex, + IN UINT8 IioPort + ); + +typedef +EFI_STATUS +(EFIAPI *DXE_IioVmdGetPciLocation) ( + IN UINT8 IioIndex, + IN UINT8 IioStack, + OUT UINT8 *PciDevPtr, + OUT UINT8 *PciFuncPtr + ); + +typedef +UINT8 +(EFIAPI *DXE_GetCurrentPXPMap) ( + IN UINT8 SocId, + IN UINT8 PortIndex + ); + +typedef +BOOLEAN +(EFIAPI *DXE_IsSlowBoot) ( + VOID + ); + +typedef +EFI_STATUS +(EFIAPI *DXE_UpdatePcatTable) ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ); + +#pragma pack(1) +typedef struct { + UINT32 ApicId; + UINT32 ThreadIdValue; + UINT32 CollocatedChaId; + UINT32 SNCProximityDomain; +} CPU_LOGICAL_THREAD_ID_TABLE; +#pragma pack() + +typedef +UINT8 +(EFIAPI *DXE_GetNumOfClusterPerSystem) ( + VOID + ); + +typedef +UINT8 +(EFIAPI *DXE_GetMaxPhysicalAddrBits) ( + VOID + ); + +typedef +BOOLEAN +(EFIAPI *DXE_IsMemTypeVolatile) ( + MEM_TYPE MemType + ); + +typedef +BOOLEAN +(EFIAPI *DXE_IsMemType2lm) ( + MEM_TYPE MemType + ); + +typedef +BOOLEAN +(EFIAPI *DXE_IsMemTypeReserved) ( + MEM_TYPE MemType + ); + +typedef +BOOLEAN +(EFIAPI *DXE_IsMemTypeAppDirect) ( + MEM_TYPE MemType + ); + +typedef +BOOLEAN +(EFIAPI *DXE_IsMemTypeFpga) ( + MEM_TYPE MemType + ); + +typedef +UINT8 +(EFIAPI *DXE_GetKtiPortCnt) ( + VOID + ); + +typedef +UINT8 +(EFIAPI *DXE_GetMaxImc) ( + VOID + ); + +typedef +UINT8 +(EFIAPI *DXE_GetNumChannelPerMc) ( + VOID + ); + +typedef +UINT8 +(EFIAPI *DXE_GetAcpiDieCount) ( + IN UINT8 SocketId + ); + +typedef +EFI_STATUS +(EFIAPI *DXE_SpdReadByte) ( + IN UINT8 Socket, + IN UINT8 Chan, + IN UINT8 Dimm, + IN UINT16 ByteOffset, + OUT UINT8 *Data + ); + +typedef +UINT8 +(EFIAPI *DXE_DetectHwpFeature) ( + VOID + ); + +typedef +BOOLEAN +(EFIAPI *DXE_SocketPresent) ( + IN UINT32 SocId + ); + +typedef +BOOLEAN +(EFIAPI *DXE_IfStackPresent) ( + IN UINT8 SocId, + IN UINT8 StackId + ); + +typedef +EFI_STATUS +(EFIAPI *DXE_PchHpetBaseGet) ( + OUT UINT32 *HpetBase + ); + +typedef +UINT32 +(EFIAPI *DXE_PcuGetDesiredCoreSmtDis) ( + UINT8 Socket + ); + +// +// UBA specific silicon abstraction protocol +// +typedef struct { + UINT32 Signature; + UINT32 Version; + + DXE_GetVtdBar GetVtdBar; + DXE_GetMaxPortPerSocket GetMaxPortPerSocket; + DXE_GetStackPerPort GetStackPerPort; + DXE_GetSocketPortBusNum GetSocketPortBusNum; + DXE_IioNtbIsEnabled IioNtbIsEnabled; + DXE_IioVmdPortIsEnabled IioVmdPortIsEnabled; + DXE_IioVmdGetPciLocation IioVmdGetPciLocation; + DXE_GetCurrentPXPMap GetCurrentPXPMap; + DXE_IsSlowBoot IsSlowBoot; + DXE_UpdatePcatTable UpdatePcatTable; + DXE_GetNumOfClusterPerSystem GetNumOfClusterPerSystem; + DXE_GetMaxPhysicalAddrBits GetMaxPhysicalAddrBits; + DXE_IsMemTypeVolatile IsMemTypeVolatile; + DXE_IsMemType2lm IsMemType2lm; + DXE_IsMemTypeReserved IsMemTypeReserved; + DXE_IsMemTypeAppDirect IsMemTypeAppDirect; + DXE_IsMemTypeFpga IsMemTypeFpga; + DXE_GetKtiPortCnt GetKtiPortCnt; + DXE_GetMaxImc GetMaxImc; + DXE_GetNumChannelPerMc GetNumChannelPerMc; + DXE_GetAcpiDieCount GetAcpiDieCount; + DXE_SpdReadByte SpdReadByte; + DXE_DetectHwpFeature DetectHwpFeature; + DXE_SocketPresent SocketPresent; + DXE_IfStackPresent IfStackPresent; + DXE_PchHpetBaseGet PchHpetBaseGet; + DXE_PcuGetDesiredCoreSmtDis PcuGetDesiredCoreSmtDis; +} DYNAMIC_SI_LIBARY_PROTOCOL2; + +extern EFI_GUID gDynamicSiLibraryProtocol2Guid; + +#endif // _DYNAMIC_SI_LIBARY_PROTOCOL2_H_ diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/NfitTableUpda= teProtocol.h b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/NfitTableUp= dateProtocol.h new file mode 100644 index 0000000000..bd85f646c9 --- /dev/null +++ b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/NfitTableUpdateProto= col.h @@ -0,0 +1,27 @@ +/** @file + + @copyright + Copyright 2018 - 2019 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _NFIT_TABLE_UPDATE_PROTOCOL_H_ +#define _NFIT_TABLE_UPDATE_PROTOCOL_H_ + +// +// Extern the GUID for protocol users. +// +extern EFI_GUID gEfiNfitTableUpdateProtocolGuid; + +typedef +EFI_STATUS +(EFIAPI *NFIT_TABLE_UPDATE) ( + UINT64 *NfitTablePointer + ); + +typedef struct _EFI_NFIT_TABLE_UPDATE_PROTOCOL { + NFIT_TABLE_UPDATE UpdateAcpiTable; +} EFI_NFIT_TABLE_UPDATE_PROTOCOL; + +#endif // _NFIT_TABLE_UPDATE_PROTOCOL_H_ diff --git a/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/SmbiosMemInfo= .h b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/SmbiosMemInfo.h new file mode 100644 index 0000000000..7b398cf1dc --- /dev/null +++ b/Silicon/Intel/WhitleySiliconPkg/Include/Protocol/SmbiosMemInfo.h @@ -0,0 +1,87 @@ +/** @file + This file publishes protocol that provides additional information + for memory related SMBIOS entries. + NOTE: Currently only Type17 entries are used, no need for others identif= ied. + Only Type17 entries that represent existing DIMMs are listed. + + @copyright + Copyright 2017 - 2018 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _PROTOCOL_SMBIOSMEMINFO_H_ +#define _PROTOCOL_SMBIOSMEMINFO_H_ + +#define SMBIOS_MEMINFO_PROT_VERSION 1 + +// +// Invalid SMBIOS handle to use if Type17 entry does not exist. +// +#define SMBIOS_INVALID_HANDLE 0xFFFF + +typedef struct _SMBIOS_MEM_INFO_PROTOCOL_ SMBIOS_MEM_INFO_PROTOCOL; + +/** + * Localization information for SMBIOS Type17 entries that represent DIMMs. + */ +typedef struct _SMBIOS_DIMM_INFO_ { + INT8 Socket; ///< Socket index (0 based) + INT8 Imc; ///< Intergrated memory controller in th= e above socket + INT8 Channel; ///< Channel in the above IMC + INT8 Dimm; ///< DIMM slot index in the above channel + EFI_SMBIOS_HANDLE Type17Handle; ///< Type17 handle in SMBIOS table + BOOLEAN IsNvDimm; ///< True if it is Non Volatile DIMM +} SMBIOS_DIMM_INFO; + + +/** + This function finds SMBIOS Type17 entry for given SMBIOS handle. + + On input Info->Handle must be set. + On output, unless error was returned, the rest of the structure is fille= d. + + @param[in] This - Pointer to the protocol + @param[in,out] Info - Pointer to DIMM info structure + + @return Standard status codes are returned. +**/ +typedef EFI_STATUS (EFIAPI *SMBIOS_GET_DIMM_BY_HANDLE) ( + IN SMBIOS_MEM_INFO_PROTOCOL *This, + IN OUT SMBIOS_DIMM_INFO *Info + ); + +/** + This function finds SMBIOS Type17 entry for given DIMM location. + + On input Info->Socket, Info->Imc, Info->Channel, Info->Dimm must be set. + On output, unless error was returned, the rest of the structure is fille= d. + + @param[in] This - Pointer to the protocol + @param[in,out] Info - Pointer to DIMM info structure. + + @return Standard status codes are returned. +**/ +typedef EFI_STATUS (EFIAPI *SMBIOS_GET_DIMM_BY_LOCATION) ( + IN SMBIOS_MEM_INFO_PROTOCOL *This, + IN OUT SMBIOS_DIMM_INFO *Info + ); + +/** + * This protocol provides information about memory related SMBIOS entries. + * + * NOTE: Currently only Type17 entries are used, no need for others. + * Only Type17 entries that represent existing DIMMs are listed. + */ +typedef struct _SMBIOS_MEM_INFO_PROTOCOL_ { + UINT16 SmbiosMemInfoProtVersion; + UINT8 Reserved[2]; + UINT32 SmbiosDimmNum; ///< Number of DIMM (Type17) = handles in SMBIOS + + SMBIOS_GET_DIMM_BY_HANDLE SmbiosGetDimmByHandle; + SMBIOS_GET_DIMM_BY_LOCATION SmbiosGetDimmByLocation; +} SMBIOS_MEM_INFO_PROTOCOL; + +extern EFI_GUID gSmbiosMemInfoProtocolGuid; + +#endif // _PROTOCOL_SMBIOSMEMINFO_H_ diff --git a/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core= /Include/MemRegs.h b/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCore= Lib/Core/Include/MemRegs.h index 3c8abe4dbb..7b2baa3284 100644 --- a/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Includ= e/MemRegs.h +++ b/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Includ= e/MemRegs.h @@ -10,6 +10,8 @@ #ifndef _memregs_h #define _memregs_h =20 +#define SPD_TYPE_DDR4 0x0C // DDR4 SDRAM + // // NVM DIMM Reg Structs // diff --git a/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core= /Include/MrcCommonTypes.h b/Silicon/Intel/WhitleySiliconPkg/Library/BaseMem= oryCoreLib/Core/Include/MrcCommonTypes.h index eba0a14354..a85e10609a 100644 --- a/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Includ= e/MrcCommonTypes.h +++ b/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Includ= e/MrcCommonTypes.h @@ -21,8 +21,33 @@ typedef struct { UINT32 NumDqLanesPerCh; // Number of active DQ lanes in a data c= hannel (bus width) } MRC_MSM; =20 +typedef enum { + DdrLevel =3D 0, ///< Refers to frontside of DIMM + LrbufLevel =3D 1, ///< Refers to data level at b= ackside of LRDIMM or NVMDIMM buffer + RegALevel =3D 2, ///< Refers to cmd level at bac= kside of register, side A + RegBLevel =3D 3, ///< Refers to cmd level at bac= kside of register, side B + HbmLevel =3D 4, ///< Refers to HBM + MrcLtMax, + MrcLtDelim =3D MAX_INT32 + } MRC_LT; + +/// +/// Memory training margin group selectors. +/// +typedef enum { + MrcGtMax =3D 224, + MrcGtDelim =3D MAX_INT32 + } MRC_GT; + typedef enum { MrcTtDelim =3D MAX_INT32 } MRC_TT; =20 +/// +/// External signal names +/// +typedef enum { + gsmCsnDelim =3D MAX_INT32 +} GSM_CSN; + #endif // _MrcCommonTypes_h_ diff --git a/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core= /Include/SysHost.h b/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCore= Lib/Core/Include/SysHost.h index d419edea4a..50aa342994 100644 --- a/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Includ= e/SysHost.h +++ b/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Core/Includ= e/SysHost.h @@ -27,39 +27,7 @@ typedef struct sysHost SYSHOST, *PSYSHOST; #include "PlatformHost.h" #include "MemHost.h" #include - -/// -/// Enhanced Warning Log Header -/// -typedef struct { - EFI_GUID EwlGuid; /// GUID that uniquely identifies the EWL revisi= on - UINT32 Size; /// Total size in bytes including the header and= buffer - UINT32 FreeOffset; /// Offset of the beginning of the free space fr= om byte 0 - /// of the buffer immediately following this str= ucture - /// Can be used to determine if buffer has suffi= cient space for next entry - UINT32 Crc; /// 32-bit CRC generated over the whole size min= us this crc field - /// Note: UEFI 32-bit CRC implementation (Calcul= ateCrc32) (References [7]) - /// Consumers can ignore CRC check if not needed. - UINT32 Reserved; /// Reserved for future use, must be initialized= to 0 -} EWL_HEADER; - -/// -/// Enhanced Warning Log Spec defined data log structure -/// -typedef struct { - EWL_HEADER Header; /// The size will vary by implementation and= should not be assumed - UINT8 Buffer[4 * 1024]; /// The spec requirement is that the buffe= r follow the header -} EWL_PUBLIC_DATA; - -/// -/// EWL private data structure. This is going to be implementation depend= ent -/// When we separate OEM hooks via a PPI, we can remove this -/// -typedef struct { - UINT32 bufSizeOverflow; // Number of bytes that could not be= added to buffer - UINT32 numEntries; // Number of entries currently logged - EWL_PUBLIC_DATA status; // Spec defined EWL -} EWL_PRIVATE_DATA; +#include =20 #pragma pack(1) =20 diff --git a/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Plat= form/MemDefaults.h b/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCore= Lib/Platform/MemDefaults.h index 68c2f447c9..97f1f45290 100644 --- a/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Platform/Me= mDefaults.h +++ b/Silicon/Intel/WhitleySiliconPkg/Library/BaseMemoryCoreLib/Platform/Me= mDefaults.h @@ -17,6 +17,13 @@ #define SMB_CLK_700K 2 #define SMB_CLK_1M 3 =20 +// +// Volatile Memory Mode +// +#define VOL_MEM_MODE_1LM 0 +#define VOL_MEM_MODE_2LM 1 +#define VOL_MEM_MODE_MIX_1LM2LM 2 + #define MAX_PARTIAL_MIRROR 4 //Maximum number of partial mirror regi= ons that can be created =20 // diff --git a/Silicon/Intel/WhitleySiliconPkg/Pch/SouthClusterLbg/Include/Pc= hInfoHob.h b/Silicon/Intel/WhitleySiliconPkg/Pch/SouthClusterLbg/Include/Pc= hInfoHob.h new file mode 100644 index 0000000000..0972181531 --- /dev/null +++ b/Silicon/Intel/WhitleySiliconPkg/Pch/SouthClusterLbg/Include/PchInfoHo= b.h @@ -0,0 +1,50 @@ +/** @file + This file contains definitions of PCH Info HOB. + +@copyright + Copyright 2018 Intel Corporation. + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _PCH_INFO_HOB_H_ +#define _PCH_INFO_HOB_H_ + +#include + +extern EFI_GUID gPchInfoHobGuid; + +#define PCH_INFO_HOB_REVISION 2 + +#pragma pack (push,1) +/** + This structure is used to provide the information of PCH controller. + + Revision 1: + - Initial version. + Revision 2: + - Add CridSupport, CridOrgRid, and CridNewRid. +**/ +typedef struct { + /** + This member specifies the revision of the PCH Info HOB. This field is = used + to indicate backwards compatible changes to the protocol. Platform cod= e that + consumes this protocol must read the correct revision value to correct= ly interpret + the content of the protocol fields. + **/ + UINT8 Revision; + + /** + Publish Hpet BDF and IoApic BDF information for VTD. + **/ + UINT32 HpetBusNum : 8; + UINT32 HpetDevNum : 5; + UINT32 HpetFuncNum : 3; + UINT32 IoApicBusNum : 8; + UINT32 IoApicDevNum : 5; + UINT32 IoApicFuncNum : 3; +} PCH_INFO_HOB; + +#pragma pack (pop) + +#endif // _PCH_INFO_HOB_H_ diff --git a/Silicon/Intel/WhitleySiliconPkg/WhitleySiliconPkg.dec b/Silico= n/Intel/WhitleySiliconPkg/WhitleySiliconPkg.dec index ae951e0b14..d50b1d8da3 100644 --- a/Silicon/Intel/WhitleySiliconPkg/WhitleySiliconPkg.dec +++ b/Silicon/Intel/WhitleySiliconPkg/WhitleySiliconPkg.dec @@ -37,6 +37,7 @@ PACKAGE_GUID =3D 6f1ec317-5d04-456a-8908-6290453d57ac =20 [Protocols] gDynamicSiLibraryProtocolGuid =3D { 0xb235fbed, 0x3b25, = 0x4cb3, { 0x98, 0x9c, 0x8c, 0xe7, 0xec, 0x49, 0x8b, 0x7e }} + gDynamicSiLibraryProtocol2Guid =3D { 0x98bdd399, 0x9349, = 0x4131, { 0x87, 0x60, 0x90, 0xaf, 0x68, 0x01, 0x21, 0xee }} gDynamicSiLibrarySmmProtocolGuid =3D { 0x82faf3a3, 0x6226, = 0x48be, {0xb0, 0x4e, 0xc2, 0xfb, 0x0f, 0x72, 0xcf, 0x2f }} =20 [PcdsDynamicEx] --=20 2.27.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#87425): https://edk2.groups.io/g/devel/message/87425 Mute This Topic: https://groups.io/mt/89698847/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat May 18 21:45:23 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+87430+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+87430+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1646952118; cv=none; d=zohomail.com; s=zohoarc; b=fU8XowuEqjIMcsICqlA7E72KfVJcoSRREDgXGRWpzuPcnyFaOG9YXtWqLih4/e0LrWdnD0WHWrKCN6qaHKNw4UbsaNuQoIuPsGMafXiFcVbV9JGO9n1tsu7jKho/7KVC0r//h3snzMzpDosRMNd80pi/GEzAMN+3sYS2YJjBb/E= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1646952118; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=PGez+7ftPUPSXCH4+ypuKlpqhXs/423N8GhQveuXKj4=; b=FBqr/mABoYulPT6GxNmXjh3BeYIvR+CjnrJlwfYFwl+O1MX3FIvq+VtH5e4tqyB53/d0Zt61QJ29xudre1r/nuL6X7rhJAwY0rqJa6LaO8TtZna0cu9lFGgrWAvgvhtI+10Kh/J18wl6yRdhKtMVA3ZS0nqotMi65cp8HVx3DKU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+87430+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1646952118460798.3618774450385; Thu, 10 Mar 2022 14:41:58 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id rNiiYY1788612xEPVVZU2CAC; Thu, 10 Mar 2022 14:41:57 -0800 X-Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mx.groups.io with SMTP id smtpd.web12.860.1646952112302807460 for ; Thu, 10 Mar 2022 14:41:52 -0800 X-IronPort-AV: E=McAfee;i="6200,9189,10282"; a="316121249" X-IronPort-AV: E=Sophos;i="5.90,171,1643702400"; d="scan'208";a="316121249" X-Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2022 14:41:34 -0800 X-IronPort-AV: E=Sophos;i="5.90,171,1643702400"; d="scan'208";a="644643363" X-Received: from iworam-desk.amr.corp.intel.com ([10.7.150.60]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2022 14:41:34 -0800 From: "Oram, Isaac W" To: devel@edk2.groups.io Cc: Nate DeSimone , Chasel Chiu Subject: [edk2-devel][edk2-platforms][PATCH V1 3/9] WhitleyOpenBoardPkg/BaseCrcLib: Add library for CRC16 Date: Thu, 10 Mar 2022 14:41:08 -0800 Message-Id: <406972869595ac96cd402be7843f16b9e0534df9.1646951441.git.isaac.w.oram@intel.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,isaac.w.oram@intel.com X-Gm-Message-State: poj7ayBBrNZoMBVHTeZZ0u6Kx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1646952117; bh=SVMLo/szrNJmH9Tr6Ga7qkZiZLp4nKKPgzDgOerbmws=; h=Cc:Date:From:Reply-To:Subject:To; b=Lc2nINXjgwRfS0yzsiaxlyq7Uqa4O+bzjGhlWyjES/6zcQO0cHPqMTkhWCuZzvDu9nH tPBiJ72ED6avCTYqLJA60VKw58Ie7HEcuGZlVAj0PAQuO5IAjpqSX252qQVDdezgupX9a Zm56zQFSfj+63/BTxi4+tZdiU26aBszJSiA= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1646952120236100013 Content-Type: text/plain; charset="utf-8" Core only supports CRC32, this library adds CRC16 support. Cc: Nate DeSimone Cc: Chasel Chiu Signed-off-by: Isaac Oram Reviewed-by: Nate DeSimone --- Platform/Intel/WhitleyOpenBoardPkg/Include/Library/CrcLib.h | 42 = ++++++++++++ Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.c | 71 = ++++++++++++++++++++ Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf | 23 = +++++++ Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc | 1 + 4 files changed, 137 insertions(+) diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/CrcLib.h b/= Platform/Intel/WhitleyOpenBoardPkg/Include/Library/CrcLib.h new file mode 100644 index 0000000000..7ca3b7cabb --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/CrcLib.h @@ -0,0 +1,42 @@ +/** @file + Interface header file for the CRC library class. + + @copyright + Copyright 2016 - 2018 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _CRC_LIB_H_ +#define _CRC_LIB_H_ + +#include + +/** + Calculate a 16-bit CRC. + + The algorithm used is MSB-first form of the ITU-T Recommendation V.41, w= hich + uses an initial value of 0x0000 and a polynomial of 0x1021. It is the sa= me + algorithm used by XMODEM. + + The output CRC location is not updated until the calculation is finished= , so + it is possible to pass a structure as the data, and the CRC field of the= same + structure as the output location for the calculated CRC. The CRC field s= hould + be set to zero before calling this function. Once the CRC field is updat= ed by + this function, running it again over the structure produces a CRC of zer= o. + + @param[in] Data A pointer to the target data. + @param[in] DataSize The target data size. + @param[out] CrcOut A pointer to the return location of the CR= C. + + @retval EFI_SUCCESS The CRC was calculated successfully. + @retval EFI_INVALID_PARAMETER A null pointer was provided. +**/ +EFI_STATUS +CalculateCrc16 ( + IN VOID *Data, + IN UINTN DataSize, + OUT UINT16 *CrcOut + ); + +#endif // _CRC_LIB_H_ diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcL= ib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.c new file mode 100644 index 0000000000..3e8fa402ad --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.c @@ -0,0 +1,71 @@ +/** @file + Base implementation of the CRC library class. + + @copyright + Copyright 2016 - 2018 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include + +/** + Calculate a 16-bit CRC. + + The algorithm used is MSB-first form of the ITU-T Recommendation V.41, w= hich + uses an initial value of 0x0000 and a polynomial of 0x1021. It is the sa= me + algorithm used by XMODEM. + + The output CRC location is not updated until the calculation is finished= , so + it is possible to pass a structure as the data, and the CRC field of the= same + structure as the output location for the calculated CRC. The CRC field s= hould + be set to zero before calling this function. Once the CRC field is updat= ed by + this function, running it again over the structure produces a CRC of zer= o. + + @param[in] Data A pointer to the target data. + @param[in] DataSize The target data size. + @param[out] CrcOut A pointer to the return location of the CR= C. + + @retval EFI_SUCCESS The CRC was calculated successfully. + @retval EFI_INVALID_PARAMETER A null pointer was provided. +**/ +EFI_STATUS +CalculateCrc16 ( + IN VOID *Data, + IN UINTN DataSize, + OUT UINT16 *CrcOut + ) +{ + UINT32 Crc; + UINTN Index; + UINT8 *Byte; + + if (Data =3D=3D NULL || CrcOut =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + Crc =3D 0x0000; + for (Byte =3D (UINT8 *) Data; Byte < (UINT8 *) Data + DataSize; Byte++) { + // + // XOR the next data byte into the CRC. + // + Crc ^=3D (UINT16) *Byte << 8; + // + // Shift out eight bits, feeding back based on the polynomial whenever= a + // 1 is shifted out of bit 15. + // + for (Index =3D 0; Index < 8; Index++) { + Crc <<=3D 1; + if (Crc & BIT16) { + Crc ^=3D 0x1021; + } + } + } + + // + // Mask and return the 16-bit CRC. + // + *CrcOut =3D (UINT16) (Crc & 0xFFFF); + return EFI_SUCCESS; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcL= ib.inf b/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.i= nf new file mode 100644 index 0000000000..6b404e1259 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf @@ -0,0 +1,23 @@ +## @file +# Base implementation of the CRC library class. +# +# @copyright +# Copyright 2016 Intel Corporation.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010019 + BASE_NAME =3D BaseCrcLib + FILE_GUID =3D F3BE9A28-78A2-4B02-AB26-D27EE85D9256 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D CrcLib + +[Sources] + BaseCrcLib.c + +[Packages] + MdePkg/MdePkg.dec + WhitleyOpenBoardPkg/PlatformPkg.dec diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc b/Platform/= Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc index e78a104004..9cdb5bc2f6 100644 --- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc +++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc @@ -618,6 +618,7 @@ PciSegmentInfoLib|$(PLATFORM_PKG)/Pci/Library/PciSegmentInfoLibSimple/Pc= iSegmentInfoLibSimple.inf PlatformOpromPolicyLib|$(RP_PKG)/Library/PlatformOpromPolicyLibNull/Plat= formOpromPolicyLibNull.inf VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf + CrcLib|WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf =20 [LibraryClasses.Common.SEC, LibraryClasses.Common.PEI_CORE, LibraryClasses= .Common.PEIM] FspWrapperApiLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFs= pWrapperApiLib.inf --=20 2.27.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#87430): https://edk2.groups.io/g/devel/message/87430 Mute This Topic: https://groups.io/mt/89698852/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat May 18 21:45:23 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+87427+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+87427+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1646952113; cv=none; d=zohomail.com; s=zohoarc; b=hWuYpPcEo7kase02pt/xo1T52iikdrGIGJMfE6rVUUhfunjkyUZtByZ3z99eiaTKPFRANOhBq3bUpu3lMww4lIHxUK5kZp5Mpz0XaUdpQ5tRyuxVPd2nEBoBA/RjqdpxwzduIX7eT5ioCNSYFU3sdJc+oywg9PaRCwsY5VPB39I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1646952113; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=yP99k9NkbMEnM8c5b+NwyGuJY298iO3zxrA+LiFFALE=; b=RbKK/FN/h2SOybLUT3uelHhieN1vJOKLjSqkGOGG+gc44jHspyG0XX3XOgYoEkp332UVf7UNtuAFpJf7Vvx3dIFZXSBsZ62R8oczWqkEbvRfoANv2iVGRKLCKV/prUNZkTHqfr9JM5Lpdj/p3IW0y4eWcftHzfjTN9xljVYY5Wo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+87427+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1646952113852521.9470464717767; Thu, 10 Mar 2022 14:41:53 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id JB1NYY1788612xE2KBSU6NWd; Thu, 10 Mar 2022 14:41:53 -0800 X-Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mx.groups.io with SMTP id smtpd.web08.849.1646952110863190430 for ; Thu, 10 Mar 2022 14:41:52 -0800 X-IronPort-AV: E=McAfee;i="6200,9189,10282"; a="316121250" X-IronPort-AV: E=Sophos;i="5.90,171,1643702400"; d="scan'208";a="316121250" X-Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2022 14:41:34 -0800 X-IronPort-AV: E=Sophos;i="5.90,171,1643702400"; d="scan'208";a="644643367" X-Received: from iworam-desk.amr.corp.intel.com ([10.7.150.60]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2022 14:41:34 -0800 From: "Oram, Isaac W" To: devel@edk2.groups.io Cc: Nate DeSimone , Chasel Chiu Subject: [edk2-devel][edk2-platforms][PATCH V1 4/9] WhitleyOpenBoardPkg: Add UbaPlatLib Library Date: Thu, 10 Mar 2022 14:41:09 -0800 Message-Id: <239581252d3c5691a8e11c3ec59453892e85008d.1646951441.git.isaac.w.oram@intel.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,isaac.w.oram@intel.com X-Gm-Message-State: JYbJwpCcM5c1Us2cb7XaPX3Zx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1646952113; bh=I48kLktgNnzjHhZ1LD2JDGod+2H/9+vU0D3M45zFWnM=; h=Cc:Date:From:Reply-To:Subject:To; b=hvJNot0KRumXScUSXMdNOiSABeDh0txdbLF4dn7WdQPJdVFugk0ALe1fiHgUMSw+s1V i+61eLQ6ZSGvYFbrdwo3ZhA4lGNWQNLUP3WCn5ykjY7g5XGFjRIflP9StkopY0kK192zN ETvK8bcjuTs5p9sbjpXv3h2RyRPKGF3/64o= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1646952115733100009 Content-Type: text/plain; charset="utf-8" UbaPlatLib is required by AcpiTablesLib used by AcpiPlatform driver. Cc: Nate DeSimone Cc: Chasel Chiu Signed-off-by: Isaac Oram Reviewed-by: Nate DeSimone --- Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaGpioPlatformCo= nfigLib.c | 388 ++++++++++++ Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemBoardInf= oLib.c | 62 ++ Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemConfigUp= dateLib.c | 60 ++ Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaUsbOcUpdateLib= .c | 61 ++ Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaAcpiUpdateLib.c = | 59 ++ Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaFpkConfigLib.c = | 57 ++ Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaIioConfigLib.c = | 132 ++++ Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaOpromUpdateLib.c = | 221 +++++++ Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaPlatLib.inf = | 62 ++ Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSlotUpdateLib.c = | 114 ++++ Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSmbiosUpdateLib.c= | 663 ++++++++++++++++++++ Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaCommon.dsc = | 3 + 12 files changed, 1882 insertions(+) diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaGp= ioPlatformConfigLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatL= ib/DxeUbaGpioPlatformConfigLib.c new file mode 100644 index 0000000000..d03f0f9957 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaGpioPlatf= ormConfigLib.c @@ -0,0 +1,388 @@ +/** @file + + @copyright + Copyright 2012 - 2017 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// UBA and GPIO headers +// + +#include +#include + +STATIC PLATFORM_GPIO_CONFIG_TABLE mGpioParams; +DYNAMIC_SI_LIBARY_PROTOCOL *mDynamicSiLibraryProtocol = =3D NULL; + +/** + The library constructor call. Gets required protocols and stores for lat= er usage + This also applies for SMM mode usage + + @param[in] None + + @retval EFI_SUCCESS The function completed successfully + +**/ +EFI_STATUS +EFIAPI +InitializeDxeUbaPlatLib ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + UBA_CONFIG_DATABASE_PROTOCOL *UbaConfigProtocol =3D NULL; + UINTN TableSize; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, &m= DynamicSiLibraryProtocol); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return EFI_NOT_FOUND; + } + + Status =3D gBS->LocateProtocol ( + &gUbaConfigDatabaseProtocolGuid, + NULL, + &UbaConfigProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + + TableSize =3D sizeof (PLATFORM_GPIO_CONFIG_TABLE); + Status =3D UbaConfigProtocol->GetData ( + UbaConfigProtocol, + &gPlatformGpioPlatformConfigDataGuid, + &mGpioParams, + &TableSize + ); + + return Status; + +} + +/** + Reads GPIO pin to get DFX jumper status + + @param[out] DfxJumper - The pointer to the DFX jumper input + + @retval Status - Success if GPIO's are read properly + +**/ +EFI_STATUS +GpioGetDfxPadVal ( + OUT UINT32 *DfxJumper + ) +{ + EFI_STATUS Status; + + if (mGpioParams.ReservedM =3D=3D UNUSED_GPIO) { + return EFI_UNSUPPORTED; + } + + Status =3D mDynamicSiLibraryProtocol->GpioGetInputValue (mGpioParams.Res= ervedM, DfxJumper); + return Status; +} + +/** + Reads GPIO pin to get recovery jumper status + + @param[out] RcvJumper - The pointer to the Recovery jumper input + + @retval Status - Success if GPIO's are read properly + +**/ +EFI_STATUS +GpioGetRcvPadVal ( + OUT UINT32 *RcvJumper + ) +{ + EFI_STATUS Status; + + if (mGpioParams.RcvJumper =3D=3D UNUSED_GPIO) { + return EFI_UNSUPPORTED; + } + + Status =3D mDynamicSiLibraryProtocol->GpioGetInputValue (mGpioParams.Rcv= Jumper, RcvJumper); + return Status; +} + +/** + Reads GPIO pin to get FM ADR trigger pin + + @param[out] FmAdrTrigger - The pointer to the ADR trigger input + + @retval Status - Success if GPIO's are read properly + +**/ +EFI_STATUS +GpioGetFmAdrTriggerPadVal ( + OUT UINT32 *FmAdrTrigger + ) +{ + EFI_STATUS Status; + + if (mGpioParams.FmAdrTrigger =3D=3D UNUSED_GPIO) { + return EFI_UNSUPPORTED; + } + + Status =3D mDynamicSiLibraryProtocol->GpioGetInputValue (mGpioParams.FmA= drTrigger, FmAdrTrigger); + return Status; +} + +/** + Sets GPIO pin to enable ADR on the board + + @param Set[in] - If TRUE means the pas should go 'high', otherwise 'low' + + @retval Status - Success if GPIO set properly + +**/ +EFI_STATUS +GpioSetAdrEnablePadOutVal ( + IN BOOLEAN Set + ) +{ + EFI_STATUS Status; + + if (mGpioParams.AdrEnable =3D=3D UNUSED_GPIO) { + return EFI_UNSUPPORTED; + } + + if (Set) { + Status =3D mDynamicSiLibraryProtocol->GpioSetOutputValue (mGpioParams.= AdrEnable, GpioOutHigh); + } else { + Status =3D mDynamicSiLibraryProtocol->GpioSetOutputValue (mGpioParams.= AdrEnable, GpioOutLow); + } + return Status; +} + +/** + Reads GPIO pin to Force to S1 config mode pad + + @param[out] ForceS1ConfigPad - Input value of the Force S1 Config pad + + @retval Status - Success if GPIO's are read properly + +**/ +EFI_STATUS +GpioGetForcetoS1ConfigModePadVal ( + OUT UINT32 *ForceS1ConfigPad + ) +{ + EFI_STATUS Status; + + if (mGpioParams.ForceTo1SConfigModePad =3D=3D UNUSED_GPIO) { + return EFI_UNSUPPORTED; + } + + Status =3D mDynamicSiLibraryProtocol->GpioGetInputValue (mGpioParams.For= ceTo1SConfigModePad, ForceS1ConfigPad); + return Status; +} + +/** + Reads GPIO pin related to QAT + + @param[out] QATPad - Input value of the QAT pad + + @retval Status - Success if GPIO's are read properly + +**/ +EFI_STATUS +GpioGetQATPadVal ( + OUT UINT32 *QATPad + ) +{ + EFI_STATUS Status; + + if (mGpioParams.QATGpio =3D=3D UNUSED_GPIO) { + return EFI_UNSUPPORTED; + } + + Status =3D mDynamicSiLibraryProtocol->GpioGetInputValue (mGpioParams.QAT= Gpio, QATPad); + return Status; +} + +/** + Get GPIO pin for SCI detection for WHEA RAS functionality + + @param[out] WheaSciPad - Input value of the Whea SCI pad + + @retval Status - Success if GPIO's pad read properly + +**/ +EFI_STATUS +GpioGetWheaSciPad ( + OUT UINT32 *WheaSciPad + ) +{ + if (mGpioParams.WheaSciPad =3D=3D UNUSED_GPIO) { + return EFI_UNSUPPORTED; + } + + *WheaSciPad =3D (UINT32) mGpioParams.WheaSciPad; + return EFI_SUCCESS; +} + +/** + Get GPIO pin for FPGA error detection RAS functionality + + @param[out] FpgaErrorPad -The input value of the FPGA error 1 pad + + @retval Status - Success if GPIO's pad read properly + +**/ +EFI_STATUS +GpioGetFpgaErrorPad1 ( + OUT UINT32 *FpgaErrorPad + ) +{ + if (mGpioParams.FpgaErrorSingnalPad1 =3D=3D UNUSED_GPIO) { + return EFI_UNSUPPORTED; + } + + *FpgaErrorPad =3D (UINT32) mGpioParams.FpgaErrorSingnalPad1; + return EFI_SUCCESS; +} + +/** + Get GPIO pin for FPGA error detection RAS functionality + + @param[out] FpgaErrorPad -The input value of the FPGA error 2 pad + + @retval Status - Success if GPIO's pad read properly + +**/ +EFI_STATUS +GpioGetFpgaErrorPad2 ( + OUT UINT32 *FpgaErrorPad + ) +{ + + if (mGpioParams.FpgaErrorSingnalPad2 =3D=3D UNUSED_GPIO) { + return EFI_UNSUPPORTED; + } + + *FpgaErrorPad =3D (UINT32) mGpioParams.FpgaErrorSingnalPad2; + return EFI_SUCCESS; +} + +/** + Get GPIO pin for CPU HP SMI detection for RAS functionality + + @retval Status - Success if GPIO's pad read properly + +**/ +EFI_STATUS +GpioGetCpuHpSmiPad ( + OUT UINT32 *CpuHpSmiPad + ) +{ + + if (mGpioParams.CpuHpSmiPad =3D=3D UNUSED_GPIO) { + return EFI_UNSUPPORTED; + } + + *CpuHpSmiPad =3D (UINT32) mGpioParams.CpuHpSmiPad; + return EFI_SUCCESS; +} + +/** + Reads GPIO pin that is first bit of the Board ID indication word + + @param[out] BoardID0Gpio - Input value of the first Board ID pad + + @retval Status - Success if GPIO's are read properly + +**/ +EFI_STATUS +GpioGetBoardId0PadVal ( + OUT UINT32 *BoardID0Gpio + ) +{ + EFI_STATUS Status; + + if (mGpioParams.BoardID0Gpio =3D=3D UNUSED_GPIO) { + return EFI_UNSUPPORTED; + } + + Status =3D mDynamicSiLibraryProtocol->GpioGetInputValue (mGpioParams.Boa= rdID0Gpio, BoardID0Gpio); + return Status; +} + +/** + Sets GPIO's used for Boot Mode + + @param None + + @retval Status - Success if GPIO's are configured + +**/ +EFI_STATUS +GpioConfigForMFGMode ( + VOID + ) +{ + EFI_STATUS Status; + + if (mGpioParams.GpioMfgPad.GpioPad =3D=3D UNUSED_GPIO) { + return EFI_UNSUPPORTED; + } + + DEBUG ((DEBUG_INFO, "Start ConfigureGpio() for BootMode Detection.\n")); + + Status =3D mDynamicSiLibraryProtocol->GpioSetPadConfig (mGpioParams.Gpio= MfgPad.GpioPad, + &mGpioParams.GpioMfgPad.GpioConfig); + ASSERT_EFI_ERROR (Status); + + DEBUG ((DEBUG_INFO, "End ConfigureGpio() for BootMode Detection.\n")); + return Status; +} + +/** + Checks whether the MDF jumper has been set + + @param None + + @retval ManufacturingMode - TRUE when MFG jumper is on, FALSE otherwise + +**/ +BOOLEAN +IsManufacturingMode ( + VOID + ) +{ + BOOLEAN ManufacturingMode =3D TRUE; + + EFI_STATUS Status; + UINT32 GpiValue; + + if (mGpioParams.GpioMfgPad.GpioPad =3D=3D UNUSED_GPIO) { + return FALSE; + } + + Status =3D GpioConfigForMFGMode (); + ASSERT_EFI_ERROR (Status); + + Status =3D mDynamicSiLibraryProtocol->GpioGetInputValue (mGpioParams.Gpi= oMfgPad.GpioPad, &GpiValue); + ASSERT_EFI_ERROR (Status); + + if (!GpiValue) { + ManufacturingMode =3D FALSE; + } + return ManufacturingMode; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSy= stemBoardInfoLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/= DxeUbaSystemBoardInfoLib.c new file mode 100644 index 0000000000..f585b1ac9e --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemBoa= rdInfoLib.c @@ -0,0 +1,62 @@ +/** @file + + @copyright + Copyright 2017 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + + +EFI_STATUS +GetSystemBoardInfo ( + IN OUT DXE_SYSTEM_BOARD_INFO **SystemboardInfoTableBuffer + ) +{ + EFI_STATUS Status; + UBA_CONFIG_DATABASE_PROTOCOL *UbaConfigProtocol =3D NULL; + UINTN DataLength =3D 0; + SYSTEM_BOARD_INFO_DATA SystemBoardInfoData; + + Status =3D gBS->LocateProtocol ( + &gUbaConfigDatabaseProtocolGuid, + NULL, + &UbaConfigProtocol + ); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR," [GetSystemBoardInfo] Locate UbaConfigProtocol fa= il!\n")); + return Status; + } + + DataLength =3D sizeof(SystemBoardInfoData); + Status =3D UbaConfigProtocol->GetData ( + UbaConfigProtocol, + &gSystemBoardInfoConfigDataGuid, + &SystemBoardInfoData, + &DataLength + ); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR," [GetSystemBoardInfo] Get Data fail!\n")); + return Status; + } + + ASSERT (SystemBoardInfoData.Signature =3D=3D SYSTEM_SYSTEM_BOARD_INFO_SI= GNATURE); + ASSERT (SystemBoardInfoData.Version =3D=3D SYSTEM_SYSTEM_BOARD_INFO_VE= RSION); + + *SystemboardInfoTableBuffer =3D SystemBoardInfoData.CallUpdate (); + + return Status; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSy= stemConfigUpdateLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatL= ib/DxeUbaSystemConfigUpdateLib.c new file mode 100644 index 0000000000..525e44358f --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaSystemCon= figUpdateLib.c @@ -0,0 +1,60 @@ +/** @file + + @copyright + Copyright 2017 - 2018 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +EFI_STATUS +UpdateIioDefaultConfig ( + IN SYSTEM_CONFIGURATION *Default + ) +{ + EFI_STATUS Status; + UBA_CONFIG_DATABASE_PROTOCOL *UbaConfigProtocol =3D NULL; + UINTN DataLength =3D 0; + SYSTEM_CONFIG_UPDATE_DATA SystemConfigUpdateTable; + + Status =3D gBS->LocateProtocol ( + &gUbaConfigDatabaseProtocolGuid, + NULL, + &UbaConfigProtocol + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR," [UpdateIioDefaultConfig] Locate UbaConfigProtoco= l fail!\n")); + return Status; + } + + DataLength =3D sizeof(SystemConfigUpdateTable); + Status =3D UbaConfigProtocol->GetData ( + UbaConfigProtocol, + &gSystemConfigUpdateDataGuid, + &SystemConfigUpdateTable, + &DataLength + ); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR," [UpdateIioDefaultConfig] Get Data fail!\n")); + return Status; + } + + ASSERT (SystemConfigUpdateTable.Signature =3D=3D SYSTEM_CONFIG_UPDATE_SI= GNATURE); + ASSERT (SystemConfigUpdateTable.Version =3D=3D SYSTEM_CONFIG_UPDATE_VE= RSION); + + SystemConfigUpdateTable.CallUpdateIioConfig (Default); + + return Status; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaUs= bOcUpdateLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeU= baUsbOcUpdateLib.c new file mode 100644 index 0000000000..bdbd012913 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/DxeUbaUsbOcUpda= teLib.c @@ -0,0 +1,61 @@ +/** @file + + @copyright + Copyright 2012 - 2019 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +EFI_STATUS +PlatformGetUsbOcMappings ( + IN OUT USB_OVERCURRENT_PIN **Usb20OverCurrentMappings, + IN OUT USB_OVERCURRENT_PIN **Usb30OverCurrentMappings, + IN OUT USB2_PHY_PARAMETERS **Usb20AfeParams + ) +{ + EFI_STATUS Status; + UBA_CONFIG_DATABASE_PROTOCOL *UbaConfigProtocol =3D NULL; + PLATFORM_USBOC_UPDATE_TABLE UsbOcUpdateTable; + UINTN TableSize; + + Status =3D gBS->LocateProtocol ( + &gUbaConfigDatabaseProtocolGuid, + NULL, + &UbaConfigProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + + TableSize =3D sizeof(UsbOcUpdateTable); + Status =3D UbaConfigProtocol->GetData ( + UbaConfigProtocol, + &gDxePlatformUbaOcConfigDataGuid, + &UsbOcUpdateTable, + &TableSize + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + ASSERT (UsbOcUpdateTable.Signature =3D=3D PLATFORM_USBOC_UPDATE_SIGNATUR= E); + ASSERT (UsbOcUpdateTable.Version =3D=3D PLATFORM_USBOC_UPDATE_VERSION); + + UsbOcUpdateTable.CallUsbOcUpdate ( Usb20OverCurrentMappings, + Usb30OverCurrentMappings, + Usb20AfeParams + ); + + return Status; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaAcpiU= pdateLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaAcpiU= pdateLib.c new file mode 100644 index 0000000000..595d1a62fd --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaAcpiUpdateLi= b.c @@ -0,0 +1,59 @@ +/** @file + + @copyright + Copyright 2013 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +EFI_STATUS +PlatformGetAcpiFixTableDataPointer ( + IN VOID **TablePtr + ) +{ + EFI_STATUS Status; + + UBA_CONFIG_DATABASE_PROTOCOL *UbaConfigProtocol =3D NULL; + UINTN DataLength =3D 0; + ACPI_FIX_UPDATE_TABLE AcpiFixUpdateTable; + + Status =3D gBS->LocateProtocol ( + &gUbaConfigDatabaseProtocolGuid, + NULL, + &UbaConfigProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DataLength =3D sizeof (AcpiFixUpdateTable); + Status =3D UbaConfigProtocol->GetData ( + UbaConfigProtocol, + &gPlatformAcpiFixTableGuid, + &AcpiFixUpdateTable, + &DataLength + ); + if (EFI_ERROR (Status)) { + return Status; + } + + ASSERT (AcpiFixUpdateTable.Signature =3D=3D PLATFORM_ACPI_FIX_UPDATE_SIG= NATURE); + ASSERT (AcpiFixUpdateTable.Version =3D=3D PLATFORM_ACPI_FIX_UPDATE_VERSI= ON); + + *TablePtr =3D AcpiFixUpdateTable.TablePtr; + + return EFI_SUCCESS; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaFpkCo= nfigLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaFpkCon= figLib.c new file mode 100644 index 0000000000..9d1c867cab --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaFpkConfigLib= .c @@ -0,0 +1,57 @@ +/** @file + UBA FPK configuration library + + @copyright + Copyright 2016 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include + +/** + Retrieves FPK config struct from UBA database + + @retval EFI_SUCCESS Config struct is retrieved. + @retval EFI_NOT_FOUND UBA protocol, platform or data not found. + @retval EFI_INVALID_PARAMETER If PlatformFpkConfigStruct is NULL. +**/ +EFI_STATUS +FpkConfigGetConfigStruct ( + OUT PLATFORM_FPK_CONFIG_STRUCT *PlatformFpkConfigStruct + ) +{ + EFI_STATUS Status; + UBA_CONFIG_DATABASE_PROTOCOL *UbaConfigProtocol =3D NULL; + UINTN DataLength =3D 0; + + Status =3D gBS->LocateProtocol ( + &gUbaConfigDatabaseProtocolGuid, + NULL, + &UbaConfigProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DataLength =3D sizeof (*PlatformFpkConfigStruct); + Status =3D UbaConfigProtocol->GetData ( + UbaConfigProtocol, + &gPlatformFpkConfigDataGuid, + PlatformFpkConfigStruct, + &DataLength + ); + if (EFI_ERROR (Status)) { + return Status; + } + + ASSERT (PlatformFpkConfigStruct->Signature =3D=3D PLATFORM_FPK_CONFIG_SI= GNATURE); + ASSERT (PlatformFpkConfigStruct->Version =3D=3D PLATFORM_FPK_CONFIG_VE= RSION); + + return EFI_SUCCESS; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaIioCo= nfigLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaIioCon= figLib.c new file mode 100644 index 0000000000..0e18b4543b --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaIioConfigLib= .c @@ -0,0 +1,132 @@ +/** @file + DxeUbaIioConfigLib implementation. + + @copyright + Copyright 2012 - 2018 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +EFI_STATUS +PlatformIioConfigInit ( + IN OUT IIO_BIFURCATION_DATA_ENTRY **BifurcationTable, + IN OUT UINT8 *BifurcationEntries, + IN OUT IIO_SLOT_CONFIG_DATA_ENTRY **SlotTable, + IN OUT UINT8 *SlotEntries + ) +{ + EFI_STATUS Status; + UBA_CONFIG_DATABASE_PROTOCOL *UbaConfigProtocol =3D NULL; + UINTN DataLength =3D 0; + PLATFORM_IIO_CONFIG_UPDATE_TABLE IioUpdateTable; + + Status =3D gBS->LocateProtocol ( + &gUbaConfigDatabaseProtocolGuid, + NULL, + &UbaConfigProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DataLength =3D sizeof (IioUpdateTable); + Status =3D UbaConfigProtocol->GetData ( + UbaConfigProtocol, + &gPlatformIioConfigDataDxeGuid, + &IioUpdateTable, + &DataLength + ); + if (EFI_ERROR (Status)) { + return Status; + } + + ASSERT (IioUpdateTable.Signature =3D=3D PLATFORM_IIO_CONFIG_UPDATE_SIGNA= TURE); + ASSERT (IioUpdateTable.Version =3D=3D PLATFORM_IIO_CONFIG_UPDATE_VERSION= ); + + *BifurcationTable =3D IioUpdateTable.IioBifurcationTablePtr; + *BifurcationEntries =3D (UINT8) (IioUpdateTable.IioBifurcationTableSize = / sizeof(IIO_BIFURCATION_DATA_ENTRY)); + + *SlotTable =3D IioUpdateTable.IioSlotTablePtr; + *SlotEntries =3D (UINT8)(IioUpdateTable.IioSlotTableSize / sizeof(IIO_SL= OT_CONFIG_DATA_ENTRY)); + + return EFI_SUCCESS; +} + +EFI_STATUS +PlatformIioConfigInit2 ( + IN UINT8 SkuPersonalityType, + IN OUT IIO_BIFURCATION_DATA_ENTRY **BifurcationTable, + IN OUT UINT8 *BifurcationEntries, + IN OUT IIO_SLOT_CONFIG_DATA_ENTRY **SlotTable, + IN OUT UINT8 *SlotEntries + ) +{ + EFI_STATUS Status; + UBA_CONFIG_DATABASE_PROTOCOL *UbaConfigProtocol =3D NULL; + UINTN DataLength =3D 0; + PLATFORM_IIO_CONFIG_UPDATE_TABLE IioUpdateTable; + + Status =3D gBS->LocateProtocol ( + &gUbaConfigDatabaseProtocolGuid, + NULL, + &UbaConfigProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DataLength =3D sizeof (IioUpdateTable); + if (SkuPersonalityType =3D=3D 1) { + Status =3D UbaConfigProtocol->GetData ( + UbaConfigProtocol, + &gPlatformIioConfigDataDxeGuid_1, + &IioUpdateTable, + &DataLength + ); + } else if (SkuPersonalityType =3D=3D 2) { + Status =3D UbaConfigProtocol->GetData ( + UbaConfigProtocol, + &gPlatformIioConfigDataDxeGuid_2, + &IioUpdateTable, + &DataLength + ); + } else if (SkuPersonalityType =3D=3D 3) { + Status =3D UbaConfigProtocol->GetData ( + UbaConfigProtocol, + &gPlatformIioConfigDataDxeGuid_3, + &IioUpdateTable, + &DataLength + ); + } else { + Status =3D UbaConfigProtocol->GetData ( + UbaConfigProtocol, + &gPlatformIioConfigDataDxeGuid, + &IioUpdateTable, + &DataLength + ); + } + if (EFI_ERROR (Status)) { + return Status; + } + + ASSERT (IioUpdateTable.Signature =3D=3D PLATFORM_IIO_CONFIG_UPDATE_SIGNA= TURE); + ASSERT (IioUpdateTable.Version =3D=3D PLATFORM_IIO_CONFIG_UPDATE_VERSION= ); + + *BifurcationTable =3D IioUpdateTable.IioBifurcationTablePtr; + *BifurcationEntries =3D (UINT8) (IioUpdateTable.IioBifurcationTableSize = / sizeof(IIO_BIFURCATION_DATA_ENTRY)); + + *SlotTable =3D IioUpdateTable.IioSlotTablePtr; + *SlotEntries =3D (UINT8)(IioUpdateTable.IioSlotTableSize / sizeof(IIO_SL= OT_CONFIG_DATA_ENTRY)); + + return EFI_SUCCESS; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaOprom= UpdateLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaOpro= mUpdateLib.c new file mode 100644 index 0000000000..922b7daaca --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaOpromUpdateL= ib.c @@ -0,0 +1,221 @@ +/** @file + + @copyright + Copyright 2013 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + + +BOOLEAN +PlatformCheckPcieRootPort ( + IN UINTN Bus, + IN UINT32 PcieSlotOpromBitMap + ) +{ + EFI_STATUS Status; + + UBA_CONFIG_DATABASE_PROTOCOL *UbaConfigProtocol =3D NULL; + UINTN DataLength =3D 0; + PLATFORM_OPTION_ROM_UPDATE_DATA OptionRomUpdateTable; + + Status =3D gBS->LocateProtocol ( + &gUbaConfigDatabaseProtocolGuid, + NULL, + &UbaConfigProtocol + ); + if (EFI_ERROR (Status)) { + return TRUE; + } + + DataLength =3D sizeof (OptionRomUpdateTable); + Status =3D UbaConfigProtocol->GetData ( + UbaConfigProtocol, + &gPlatformOptionRomUpdateConfigDataGui= d, + &OptionRomUpdateTable, + &DataLength + ); + if (EFI_ERROR (Status)) { + return TRUE; + } + + ASSERT (OptionRomUpdateTable.Signature =3D=3D PLATFORM_OPTION_ROM_UPDATE= _SIGNATURE); + ASSERT (OptionRomUpdateTable.Version =3D=3D PLATFORM_OPTION_ROM_UPDATE_V= ERSION); + + return OptionRomUpdateTable.CallCheckRootPort (Bus, PcieSlotOpromBitMap); +} + +EFI_STATUS +PlatformGetOptionRomTable ( + IN PC_PCI_OPTION_ROM_TABLE **OptionRomTable + ) +{ + EFI_STATUS Status; + + UBA_CONFIG_DATABASE_PROTOCOL *UbaConfigProtocol =3D NULL; + UINTN DataLength =3D 0; + PLATFORM_OPTION_ROM_UPDATE_DATA OptionRomUpdateTable; + + Status =3D gBS->LocateProtocol ( + &gUbaConfigDatabaseProtocolGuid, + NULL, + &UbaConfigProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DataLength =3D sizeof (OptionRomUpdateTable); + Status =3D UbaConfigProtocol->GetData ( + UbaConfigProtocol, + &gPlatformOptionRomUpdateConfigDataGui= d, + &OptionRomUpdateTable, + &DataLength + ); + if (EFI_ERROR (Status)) { + return Status; + } + + ASSERT (OptionRomUpdateTable.Signature =3D=3D PLATFORM_OPTION_ROM_UPDATE= _SIGNATURE); + ASSERT (OptionRomUpdateTable.Version =3D=3D PLATFORM_OPTION_ROM_UPDATE_V= ERSION); + + if (OptionRomUpdateTable.GetOptionRomTable =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + return OptionRomUpdateTable.GetOptionRomTable (OptionRomTable); +} + +EFI_STATUS +PlatformGetNicSetupConfigTable ( + IN NIC_SETUP_CONFIGURATION_STUCT **NicSetupConfigTable, + IN UINTN *NumOfConfig + ) +{ + EFI_STATUS Status; + + UBA_CONFIG_DATABASE_PROTOCOL *UbaConfigProtocol =3D NULL; + UINTN DataLength =3D 0; + PLATFORM_OPTION_ROM_UPDATE_DATA OptionRomUpdateTable; + + Status =3D gBS->LocateProtocol ( + &gUbaConfigDatabaseProtocolGuid, + NULL, + &UbaConfigProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DataLength =3D sizeof (OptionRomUpdateTable); + Status =3D UbaConfigProtocol->GetData ( + UbaConfigProtocol, + &gPlatformOptionRomUpdateConfigDataGui= d, + &OptionRomUpdateTable, + &DataLength + ); + if (EFI_ERROR (Status)) { + return Status; + } + + ASSERT (OptionRomUpdateTable.Signature =3D=3D PLATFORM_OPTION_ROM_UPDATE= _SIGNATURE); + ASSERT (OptionRomUpdateTable.Version =3D=3D PLATFORM_OPTION_ROM_UPDATE_V= ERSION); + + if (OptionRomUpdateTable.GetNicSetupConfigTable =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + return OptionRomUpdateTable.GetNicSetupConfigTable (NicSetupConfigTable,= NumOfConfig); +} + +EFI_STATUS +PlatformGetNicCapabilityTable ( + IN NIC_OPTIONROM_CAPBILITY_STRUCT **NicCapabilityTable, + IN UINTN *NumOfNicCapTable + ) +{ + EFI_STATUS Status; + + UBA_CONFIG_DATABASE_PROTOCOL *UbaConfigProtocol =3D NULL; + UINTN DataLength =3D 0; + PLATFORM_OPTION_ROM_UPDATE_DATA OptionRomUpdateTable; + + Status =3D gBS->LocateProtocol ( + &gUbaConfigDatabaseProtocolGuid, + NULL, + &UbaConfigProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DataLength =3D sizeof (OptionRomUpdateTable); + Status =3D UbaConfigProtocol->GetData ( + UbaConfigProtocol, + &gPlatformOptionRomUpdateConfigDataGui= d, + &OptionRomUpdateTable, + &DataLength + ); + if (EFI_ERROR (Status)) { + return Status; + } + + ASSERT (OptionRomUpdateTable.Signature =3D=3D PLATFORM_OPTION_ROM_UPDATE= _SIGNATURE); + ASSERT (OptionRomUpdateTable.Version =3D=3D PLATFORM_OPTION_ROM_UPDATE_V= ERSION); + + if (OptionRomUpdateTable.GetNicCapabilityTable =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + return OptionRomUpdateTable.GetNicCapabilityTable (NicCapabilityTable, N= umOfNicCapTable); +} + +EFI_STATUS +PlatformSetupPcieSlotNumber ( + OUT UINT8 *PcieSlotItemCtrl + ) +{ + EFI_STATUS Status; + + UBA_CONFIG_DATABASE_PROTOCOL *UbaConfigProtocol =3D NULL; + UINTN DataLength =3D 0; + PLATFORM_OPTION_ROM_UPDATE_DATA OptionRomUpdateTable; + + Status =3D gBS->LocateProtocol ( + &gUbaConfigDatabaseProtocolGuid, + NULL, + &UbaConfigProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DataLength =3D sizeof (OptionRomUpdateTable); + Status =3D UbaConfigProtocol->GetData ( + UbaConfigProtocol, + &gPlatformOptionRomUpdateConfigDataGui= d, + &OptionRomUpdateTable, + &DataLength + ); + if (EFI_ERROR (Status)) { + return Status; + } + + ASSERT (OptionRomUpdateTable.Signature =3D=3D PLATFORM_OPTION_ROM_UPDATE= _SIGNATURE); + ASSERT (OptionRomUpdateTable.Version =3D=3D PLATFORM_OPTION_ROM_UPDATE_V= ERSION); + + return OptionRomUpdateTable.SetupSlotNumber (PcieSlotItemCtrl); +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaPlatL= ib.inf b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaPlatLib.i= nf new file mode 100644 index 0000000000..aa5f43a8b5 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaPlatLib.inf @@ -0,0 +1,62 @@ +## @file +# +# @copyright +# Copyright 2014 - 2017 Intel Corporation.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D UbaPlatLib + FILE_GUID =3D 771FA963-A317-47aa-9D0B-186917B7D829 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D UbaPlatLib | DXE_DRIVER DXE_SMM_DRIVE= R DXE_RUNTIME_DRIVER + CONSTRUCTOR =3D InitializeDxeUbaPlatLib + +[sources] + UbaAcpiUpdateLib.c + UbaOpromUpdateLib.c + UbaSmbiosUpdateLib.c + UbaIioConfigLib.c + UbaSlotUpdateLib.c + DxeUbaUsbOcUpdateLib.c + DxeUbaGpioPlatformConfigLib.c + DxeUbaSystemBoardInfoLib.c + DxeUbaSystemConfigUpdateLib.c + UbaFpkConfigLib.c + +[LibraryClasses] + BaseLib + DebugLib + BaseMemoryLib + MemoryAllocationLib + UefiLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + +[Packages] + MdePkg/MdePkg.dec + WhitleySiliconPkg/CpRcPkg.dec + WhitleySiliconPkg/SiliconPkg.dec + WhitleySiliconPkg/WhitleySiliconPkg.dec + WhitleyOpenBoardPkg/PlatformPkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[Protocols] + gUbaConfigDatabaseProtocolGuid + gEfiSmbiosProtocolGuid + gEfiPciIoProtocolGuid + gDynamicSiLibraryProtocolGuid ## CONSUMES + +[Guids] + gEfiEndOfDxeEventGroupGuid + gSystemBoardInfoConfigDataGuid + +[FixedPcd] + gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuSocketCount + gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuCoreCount + +[Depex] + gDynamicSiLibraryProtocolGuid diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSlotU= pdateLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSlotU= pdateLib.c new file mode 100644 index 0000000000..1d39cb7d6f --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSlotUpdateLi= b.c @@ -0,0 +1,114 @@ +/** @file + UbaSlotUpdateLib implementation. + + @copyright + Copyright 2012 - 2016 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +EFI_STATUS +PlatformGetSlotTableData ( + IN OUT IIO_BROADWAY_ADDRESS_DATA_ENTRY **BroadwayTable, + IN OUT UINT8 *IOU2Setting, + IN OUT UINT8 *FlagValue + ) +{ + EFI_STATUS Status; + UBA_CONFIG_DATABASE_PROTOCOL *UbaConfigProtocol =3D NULL; + UINTN DataLength =3D 0; + PLATFORM_SLOT_UPDATE_TABLE IioSlotUpdateTable; + + Status =3D gBS->LocateProtocol ( + &gUbaConfigDatabaseProtocolGuid, + NULL, + &UbaConfigProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DataLength =3D sizeof(IioSlotUpdateTable); + Status =3D UbaConfigProtocol->GetData ( + UbaConfigProtocol, + &gPlatformSlotDataDxeGuid, + &IioSlotUpdateTable, + &DataLength + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + ASSERT (IioSlotUpdateTable.Signature =3D=3D PLATFORM_SLOT_UPDATE_SIGNATU= RE); + ASSERT (IioSlotUpdateTable.Version =3D=3D PLATFORM_SLOT_UPDATE_VERSION= ); + + *BroadwayTable =3D IioSlotUpdateTable.BroadwayTablePtr; + *IOU2Setting =3D IioSlotUpdateTable.GetIOU2Setting (*IOU2Setting); + *FlagValue =3D IioSlotUpdateTable.FlagValue; + return Status; +} + +EFI_STATUS +PlatformGetSlotTableData2 ( + IN OUT IIO_BROADWAY_ADDRESS_DATA_ENTRY **BroadwayTable, + IN OUT UINT8 *IOU0Setting, + IN OUT UINT8 *FlagValue, + IN OUT UINT8 *IOU2Setting, + IN UINT8 SkuPersonalityType + ) +{ + EFI_STATUS Status; + UBA_CONFIG_DATABASE_PROTOCOL *UbaConfigProtocol =3D NULL; + UINTN DataLength =3D 0; + PLATFORM_SLOT_UPDATE_TABLE2 IioSlotUpdateTable; + + Status =3D gBS->LocateProtocol ( + &gUbaConfigDatabaseProtocolGuid, + NULL, + &UbaConfigProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DataLength =3D sizeof(IioSlotUpdateTable); + if ((SkuPersonalityType =3D=3D 1) || (SkuPersonalityType =3D=3D 3)) { + Status =3D UbaConfigProtocol->GetData ( + UbaConfigProtocol, + &gPlatformSlotDataDxeGuid2_1, + &IioSlotUpdateTable, + &DataLength + ); + } else { + Status =3D UbaConfigProtocol->GetData ( + UbaConfigProtocol, + &gPlatformSlotDataDxeGuid2, + &IioSlotUpdateTable, + &DataLength + ); + } + if (EFI_ERROR (Status)) { + return Status; + } + + ASSERT (IioSlotUpdateTable.Signature =3D=3D PLATFORM_SLOT_UPDATE_SIGNATU= RE); + ASSERT (IioSlotUpdateTable.Version =3D=3D PLATFORM_SLOT_UPDATE_VERSION= ); + + *BroadwayTable =3D IioSlotUpdateTable.BroadwayTablePtr; + *IOU0Setting =3D IioSlotUpdateTable.GetIOU0Setting (*IOU0Setting); + *FlagValue =3D IioSlotUpdateTable.FlagValue; + *IOU2Setting =3D IioSlotUpdateTable.GetIOU2Setting (SkuPersonalityType= , *IOU2Setting); + + return Status; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSmbio= sUpdateLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSmb= iosUpdateLib.c new file mode 100644 index 0000000000..5d4ed55969 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/UbaPlatLib/UbaSmbiosUpdate= Lib.c @@ -0,0 +1,663 @@ +/** @file + UbaSmbiosUpdateLib implementation. + + @copyright + Copyright 2012 - 2017 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define SMBIOS_TYPE_MAX_LENGTH 0x300 + +/** + Provide the RegData and register a callback for dynamic update SMBIOS da= ta. + + @param RegData Callback register data. + + @retval EFI_NOT_FOUND Data log protocol not found. + @retval EFI_OUT_OF_RESOURCES Data was not logged due to lack of syste= m resources. + @retval EFI_SUCCESS Data have been updated successfully. + +**/ +EFI_STATUS +PlatformRegisterSmbiosUpdate ( + IN SMBIOS_UPDATE_DATA *RegData + ) +{ + EFI_STATUS Status; + STATIC UBA_CONFIG_DATABASE_PROTOCOL *UbaConfigProtocol =3D NULL; + + if (UbaConfigProtocol =3D=3D NULL) { + + Status =3D gBS->LocateProtocol ( + &gUbaConfigDatabaseProtocolGuid, + NULL, + &UbaConfigProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + + RegData->Signature =3D PLATFORM_SMBIOS_UPDATE_SIGNATURE; + RegData->Version =3D PLATFORM_SMBIOS_UPDATE_VERSION; + + Status =3D UbaConfigProtocol->AddData ( + UbaConfigProtocol, + &gPlatformSmbiosConfigDataGuid, + RegData, + sizeof(SMBIOS_UPDATE_DATA) + ); + return Status; +} + +/** + Update a String for a filled SMBIOS data structure, the structure must b= e filled + before update string. + This function update a string indicated by StringNumber to the tail of S= MBIOS + structure. + + @param Smbios SMBIOS structure data buffer pointer. + @param BufferSize SMBIOS structure data buffer size. + @param StringNumber The string index number of SMBIOS struct= ure. + @param String String want to update. + + @retval EFI_OUT_OF_RESOURCES No enough memory for this action. + @retval EFI_SUCCESS String updated successfully. + +**/ +EFI_STATUS +PlatformSmbiosUpdateString ( + IN OUT SMBIOS_STRUCTURE_POINTER Smbios, + IN UINTN BufferSize, + IN UINTN StringNumber, + IN CHAR16 *String + ) +{ + EFI_STATUS Status; + CHAR8 *AsciiString =3D NULL; + + UINTN InputStrLen; + UINTN TargetStrLen; + UINTN StrIndex; + UINTN TargetStrOffset; + CHAR8 *StrStart; + + SMBIOS_STRUCTURE_POINTER NewSmbiosPtr; + + UINTN OrigSize =3D 0; + UINTN NewSize =3D 0; + UINTN StringSize =3D 0; + + StringSize =3D StrSize (String); + AsciiString =3D AllocateZeroPool (StringSize); + ASSERT (AsciiString !=3D NULL); + if (AsciiString =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + UnicodeStrToAsciiStrS (String, AsciiString, StringSize); + InputStrLen =3D AsciiStrLen (AsciiString); + + Status =3D PlatformSmbiosGetTypeLength (Smbios, &OrigSize); + + // + // Point to unformed string section + // + StrStart =3D (CHAR8 *) Smbios.Hdr + Smbios.Hdr->Length; + for (StrIndex =3D 1, TargetStrOffset =3D 0; StrIndex < StringNumber; Str= Start++, TargetStrOffset++) { + // + // A string ends in 00h + // + if (*StrStart =3D=3D 0) { + StrIndex++; + } + } + + // + // Now we get the string target + // + TargetStrLen =3D AsciiStrLen(StrStart); + if (InputStrLen =3D=3D TargetStrLen) { + Status =3D AsciiStrCpyS(StrStart, TargetStrLen + 1, AsciiString); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return Status; + } + return EFI_SUCCESS; + } + + // + // Original string buffer size is not exactly match input string length. + // Re-allocate buffer is needed. + // + NewSmbiosPtr.Hdr =3D AllocateZeroPool (SMBIOS_TYPE_MAX_LENGTH); + if (NewSmbiosPtr.Hdr =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Copy SMBIOS structure and optional strings. + // + CopyMem (NewSmbiosPtr.Hdr, Smbios.Hdr, Smbios.Hdr->Length + TargetStrOff= set); + CopyMem ((CHAR8*)NewSmbiosPtr.Hdr + Smbios.Hdr->Length + TargetStrOffset= , AsciiString, InputStrLen + 1); + CopyMem ((CHAR8*)NewSmbiosPtr.Hdr + Smbios.Hdr->Length + TargetStrOffset= + InputStrLen + 1, + (CHAR8*)Smbios.Hdr + Smbios.Hdr->Length + TargetStrOffset + Tar= getStrLen + 1, + OrigSize - Smbios.Hdr->Length - TargetStrOffset - TargetStrLen = - 1); + + Status =3D PlatformSmbiosGetTypeLength (NewSmbiosPtr, &NewSize); + CopyMem (Smbios.Hdr, NewSmbiosPtr.Hdr, NewSize); + + FreePool (NewSmbiosPtr.Hdr); + FreePool (AsciiString); + + return EFI_SUCCESS; +} + +/** + Get SMBIOS data structure length, include the string in tail. + + @param Smbios SMBIOS structure data buffer pointer. + @param TypeSize SMBIOS structure size. + + @retval EFI_INVALID_PARAMETER Input paramter invalid. + @retval EFI_SUCCESS Caculate data structure size successfull= y. + +**/ +EFI_STATUS +PlatformSmbiosGetTypeLength ( + IN OUT SMBIOS_STRUCTURE_POINTER Smbios, + IN OUT UINTN *TypeSize + ) +{ + UINTN FullSize; + UINTN StrLen; + UINTN MaxLen; + INT8* CharInStr; + + if (TypeSize =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + FullSize =3D Smbios.Hdr->Length; + CharInStr =3D (INT8*)Smbios.Hdr + Smbios.Hdr->Length; + *TypeSize =3D FullSize; + StrLen =3D 0; + + // + // look for the two consecutive zeros, check the string limit by the way. + // + while (*CharInStr !=3D 0 || *(CharInStr+1) !=3D 0) { + if (*CharInStr =3D=3D 0) { + *TypeSize +=3D 1; + CharInStr++; + } + + MaxLen =3D SMBIOS_STRING_MAX_LENGTH; + for (StrLen =3D 0 ; StrLen < MaxLen; StrLen++) { + if (*(CharInStr+StrLen) =3D=3D 0) { + break; + } + } + + if (StrLen =3D=3D MaxLen) { + return EFI_INVALID_PARAMETER; + } + + // + // forward the pointer + // + CharInStr +=3D StrLen; + *TypeSize +=3D StrLen; + } + + // + // count ending two zeros. + // + *TypeSize +=3D 2; + + return EFI_SUCCESS; +} + +/** + Add a new SMBIOS structure into SMBIOS database. + + @param Smbios SMBIOS structure data buffer pointer. + + @retval EFI_NOT_FOUND SMBIOS protocol not installed. + @retval EFI_SUCCESS Add data structure successfully. + +**/ +EFI_STATUS +PlatformSmbiosAddNew ( + IN SMBIOS_STRUCTURE_POINTER SmbiosPtr + ) +{ + EFI_STATUS Status; + + STATIC EFI_SMBIOS_PROTOCOL *Smbios =3D NULL; + EFI_SMBIOS_HANDLE SmbiosHandle; + + if (Smbios =3D=3D NULL) { + Status =3D gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &Smbios= ); + if (EFI_ERROR (Status)) { + return Status; + } + } + + SmbiosHandle =3D SMBIOS_HANDLE_PI_RESERVED; + Status =3D Smbios->Add (Smbios, NULL, &SmbiosHandle, (EFI_SMBIOS_TABLE_H= EADER*)SmbiosPtr.Hdr); + + return EFI_SUCCESS; +} + +/** + Get the number of instance of SMBIOS type structure in SMBIOS database. + return 0 means no instance for this type now. + + @param Type SMBIOS type. + + @retval Count Number of instance. + +**/ +UINTN +PlatformSmbiosGetInstanceCount ( + IN UINT8 Type + ) +{ + EFI_STATUS Status; + + STATIC EFI_SMBIOS_PROTOCOL *Smbios =3D NULL; + EFI_SMBIOS_TABLE_HEADER *SmbiosRecord; + EFI_SMBIOS_HANDLE SmbiosHandle; + EFI_SMBIOS_TYPE SmbiosType; + + UINTN Count =3D 0; + + if (Smbios =3D=3D NULL) { + Status =3D gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &Smbios= ); + if (EFI_ERROR (Status)) { + return Status; + } + } + + SmbiosHandle =3D SMBIOS_HANDLE_PI_RESERVED; + SmbiosType =3D Type; + + do { + Status =3D Smbios->GetNext (Smbios, &SmbiosHandle, &SmbiosType, &Smbio= sRecord, NULL); + if (!EFI_ERROR (Status) && (SmbiosHandle !=3D SMBIOS_HANDLE_PI_RESERVE= D)) { + Count ++; + } + } while (!EFI_ERROR (Status) && (SmbiosHandle !=3D SMBIOS_HANDLE_PI_RESE= RVED)); + + return Count; +} + +/** + Get SMBIOS type data structure in SMBIOS database. + + This function give you a pointer of SMBIOS structure directly in the dat= abase, you can update + the value in formated structure area and it's take affect immediately, b= ut never directly or + call PlatformSmbiosUpdateString to edit the string in this buffer, + use PlatformSmbiosGetEditCopy->PlatformSmbiosUpdateType instead. + + One of the SmbiosPtr or Handle must be valid value. + + @param Type SMBIOS type. + @param Instance The instance of this type. + @param SmbiosPtr Optional parameter, on input, pass a poi= nter of SMBIOS_STRUCTURE_POINTER + to this function. + On output, return the SMBIOS data pointe= r in SmbiosPtr. + @param Handle Optional parameter, on input, pass a poi= nter of Handle. + On output, return the SMBIOS data handle= value + + @retval EFI_INVALID_PARAMETER Both the SmbiosPtr and Handle is NULL. + @retval EFI_NOT_FOUND SMBIOS protocol not installed. + @retval EFI_SUCCESS Get structure data successfully. + +**/ +EFI_STATUS +PlatformSmbiosGetInstance ( + IN UINT8 Type, + IN UINTN Instance, + IN OUT SMBIOS_STRUCTURE_POINTER *SmbiosPtr, + IN OUT UINT16 *Handle + ) +{ + EFI_STATUS Status; + + STATIC EFI_SMBIOS_PROTOCOL *Smbios =3D NULL; + EFI_SMBIOS_TABLE_HEADER *SmbiosRecord; + EFI_SMBIOS_HANDLE SmbiosHandle; + EFI_SMBIOS_TYPE SmbiosType; + + UINTN Count =3D 0; + + if ((SmbiosPtr =3D=3D NULL) && (Handle =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (Smbios =3D=3D NULL) { + Status =3D gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &Smbios= ); + if (EFI_ERROR (Status)) { + return Status; + } + } + + SmbiosHandle =3D SMBIOS_HANDLE_PI_RESERVED; + SmbiosType =3D Type; + + do { + Status =3D Smbios->GetNext (Smbios, &SmbiosHandle, &SmbiosType, &Smbio= sRecord, NULL); + if (!EFI_ERROR (Status) && (SmbiosHandle !=3D SMBIOS_HANDLE_PI_RESERVE= D)) { + + if (++Count =3D=3D Instance) { + + if (SmbiosPtr !=3D NULL) { + (*SmbiosPtr).Hdr =3D (SMBIOS_STRUCTURE*)SmbiosRecord; + } + + if (Handle !=3D NULL) { + *Handle =3D SmbiosHandle; + } + + return EFI_SUCCESS; + } + } + } while (!EFI_ERROR (Status) && (SmbiosHandle !=3D SMBIOS_HANDLE_PI_RESE= RVED)); + + return EFI_NOT_FOUND; +} + +/** + Get a copy of SMBIOS type structure data in SMBIOS database. + Must allocate memory large enough first, then call this function to get = the copy. + + @param Type SMBIOS type. + @param Instance The instance of this type. + @param SmbiosPtr A valid buffer pointer which SMBIOS data= will copy to this buffer. + + @retval EFI_NOT_FOUND SMBIOS protocol not installed. + @retval EFI_SUCCESS Get structure data successfully. + +**/ +EFI_STATUS +PlatformSmbiosGetEditCopy ( + IN UINT8 Type, + IN UINTN Instance, + IN OUT SMBIOS_STRUCTURE_POINTER SmbiosPtr + ) +{ + EFI_STATUS Status; + SMBIOS_STRUCTURE_POINTER NewSmbiosPtr; + UINTN Size; + + Status =3D PlatformSmbiosGetInstance (Type, Instance, &NewSmbiosPtr, NUL= L); + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D PlatformSmbiosGetTypeLength (NewSmbiosPtr, &Size); + if (EFI_ERROR (Status)) { + return Status; + } + + CopyMem (SmbiosPtr.Hdr, NewSmbiosPtr.Hdr, Size); + + return EFI_SUCCESS; +} + +/** + Update a string which in SMBIOS database. + The data structure which string belong to must installed before. + + @param Type SMBIOS type. + @param Instance The instance of this type. + @param StringNumber The string number. + @param String The string want to update. + + @retval EFI_NOT_FOUND SMBIOS protocol not installed. + @retval EFI_SUCCESS Update data successfully. + +**/ +EFI_STATUS +PlatformSmbiosUpdateInstalledString ( + IN UINT8 Type, + IN UINTN Instance, + IN UINTN StringNumber, + IN CHAR16 *String + ) +{ + EFI_STATUS Status; + STATIC EFI_SMBIOS_PROTOCOL *Smbios =3D NULL; + EFI_SMBIOS_HANDLE SmbiosHandle; + + CHAR8 *AsciiStr =3D NULL; + UINTN StringSize =3D 0; + + if (Smbios =3D=3D NULL) { + Status =3D gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &Smbios= ); + if (EFI_ERROR (Status)) { + return Status; + } + } + + StringSize =3D StrSize (String); + AsciiStr =3D AllocateZeroPool (StringSize); + UnicodeStrToAsciiStrS (String, AsciiStr, StringSize); + + Status =3D PlatformSmbiosGetInstance (Type, Instance, NULL, &SmbiosHandl= e); + if (!EFI_ERROR (Status)) { + Status =3D Smbios->UpdateString (Smbios, &SmbiosHandle, &StringNumber,= AsciiStr); + } + + FreePool (AsciiStr); + + return Status; +} + +/** + Remove a SMBIOS instance in SMBIOS database. + + @param Type SMBIOS type. + @param Instance The instance of this type. + + @retval EFI_NOT_FOUND SMBIOS protocol not installed. + @retval EFI_SUCCESS Remove data successfully. + +**/ +EFI_STATUS +PlatformSmbiosRemoveType ( + IN UINT8 Type, + IN UINTN Instance + ) +{ + EFI_STATUS Status; + + STATIC EFI_SMBIOS_PROTOCOL *Smbios =3D NULL; + EFI_SMBIOS_HANDLE SmbiosHandle; + + if (Smbios =3D=3D NULL) { + Status =3D gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &Smbios= ); + if (EFI_ERROR (Status)) { + return Status; + } + } + + Status =3D PlatformSmbiosGetInstance (Type, Instance, NULL, &SmbiosHandl= e); + if (!EFI_ERROR (Status)) { + Status =3D Smbios->Remove (Smbios, SmbiosHandle); + } + + return Status; +} + +/** + Remove all the instance of specific SMBIOS type in SMBIOS database. + + @param Type SMBIOS type. + + @retval EFI_NOT_FOUND SMBIOS protocol not installed. + @retval EFI_SUCCESS Remove data successfully. + +**/ +EFI_STATUS +PlatformSmbiosRemoveAll ( + IN UINT8 Type + ) +{ + EFI_STATUS Status; + UINTN Count; + UINTN Index; + + Count =3D PlatformSmbiosGetInstanceCount (Type); + + for (Index =3D 0; Index < Count; Index++) { + Status =3D PlatformSmbiosRemoveType (Type, 1); + if (EFI_ERROR (Status)) { + return Status; + } + } + + return EFI_SUCCESS; +} + +/** + Update SMBIOS data structure in database with new structure data. + + @param Type SMBIOS type. + @param Instance The instance of this type. + @param SmbiosPtr A valid buffer pointer which new SMBIOS = data stored. + + @retval EFI_NOT_FOUND SMBIOS protocol not installed. + @retval EFI_SUCCESS Update data successfully. + +**/ +EFI_STATUS +PlatformSmbiosUpdateType ( + IN UINT8 Type, + IN UINTN Instance, + IN SMBIOS_STRUCTURE_POINTER SmbiosPtr + ) +{ + EFI_STATUS Status; + STATIC EFI_SMBIOS_PROTOCOL *Smbios =3D NULL; + EFI_SMBIOS_HANDLE SmbiosHandle; + + if (Smbios =3D=3D NULL) { + Status =3D gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &Smbios= ); + if (EFI_ERROR (Status)) { + return Status; + } + } + + Status =3D PlatformSmbiosGetInstance (Type, Instance, NULL, &SmbiosHandl= e); + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D PlatformSmbiosRemoveType (Type, Instance); + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D PlatformSmbiosAddNew (SmbiosPtr); + if (EFI_ERROR (Status)) { + return Status; + } + + return Status; +} + +/** + Implement the dynamic SMBIOS data update. + + @param UpdateType Immediately update or delay update at BD= S. + + @retval EFI_SUCCESS Update successfully. + +**/ +EFI_STATUS +DispatchSmbiosDynamicUpdate ( + IN SmbiosUpdateType UpdateType + ) +{ + EFI_STATUS Status; + + UBA_CONFIG_DATABASE_PROTOCOL *UbaConfigProtocol =3D NULL; + UINTN DataLength =3D 0; + SMBIOS_UPDATE_DATA RegData; + + Status =3D gBS->LocateProtocol ( + &gUbaConfigDatabaseProtocolGuid, + NULL, + &UbaConfigProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DataLength =3D sizeof (SMBIOS_UPDATE_DATA); + Status =3D UbaConfigProtocol->GetData ( + UbaConfigProtocol, + &gPlatformSmbiosConfigDataGuid, + &RegData, + &DataLength + ); + if (EFI_ERROR (Status)) { + return Status; + } + + ASSERT (RegData.Signature =3D=3D PLATFORM_SMBIOS_UPDATE_SIGNATURE); + ASSERT (RegData.Version =3D=3D PLATFORM_SMBIOS_UPDATE_VERSION); + + // + // Check for updatetype match. + // + if ((RegData.UpdateType =3D=3D UpdateType) && (RegData.CallUpdate !=3D N= ULL)) { + // + // Invoke the callback and update every instance of this type + // + Status =3D RegData.CallUpdate (); + } + + return EFI_SUCCESS; +} + +/** + Function provide to DXE driver, which initial the dynamic update. + + @param NULL + + @retval EFI_NOT_FOUND Required protocol not found. + @retval EFI_SUCCESS Init successfully. + +**/ +EFI_STATUS +PlatformInitSmbiosUpdate ( + VOID + ) +{ + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "UBA SMBIOS Update Library: PlatformInitSmbiosUpdate= !\n")); + Status =3D DispatchSmbiosDynamicUpdate (SmbiosDelayUpdate); + + return Status; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaCommon.dsc b/Platfor= m/Intel/WhitleyOpenBoardPkg/Uba/UbaCommon.dsc index a3e961aa76..28f75477c4 100644 --- a/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaCommon.dsc +++ b/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaCommon.dsc @@ -11,6 +11,9 @@ UbaPlatLib|$(RP_PKG)/Library/PeiUbaPlatLib/PeiUbaPlatLib.inf UbaGpioInitLib|$(RP_PKG)/Library/UbaGpioInitLib/UbaGpioInitLib.inf =20 +[LibraryClasses.X64] + UbaPlatLib|$(RP_PKG)/Library/UbaPlatLib/UbaPlatLib.inf + [Components.IA32] $(RP_PKG)/Uba/CfgDb/Pei/CfgDbPei.inf $(RP_PKG)/Uba/UbaUpdatePcds/Pei/UpdatePcdsPei.inf --=20 2.27.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#87427): https://edk2.groups.io/g/devel/message/87427 Mute This Topic: https://groups.io/mt/89698849/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat May 18 21:45:23 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+87428+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+87428+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1646952114; cv=none; d=zohomail.com; s=zohoarc; b=OU9fjz+OoUGg5ZJsLXJKlIJrNDH88xa5duV+xFBZS9zErc5gz0lGLDBmYoVij4k7BeTOJ888LFumIMcXVHotuPLepw/zbj+5oPuqvKZlFmibtxgqTf4dL4naz8AdJuLWpttyUgV4uoOkrf16ILO20cQZSrvNbQdWlpj0BvR0Eng= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1646952114; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=8+bxBrGBLMyCttM7S7jxn0GRwtgrUK5yey4J0BO1bpE=; b=cESiMdSa4Q4S2c7+uAdAgvUPPFqeCZxypw6vAa6TGl1+UIxGyWubctliBr3jxvL7cIn0So4ThvaRfJI6NOU2P1PmvIUm67Zo7+NbD1DhMdl7bk/+wvPIe0W4XcY9ES0Ojaq/ZcdBdEDywdvUcki7kwP2BTxiKaqqjsvwIZkDQI4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+87428+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1646952114266642.6097781775103; Thu, 10 Mar 2022 14:41:54 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id h3yDYY1788612xhLiDq21ca6; Thu, 10 Mar 2022 14:41:53 -0800 X-Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mx.groups.io with SMTP id smtpd.web12.860.1646952112302807460 for ; Thu, 10 Mar 2022 14:41:52 -0800 X-IronPort-AV: E=McAfee;i="6200,9189,10282"; a="316121251" X-IronPort-AV: E=Sophos;i="5.90,171,1643702400"; d="scan'208";a="316121251" X-Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2022 14:41:34 -0800 X-IronPort-AV: E=Sophos;i="5.90,171,1643702400"; d="scan'208";a="644643370" X-Received: from iworam-desk.amr.corp.intel.com ([10.7.150.60]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2022 14:41:34 -0800 From: "Oram, Isaac W" To: devel@edk2.groups.io Cc: Nate DeSimone , Chasel Chiu Subject: [edk2-devel][edk2-platforms][PATCH V1 5/9] WhitleyOpenBoardPkg/PlatformSpecificAcpiTableLib: Add library Date: Thu, 10 Mar 2022 14:41:10 -0800 Message-Id: <0477469fab21ad96740518f5e13aa678891bd0d3.1646951441.git.isaac.w.oram@intel.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,isaac.w.oram@intel.com X-Gm-Message-State: a3Y5UHLtrCeAfijRDtknlmdIx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1646952113; bh=PiZlyfVTYxiTMIhsr2pq8anVYOe3TyI/i0P/TgWTD+M=; h=Cc:Date:From:Reply-To:Subject:To; b=GSfyGFFhKWipQLJOKhgmLF0Kfyvg18+BXm8QkdLOE+qCNK6CTdZArs45PQ6HZzs+7Jb UKko+OH2ramsCB7v6vZQKuL+xVe7vZDYpxCuUab3IARUOos/uB/jpCBDnumzgA6iEjQW+ ZyyPA1Acdo/BwoiYLkfBTPeWDajZp89w87k= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1646952115852100015 Content-Type: text/plain; charset="utf-8" Enables boards to modify the AcpiPlatform driver behaviors. Cc: Nate DeSimone Cc: Chasel Chiu Signed-off-by: Isaac Oram Reviewed-by: Nate DeSimone --- Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformSpecificAcpiTab= leLib.h | 129 ++++++++++++++++++++ Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNul= l/AcpiPlatformLibSpcrNull.c | 23 ++++ Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNul= l/PlatformSpecificAcpiTableLibNull.c | 50 ++++++++ Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNul= l/PlatformSpecificAcpiTableLibNull.inf | 27 ++++ Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc = | 1 + 5 files changed, 230 insertions(+) diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformSpe= cificAcpiTableLib.h b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/Pl= atformSpecificAcpiTableLib.h new file mode 100644 index 0000000000..a260703274 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/PlatformSpecificAc= piTableLib.h @@ -0,0 +1,129 @@ +/** @file + This library provides a set of platform only ACPI tables and functions. + + @copyright + Copyright 2012 - 2020 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _PLATFORM_SPECIFIC_ACPI_TABLE_LIB_H_ +#define _PLATFORM_SPECIFIC_ACPI_TABLE_LIB_H_ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/** + This function will check ACPI Table is active or not active. + This allows boards to prevent publication of unused tables. + + @param Table - The table to check + + @retval EFI_SUCCESS - The Table is active. + +**/ +EFI_STATUS +PlatformAcpiReportHooksTableIsActive ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ); + +/** + This function will patch to update platform ACPI Table information. + + @param [in, out] Table The table to be udated. + + @retval EFI_SUCCESS - The function completed successfully. + +**/ +EFI_STATUS +PatchPlatformSpecificAcpiTableHooks ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ); + +/** + This function will patch to update SPCR Table information. + + @param [in, out] Table The table to be udated. + + @retval EFI_SUCCESS - The function completed successfully. + +**/ +EFI_STATUS +PatchSpcrAcpiTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ); + +/** + Update the HMAT table. + + @param [in, out] Table The table to be udated. + + @retval EFI SUCCESS Procedure returned successfully. +**/ +EFI_STATUS +PatchHmatAcpiTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ); + +/** + Update the PMTT ACPI table + + @param [in, out] Table The table to be udated. + + @retval EFI_SUCCESS - Returns Success + +**/ +EFI_STATUS +PatchPlatformMemoryTopologyTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ); + +/** + Update the MSCT ACPI table + + @param [in, out] Table The table to be udated. + + @retval EFI_SUCCESS - Returns Success + +**/ +EFI_STATUS +PatchMsctAcpiTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ); + +/** + + Update the MIGT ACPI table + + @param [in, out] Table The table to be udated. + + @retval EFI_SUCCESS - Returns Success + +**/ +EFI_STATUS +PatchMigtAcpiTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ); + +/** + Update the BDAT ACPI table: Multiple instances of the BDAT DATA HOB are = placed into one contiguos memory range + + @param [in, out] Table The table to be udated. + + @retval EFI_SUCCESS - Returns Success + +**/ +EFI_STATUS +PatchBdatAcpiTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ); + +#endif diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcp= iTableLibNull/AcpiPlatformLibSpcrNull.c b/Platform/Intel/WhitleyOpenBoardPk= g/Library/PlatformSpecificAcpiTableLibNull/AcpiPlatformLibSpcrNull.c new file mode 100644 index 0000000000..0f4ffcf86f --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableL= ibNull/AcpiPlatformLibSpcrNull.c @@ -0,0 +1,23 @@ +/** @file + ACPI Platform Driver Hooks + + @copyright + Copyright 1996 - 2016 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// Statements that include other files +// +#include + +EFI_STATUS +PatchSpcrAcpiTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + EFI_STATUS Status =3D EFI_SUCCESS; + + return Status; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcp= iTableLibNull/PlatformSpecificAcpiTableLibNull.c b/Platform/Intel/WhitleyOp= enBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTab= leLibNull.c new file mode 100644 index 0000000000..74bce3141d --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableL= ibNull/PlatformSpecificAcpiTableLibNull.c @@ -0,0 +1,50 @@ +/** @file + Hooks for Platform populate different function and Platform only ACPI T= able. + + @copyright + Copyright 2013 - 2019 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include + +/** + This function will check ACPI Table is active or not active. + + @param [in, out] Table The table to be udated. + + @retval EFI_SUCCESS - The Table is active. + +**/ +EFI_STATUS +PlatformAcpiReportHooksTableIsActive ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + EFI_ACPI_DESCRIPTION_HEADER *TableHeader; + + TableHeader =3D (EFI_ACPI_DESCRIPTION_HEADER *) Table; + if (TableHeader->Signature =3D=3D EFI_ACPI_6_2_SERVER_PLATFORM_MANAGEMEN= T_INTERFACE_TABLE_SIGNATURE) { + return EFI_NOT_FOUND; + } + return EFI_SUCCESS; +} + +/** + + This function will patch to update platform level Acpi Table information. + + @param [in, out] Table The table to be udated. + + @retval EFI_SUCCESS - The function completed successfully. + +**/ +EFI_STATUS +PatchPlatformSpecificAcpiTableHooks ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + return EFI_SUCCESS; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcp= iTableLibNull/PlatformSpecificAcpiTableLibNull.inf b/Platform/Intel/Whitley= OpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiT= ableLibNull.inf new file mode 100644 index 0000000000..48359b6bf5 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableL= ibNull/PlatformSpecificAcpiTableLibNull.inf @@ -0,0 +1,27 @@ +## @file +# Hooks to deactive or active platform ACPI Tables and patch platform only= ACPI Table. +# +# @copyright +# Copyright 2012 - 2018 Intel Corporation.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D PlatformSpecificAcpiTableLibNull + FILE_GUID =3D 6EF9D22E-89E7-45c7-8A3F-8D0207A084E4 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D PlatformSpecificAcpiTableLibNull + +[sources] + PlatformSpecificAcpiTableLibNull.c + AcpiPlatformLibSpcrNull.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + WhitleyOpenBoardPkg/PlatformPkg.dec + WhitleySiliconPkg/SiliconPkg.dec + WhitleySiliconPkg/CpRcPkg.dec diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc b/Platform/= Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc index 9cdb5bc2f6..2ac4a81e81 100644 --- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc +++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc @@ -619,6 +619,7 @@ PlatformOpromPolicyLib|$(RP_PKG)/Library/PlatformOpromPolicyLibNull/Plat= formOpromPolicyLibNull.inf VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf CrcLib|WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf + PlatformSpecificAcpiTableLib|WhitleyOpenBoardPkg/Library/PlatformSpecifi= cAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.inf =20 [LibraryClasses.Common.SEC, LibraryClasses.Common.PEI_CORE, LibraryClasses= .Common.PEIM] FspWrapperApiLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFs= pWrapperApiLib.inf --=20 2.27.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#87428): https://edk2.groups.io/g/devel/message/87428 Mute This Topic: https://groups.io/mt/89698850/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat May 18 21:45:23 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+87429+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+87429+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1646952115; cv=none; d=zohomail.com; s=zohoarc; b=bT+qbu+06eU+YVJ8OctVks74gi8IdXgdS/ZKVkjLvJ7V0+vSzNUSJwrre1IUxuLNq/wJVuQSaZBI6FUrF4U1rTR29wXbk7e+7HsUxUdSkqBV9lZTHgCwuDS/XIEg+ZiUSWfEG2d2p9cUpiQV4n0sLMewXdB4qNNHFZFugC3cGWg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1646952115; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=lhiY2xPqUw44pvDu2w87veQR/qFrny56MRKa4/YTIek=; b=da96njllz8pngxvJAiQR0+GPRptxGW+qNHBYCTFvTVUdr9/I+zYo0QqcYye8dRZ1hvf6cj/BCkngdAJuqjMifabUfMhepCQIjIZbLHixdh9esMheOcQaMWsnO8ko/x3ZytTpNbwZkzJUAaYu5NrnEuLy2da0c15udgrYI6zLYvM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+87429+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1646952115009128.37402137735558; Thu, 10 Mar 2022 14:41:55 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id zVI7YY1788612xv6E0loyXwY; Thu, 10 Mar 2022 14:41:54 -0800 X-Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mx.groups.io with SMTP id smtpd.web12.859.1646952111350461854 for ; Thu, 10 Mar 2022 14:41:52 -0800 X-IronPort-AV: E=McAfee;i="6200,9189,10282"; a="316121252" X-IronPort-AV: E=Sophos;i="5.90,171,1643702400"; d="scan'208";a="316121252" X-Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2022 14:41:34 -0800 X-IronPort-AV: E=Sophos;i="5.90,171,1643702400"; d="scan'208";a="644643376" X-Received: from iworam-desk.amr.corp.intel.com ([10.7.150.60]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2022 14:41:34 -0800 From: "Oram, Isaac W" To: devel@edk2.groups.io Cc: Nate DeSimone , Chasel Chiu Subject: [edk2-devel][edk2-platforms][PATCH V1 6/9] WhitleyOpenBoardPkg/BuildAcpiTablesLib: Add lib for building MADT and SRAT Date: Thu, 10 Mar 2022 14:41:11 -0800 Message-Id: In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,isaac.w.oram@intel.com X-Gm-Message-State: KfISkUNSpLyN8Cm4QnjGb5Ewx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1646952114; bh=Dlp2ofqabKPpGO3Iw1pStVzXmmwtfOHYuAJhaa/bmx8=; h=Cc:Date:From:Reply-To:Subject:To; b=nppaMJGvU3AVRLRiyBAqlokNkROt0jScky1vHf54Y8XRd+gJ6AzqaLhQ6N99157fkKi LD0oGhUROTAa7oZXnV3JRW2rD2GzG5xRlmv/76yy4nkj0CJ834XOL2bcfT76G+etdDaa8 K5W6l5bLAtbtj3s6aJAVv/6QlxWo0gMo5Eg= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1646952115871100017 Content-Type: text/plain; charset="utf-8" Library for building tables during the boot. Cc: Nate DeSimone Cc: Chasel Chiu Signed-off-by: Isaac Oram Reviewed-by: Nate DeSimone --- Platform/Intel/WhitleyOpenBoardPkg/Include/Library/BuildAcpiTablesLib.h = | 111 +++++ Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpi= TablesLib.c | 470 ++++++++++++++++++++ Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpi= TablesLib.inf | 40 ++ Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc = | 1 + 4 files changed, 622 insertions(+) diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/BuildAcpiTa= blesLib.h b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/BuildAcpiTab= lesLib.h new file mode 100644 index 0000000000..99aa1c02f7 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Library/BuildAcpiTablesLib= .h @@ -0,0 +1,111 @@ +/** @file + Library for building ACPI Tables. + + @copyright + Copyright 2016 - 2019 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _BUILD_ACPI_TABLES_LIB_H_ +#define _BUILD_ACPI_TABLES_LIB_H_ + +#include + +/** Structure of a MADT and SRAT sub-structure header. + + This structure contains the type and length fields, which are common to = every + sub-structure of the MADT and SRAT tables. A pointer to any structure ca= n be cast as this. +**/ +typedef struct { + UINT8 Type; + UINT8 Length; +} STRUCTURE_HEADER; + +/** + Initialize the MADT header. + + This function fills in the MADT's standard table header with correct val= ues, + except for the length and checksum fields, which are filled in when buil= ding + the whole table. + + @param[in,out] MadtHeader Pointer to the MADT header structure. + + @retval EFI_SUCCESS Successfully initialized the MADT header. + @retval EFI_INVALID_PARAMETER Pointer parameter was null. +**/ +EFI_STATUS +InitializeMadtHeader ( + IN OUT EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *MadtHeader + ); + +/** + Initialize the SRAT header. + + This function fills in the SRAT's standard table header with correct val= ues, + except for the length and checksum fields, which are filled in when buil= ding + the whole table. + + @param[in,out] SratHeader Pointer to the SRAT header structure. + + @retval EFI_SUCCESS Successfully initialized the SRAT header. + @retval EFI_INVALID_PARAMETER Pointer parameter was null. +**/ +EFI_STATUS +InitializeSratHeader ( + IN OUT EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *SratHeader + ); + +/** + Copy an ACPI sub-structure; MADT and SRAT supported + + This function validates the structure type and size of a sub-structure + and returns a newly allocated copy of it. + + @param[in] Header Pointer to the header of the table. + @param[in] Structure Pointer to the structure to copy. + @param[in] NewStructure Newly allocated copy of the structure. + + @retval EFI_SUCCESS Successfully copied the structure. + @retval EFI_INVALID_PARAMETER Pointer parameter was null. + @retval EFI_INVALID_PARAMETER Structure type was unknown. + @retval EFI_INVALID_PARAMETER Structure length was wrong for its type. + @retval EFI_UNSUPPORTED Header passed in is not supported. +**/ +EFI_STATUS +CopyStructure ( + IN EFI_ACPI_DESCRIPTION_HEADER *Header, + IN STRUCTURE_HEADER *Structure, + OUT STRUCTURE_HEADER **NewStructure + ); + +/** + Build ACPI Table. MADT and SRAT tables supported. + + This function builds the ACPI table from the header plus the list of sub= -structures + passed in. The table returned by this function is ready to be installed = using + the ACPI table protocol's InstallAcpiTable function, which copies it into + ACPI memory. After that, the caller should free the memory returned by t= his + function. + + @param[in] AcpiHeader Pointer to the header structure. + @param[in] TableSpecificHdrLength Size of the table specific header, no= t the ACPI standard header size. + @param[in] Structures Pointer to an array of sub-structure = pointers. + @param[in] StructureCount Number of structure pointers in the a= rray. + @param[out] NewTable Newly allocated and initialized point= er to the ACPI Table. + + @retval EFI_SUCCESS Successfully built the ACPI table. + @retval EFI_INVALID_PARAMETER Pointer parameter was null. + @retval EFI_INVALID_PARAMETER Header parameter had the wrong signature. + @retval EFI_OUT_OF_RESOURCES Space for the ACPI Table could not be allo= cated. +**/ +EFI_STATUS +BuildAcpiTable ( + IN EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader, + IN UINTN TableSpecificHdrLength, + IN STRUCTURE_HEADER **Structures, + IN UINTN StructureCount, + OUT UINT8 **NewTable + ); + +#endif // _BUILD_ACPI_TABLES_LIB_H_ diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/= DxeBuildAcpiTablesLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/BuildA= cpiTablesLib/DxeBuildAcpiTablesLib.c new file mode 100644 index 0000000000..778136311e --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuil= dAcpiTablesLib.c @@ -0,0 +1,470 @@ +/** @file + Library for building ACPI Tables. + + @copyright + Copyright 2016 - 2019 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include // library class being implemented + +STRUCTURE_HEADER mMadtStructureTable[] =3D { + {EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC, sizeof (EFI_ACPI_6_2_PROCES= SOR_LOCAL_APIC_STRUCTURE)}, + {EFI_ACPI_6_2_IO_APIC, sizeof (EFI_ACPI_6_2_IO_API= C_STRUCTURE)}, + {EFI_ACPI_6_2_INTERRUPT_SOURCE_OVERRIDE, sizeof (EFI_ACPI_6_2_INTERR= UPT_SOURCE_OVERRIDE_STRUCTURE)}, + {EFI_ACPI_6_2_NON_MASKABLE_INTERRUPT_SOURCE, sizeof (EFI_ACPI_6_2_NON_MA= SKABLE_INTERRUPT_SOURCE_STRUCTURE)}, + {EFI_ACPI_6_2_LOCAL_APIC_NMI, sizeof (EFI_ACPI_6_2_LOCAL_= APIC_NMI_STRUCTURE)}, + {EFI_ACPI_6_2_LOCAL_APIC_ADDRESS_OVERRIDE, sizeof (EFI_ACPI_6_2_LOCAL_= APIC_ADDRESS_OVERRIDE_STRUCTURE)}, + {EFI_ACPI_6_2_IO_SAPIC, sizeof (EFI_ACPI_6_2_IO_SAP= IC_STRUCTURE)}, + {EFI_ACPI_6_2_LOCAL_SAPIC, sizeof (EFI_ACPI_6_2_PROCES= SOR_LOCAL_SAPIC_STRUCTURE)}, + {EFI_ACPI_6_2_PLATFORM_INTERRUPT_SOURCES, sizeof (EFI_ACPI_6_2_PLATFO= RM_INTERRUPT_SOURCES_STRUCTURE)}, + {EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC, sizeof (EFI_ACPI_6_2_PROCES= SOR_LOCAL_X2APIC_STRUCTURE)}, + {EFI_ACPI_6_2_LOCAL_X2APIC_NMI, sizeof (EFI_ACPI_6_2_LOCAL_= X2APIC_NMI_STRUCTURE)} +}; + +STRUCTURE_HEADER mSratStructureTable[] =3D { + {EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY, sizeof (EFI_ACPI_6_2_= PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE)}, + {EFI_ACPI_6_2_MEMORY_AFFINITY, sizeof (EFI_ACPI_6_2_= MEMORY_AFFINITY_STRUCTURE)}, + {EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_AFFINITY, sizeof (EFI_ACPI_6_2_= PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE)} +}; + +/** + Get the size of the ACPI table. + + This function calculates the size needed for the ACPI Table based on the= number and + size of the sub-structures that will compose it. + + @param[in] TableSpecificHdrLength Size of the table specific header, n= ot the ACPI standard header size. + @param[in] Structures Pointer to an array of sub-structure= pointers. + @param[in] StructureCount Number of structure pointers in the = array. + + @return Total size needed for the ACPI table. +**/ +UINT32 +GetTableSize ( + IN UINTN TableSpecificHdrLength, + IN STRUCTURE_HEADER **Structures, + IN UINTN StructureCount + ) +{ + UINT32 TableLength; + UINT32 Index; + + // + // Compute size of the ACPI table; header plus all structures needed. + // + TableLength =3D (UINT32) TableSpecificHdrLength; + + for (Index =3D 0; Index < StructureCount; Index++) { + ASSERT (Structures[Index] !=3D NULL); + if (Structures[Index] =3D=3D NULL) { + return 0; + } + + TableLength +=3D Structures[Index]->Length; + } + + return TableLength; +} + +/** + Allocate the ACPI Table. + + This function allocates space for the ACPI table based on the number and= size of + the sub-structures that will compose it. + + @param[in] TableSpecificHdrLength Size of the table specific header, n= ot the ACPI standard header size. + @param[in] Structures Pointer to an array of sub-structure pointers. + @param[in] StructureCount Number of structure pointers in the array. + @param[out] Table Newly allocated ACPI Table pointer. + + @retval EFI_SUCCESS Successfully allocated the Table. + @retval EFI_OUT_OF_RESOURCES Space for the Table could not be allocated. +**/ +EFI_STATUS +AllocateTable ( + IN UINTN TableSpecificHdrLength, + IN STRUCTURE_HEADER **Structures, + IN UINTN StructureCount, + OUT EFI_ACPI_DESCRIPTION_HEADER **Table + ) +{ + EFI_STATUS Status; + UINT32 Size; + EFI_ACPI_DESCRIPTION_HEADER *InternalTable; + + // + // Get the size of the ACPI table and allocate memory. + // + Size =3D GetTableSize (TableSpecificHdrLength, Structures, StructureCoun= t); + InternalTable =3D (EFI_ACPI_DESCRIPTION_HEADER *) AllocatePool (Size); + + if (InternalTable =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + DEBUG (( + DEBUG_ERROR, + "Failed to allocate %d bytes for ACPI Table\n", + Size + )); + } else { + Status =3D EFI_SUCCESS; + *Table =3D InternalTable; + } + + return Status; +} + +/** + Initialize the header. + + This function fills in the standard table header with correct values, + except for the length and checksum fields, which are filled in later. + + @param[in,out] Header Pointer to the header structure. + + @retval EFI_SUCCESS Successfully initialized the header. + @retval EFI_INVALID_PARAMETER Pointer parameter was null. +**/ +EFI_STATUS +InitializeHeader ( + IN OUT EFI_ACPI_DESCRIPTION_HEADER *Header, + IN UINT32 Signature, + IN UINT8 Revision, + IN UINT32 OemRevision + ) +{ + UINT64 AcpiTableOemId; + + if (Header =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "Header pointer is NULL\n")); + return EFI_INVALID_PARAMETER; + } + + Header->Signature =3D Signature; + Header->Length =3D 0; // filled in by Build function + Header->Revision =3D Revision; + Header->Checksum =3D 0; // filled in by InstallAcpiTable + + CopyMem ( + (VOID *) &Header->OemId, + PcdGetPtr (PcdAcpiDefaultOemId), + sizeof (Header->OemId) + ); + + AcpiTableOemId =3D PcdGet64 (PcdAcpiDefaultOemTableId); + CopyMem ( + (VOID *) &Header->OemTableId, + (VOID *) &AcpiTableOemId, + sizeof (Header->OemTableId) + ); + + Header->OemRevision =3D OemRevision; + Header->CreatorId =3D EFI_ACPI_CREATOR_ID; + Header->CreatorRevision =3D EFI_ACPI_CREATOR_REVISION; + + return EFI_SUCCESS; +} + +/** + Initialize the MADT header. + + This function fills in the MADT's standard table header with correct val= ues, + except for the length and checksum fields, which are filled in later. + + @param[in,out] MadtHeader Pointer to the MADT header structure. + + @retval EFI_SUCCESS Successfully initialized the MADT header. + @retval EFI_INVALID_PARAMETER Pointer parameter was null. +**/ +EFI_STATUS +InitializeMadtHeader ( + IN OUT EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *MadtHeader + ) +{ + EFI_STATUS Status; + + if (MadtHeader =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "MADT header pointer is NULL\n")); + return EFI_INVALID_PARAMETER; + } + + Status =3D InitializeHeader ( + &MadtHeader->Header, + EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION, + EFI_ACPI_OEM_MADT_REVISION + ); + if (EFI_ERROR (Status)) { + return Status; + } + + MadtHeader->LocalApicAddress =3D EFI_ACPI_LOCAL_APIC_ADDRESS; + MadtHeader->Flags =3D EFI_ACPI_6_2_MULTIPLE_APIC_FLAGS; + + return EFI_SUCCESS; +} + +/** + Initialize the SRAT header. + + This function fills in the SRAT's standard table header with correct val= ues, + except for the length and checksum fields, which are filled in when buil= ding + the whole table. + + @param[in,out] SratHeader Pointer to the SRAT header structure. + + @retval EFI_SUCCESS Successfully initialized the SRAT header. + @retval EFI_INVALID_PARAMETER Pointer parameter was null. +**/ +EFI_STATUS +InitializeSratHeader ( + IN OUT EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *SratHeader + ) +{ + EFI_STATUS Status; + + if (SratHeader =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "SRAT header pointer is NULL\n")); + return EFI_INVALID_PARAMETER; + } + + Status =3D InitializeHeader ( + &SratHeader->Header, + EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE, + EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION, + EFI_ACPI_OEM_SRAT_REVISION + ); + if (EFI_ERROR (Status)) { + return Status; + } + + SratHeader->Reserved1 =3D EFI_ACPI_SRAT_RESERVED_FOR_BACKWARD_COMPATIBIL= ITY; + SratHeader->Reserved2 =3D EFI_ACPI_RESERVED_QWORD; + + return EFI_SUCCESS; +} + +/** + Copy an ACPI sub-structure; MADT and SRAT supported + + This function validates the structure type and size of a sub-structure + and returns a newly allocated copy of it. + + @param[in] Header Pointer to the header of the table. + @param[in] Structure Pointer to the structure to copy. + @param[in] NewStructure Newly allocated copy of the structure. + + @retval EFI_SUCCESS Successfully copied the structure. + @retval EFI_INVALID_PARAMETER Pointer parameter was null. + @retval EFI_INVALID_PARAMETER Structure type was unknown. + @retval EFI_INVALID_PARAMETER Structure length was wrong for its type. + @retval EFI_UNSUPPORTED Header passed in is not supported. +**/ +EFI_STATUS +CopyStructure ( + IN EFI_ACPI_DESCRIPTION_HEADER *Header, + IN STRUCTURE_HEADER *Structure, + OUT STRUCTURE_HEADER **NewStructure + ) +{ + STRUCTURE_HEADER *NewStructureInternal; + STRUCTURE_HEADER *StructureTable; + UINTN TableNumEntries; + BOOLEAN EntryFound; + UINT8 Index; + + // + // Initialize the number of table entries and the table based on the tab= le header passed in. + // + if (Header->Signature =3D=3D EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABL= E_SIGNATURE) { + TableNumEntries =3D sizeof (mMadtStructureTable) / sizeof (STRUCTURE_H= EADER); + StructureTable =3D mMadtStructureTable; + } else if (Header->Signature =3D=3D EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINIT= Y_TABLE_SIGNATURE) { + TableNumEntries =3D sizeof (mSratStructureTable) / sizeof (STRUCTURE_H= EADER); + StructureTable =3D mSratStructureTable; + } else { + return EFI_UNSUPPORTED; + } + + // + // Check the incoming structure against the table of supported structure= s. + // + EntryFound =3D FALSE; + for (Index =3D 0; Index < TableNumEntries; Index++) { + if (Structure->Type =3D=3D StructureTable[Index].Type) { + if (Structure->Length =3D=3D StructureTable[Index].Length) { + EntryFound =3D TRUE; + } else { + DEBUG (( + DEBUG_ERROR, + "Invalid length for structure type %d: expected %d, actually %d\= n", + Structure->Type, + StructureTable[Index].Length, + Structure->Length + )); + return EFI_INVALID_PARAMETER; + } + } + } + + // + // If no entry in the table matches the structure type and length passed= in + // then return invalid parameter. + // + if (!EntryFound) { + DEBUG (( + DEBUG_ERROR, + "Unknown structure type: %d\n", + Structure->Type + )); + return EFI_INVALID_PARAMETER; + } + + NewStructureInternal =3D (STRUCTURE_HEADER *) AllocatePool (Structure->L= ength); + if (NewStructureInternal =3D=3D NULL) { + DEBUG (( + DEBUG_ERROR, + "Failed to allocate %d bytes for type %d structure\n", + Structure->Length, + Structure->Type + )); + return EFI_OUT_OF_RESOURCES; + } + + CopyMem ( + (VOID *) NewStructureInternal, + (VOID *) Structure, + Structure->Length + ); + + *NewStructure =3D NewStructureInternal; + return EFI_SUCCESS; +} + +/** + Build ACPI Table. MADT and SRAT tables supported. + + This function builds the ACPI table from the header plus the list of sub= -structures + passed in. The table returned by this function is ready to be installed = using + the ACPI table protocol's InstallAcpiTable function, which copies it into + ACPI memory. After that, the caller should free the memory returned by t= his + function. + + @param[in] AcpiHeader Pointer to the header structure. + @param[in] TableSpecificHdrLength Size of the table specific header, no= t the ACPI standard header size. + @param[in] Structures Pointer to an array of sub-structure = pointers. + @param[in] StructureCount Number of structure pointers in the a= rray. + @param[out] NewTable Newly allocated and initialized point= er to the ACPI Table. + + @retval EFI_SUCCESS Successfully built the ACPI table. + @retval EFI_INVALID_PARAMETER Pointer parameter was null. + @retval EFI_INVALID_PARAMETER Header parameter had the wrong signature. + @retval EFI_OUT_OF_RESOURCES Space for the ACPI Table could not be allo= cated. +**/ +EFI_STATUS +BuildAcpiTable ( + IN EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader, + IN UINTN TableSpecificHdrLength, + IN STRUCTURE_HEADER **Structures, + IN UINTN StructureCount, + OUT UINT8 **NewTable + ) +{ + EFI_STATUS Status; + EFI_ACPI_DESCRIPTION_HEADER *InternalTable; + UINTN Index; + UINT8 *CurrPtr; + UINT8 *EndOfTablePtr; + + if (AcpiHeader =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "AcpiHeader pointer is NULL\n")); + return EFI_INVALID_PARAMETER; + } + + if (AcpiHeader->Signature !=3D EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TA= BLE_SIGNATURE && + AcpiHeader->Signature !=3D EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TAB= LE_SIGNATURE) { + DEBUG (( + DEBUG_ERROR, + "MADT or SRAT header signature is expected, actually 0x%08x\n", + AcpiHeader->Signature + )); + return EFI_INVALID_PARAMETER; + } + + if (Structures =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "Structure array pointer is NULL\n")); + return EFI_INVALID_PARAMETER; + } + + for (Index =3D 0; Index < StructureCount; Index++) { + if (Structures[Index] =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "Structure pointer %d is NULL\n", Index)); + return EFI_INVALID_PARAMETER; + } + } + + // + // Allocate the memory needed for the table. + // + Status =3D AllocateTable ( + TableSpecificHdrLength, + Structures, + StructureCount, + &InternalTable + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Copy Header and patch in structure length, checksum is programmed lat= er + // after all structures are populated. + // + CopyMem ( + (VOID *) InternalTable, + (VOID *) AcpiHeader, + TableSpecificHdrLength + ); + + InternalTable->Length =3D GetTableSize (TableSpecificHdrLength, Structur= es, StructureCount); + + // + // Copy all the sub structures to the table. + // + CurrPtr =3D ((UINT8 *) InternalTable) + TableSpecificHdrLength; + EndOfTablePtr =3D ((UINT8 *) InternalTable) + InternalTable->Length; + + for (Index =3D 0; Index < StructureCount; Index++) { + ASSERT (Structures[Index] !=3D NULL); + if (Structures[Index] =3D=3D NULL) { + break; + } + + CopyMem ( + (VOID *) CurrPtr, + (VOID *) Structures[Index], + Structures[Index]->Length + ); + + CurrPtr +=3D Structures[Index]->Length; + ASSERT (CurrPtr <=3D EndOfTablePtr); + if (CurrPtr > EndOfTablePtr) { + break; + } + } + + // + // Update the return pointer. + // + *NewTable =3D (UINT8 *) InternalTable; + return EFI_SUCCESS; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/= DxeBuildAcpiTablesLib.inf b/Platform/Intel/WhitleyOpenBoardPkg/Library/Buil= dAcpiTablesLib/DxeBuildAcpiTablesLib.inf new file mode 100644 index 0000000000..c2bb068fcf --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuil= dAcpiTablesLib.inf @@ -0,0 +1,40 @@ +## @file +# Library for building ACPI Tables. +# +# @copyright +# Copyright 2016 - 2017 Intel Corporation.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010019 + BASE_NAME =3D DxeBuildAcpiTablesLib + FILE_GUID =3D E4F78A63-7B78-43CD-A5C4-6CCB785B8854 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D BuildAcpiTablesLib|DXE_DRIVER + +[Sources] + DxeBuildAcpiTablesLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + WhitleySiliconPkg/CpRcPkg.dec + WhitleyOpenBoardPkg/PlatformPkg.dec + WhitleySiliconPkg/SiliconPkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + MemoryAllocationLib + PcdLib + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId + +[FixedPcd] + gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuSocketCount + gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuCoreCount diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc b/Platform/= Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc index 2ac4a81e81..39b93d9289 100644 --- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc +++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc @@ -620,6 +620,7 @@ VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf CrcLib|WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf PlatformSpecificAcpiTableLib|WhitleyOpenBoardPkg/Library/PlatformSpecifi= cAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.inf + BuildAcpiTablesLib|WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBui= ldAcpiTablesLib.inf =20 [LibraryClasses.Common.SEC, LibraryClasses.Common.PEI_CORE, LibraryClasses= .Common.PEIM] FspWrapperApiLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFs= pWrapperApiLib.inf --=20 2.27.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#87429): https://edk2.groups.io/g/devel/message/87429 Mute This Topic: https://groups.io/mt/89698851/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat May 18 21:45:23 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+87432+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+87432+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1646952116; cv=none; d=zohomail.com; s=zohoarc; b=Yryfm1GL95s57V35/qF+kl+l+uBzaOjVC1jxzjmr6fcs2T5wmsnr/AYqV1enn68lcONTjM8Z39dhpLRmlLQhE6M2GnZ6Vx0ZEK8INhxmTMv0Wo3A0NGuzAKd+tnKIIxU09Myj/2rl2cBe5EladfXYt1ByJ/l4BpQFgVUMJmIX/I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1646952116; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=ymUx3ZdVU1tiyjZT7s1mbU+Ez6PIvXX6RQDQaAXTXqQ=; b=eI5MHDzhQukOax2dQml/Yfd2ZKEKN/GGBIHxytvu8avL/ClY5TIcJcbPMWs7adMSnvpvxGSv81/+o5nj4vTK2eft30Asrn7pCW7cWPHOX3tyMFdFJwJEcHqHo1HXcxH+0qPXA2NybDQmo6bIbwHej0jVFikryjozPIaSIZFVvTw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+87432+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1646952116221910.0985974024203; Thu, 10 Mar 2022 14:41:56 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id zgJIYY1788612xrQvHtCdu7M; Thu, 10 Mar 2022 14:41:55 -0800 X-Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mx.groups.io with SMTP id smtpd.web12.859.1646952111350461854 for ; Thu, 10 Mar 2022 14:41:53 -0800 X-IronPort-AV: E=McAfee;i="6200,9189,10282"; a="316121255" X-IronPort-AV: E=Sophos;i="5.90,171,1643702400"; d="scan'208";a="316121255" X-Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2022 14:41:35 -0800 X-IronPort-AV: E=Sophos;i="5.90,171,1643702400"; d="scan'208";a="644643385" X-Received: from iworam-desk.amr.corp.intel.com ([10.7.150.60]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2022 14:41:34 -0800 From: "Oram, Isaac W" To: devel@edk2.groups.io Cc: Nate DeSimone , Chasel Chiu Subject: [edk2-devel][edk2-platforms][PATCH V1 7/9] WhitleyOpenBoardPkg/AcpiTablesLib: Add library for AcpiPlatform driver Date: Thu, 10 Mar 2022 14:41:12 -0800 Message-Id: <1a58840461a312b2263e0680c0c158c04ff5b359.1646951441.git.isaac.w.oram@intel.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,isaac.w.oram@intel.com X-Gm-Message-State: P6CYP0j9HUreA86IWbthR9Mwx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1646952115; bh=erGoh2oVzd8HkL7Ffi+eVGxNDHrElK/LBUsilKoh+aI=; h=Cc:Date:From:Reply-To:Subject:To; b=J5d6kzY79uZq9PKFQOt0hwCsSUB132SDMWWNH2AU2VTWZeOYerKfWontHi8MFzFOt2O rLifnE3K5Dug+Z98wx9JtZEfSZbnyu2MbbaewxD2GHtjYTDUqCdyBAIzAnPOL/dNbLIBW RcvM9h26eFrjbVCdxQ1J26eeTNbD/FaziLU= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1646952118319100006 Content-Type: text/plain; charset="utf-8" AcpiTablesLib allows for board specific updates to ACPI tables. Cc: Nate DeSimone Cc: Chasel Chiu Signed-off-by: Isaac Oram Reviewed-by: Nate DeSimone --- Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatfo= rmLib.c | 534 ++++++ Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatfo= rmLib.inf | 127 ++ Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatfo= rmLibApic.c | 735 +++++++++ Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatfo= rmLibBdat.c | 1574 ++++++++++++++++++ Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatfo= rmLibDsdt.c | 673 ++++++++ Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatfo= rmLibFadt.c | 75 + Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatfo= rmLibHmat.c | 1710 ++++++++++++++++++++ Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatfo= rmLibLocal.h | 441 +++++ Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatfo= rmLibMcfg.c | 134 ++ Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatfo= rmLibMigt.c | 69 + Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatfo= rmLibMsct.c | 101 ++ Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatfo= rmLibNfit.c | 45 + Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatfo= rmLibPcat.c | 42 + Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatfo= rmLibPmtt.c | 267 +++ Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatfo= rmLibSlit.c | 1153 +++++++++++++ Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatfo= rmLibSrat.c | 952 +++++++++++ Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiPlatfo= rmLibSsdt.c | 1004 ++++++++++++ Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dec = | 5 + Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc = | 1 + 19 files changed, 9642 insertions(+) diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLi= b/AcpiPlatformLib.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatfo= rmTableLib/AcpiPlatformLib.c new file mode 100644 index 0000000000..f321c73a51 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiP= latformLib.c @@ -0,0 +1,534 @@ +/** @file + ACPI Platform Driver Hooks + + @copyright + Copyright 1996 - 2020 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// Statements that include other files +// +#include "AcpiPlatformLibLocal.h" +#include +#include +#include +#include +#include + +extern BIOS_ACPI_PARAM *mAcpiParameter; + +EFI_PLATFORM_INFO *mPlatformInfo; +EFI_CPU_CSR_ACCESS_PROTOCOL *mCpuCsrAccess; +EFI_ACPI_TABLE_PROTOCOL *mAcpiTable; +extern EFI_IIO_UDS_PROTOCOL *mIioUds; +CPU_CSR_ACCESS_VAR *mCpuCsrAccessVarPtr; + + +UINT32 mNumOfBitShift; +BOOLEAN mX2ApicEnabled; + +SYSTEM_MEMORY_MAP_HOB *mSystemMemoryMap; + +SOCKET_MEMORY_CONFIGURATION mSocketMemoryConfiguration; +SOCKET_MP_LINK_CONFIGURATION mSocketMpLinkConfiguration; +SOCKET_IIO_CONFIGURATION mSocketIioConfiguration; +SOCKET_POWERMANAGEMENT_CONFIGURATION mSocketPowermanagementConfiguration; +SOCKET_COMMONRC_CONFIGURATION mSocketCommonRcConfiguration; +SOCKET_PROCESSORCORE_CONFIGURATION mSocketProcessorCoreConfiguration; + +CPU_CONFIG_CONTEXT_BUFFER *mCpuConfigLibConfigContextBuffer =3D NULL; + +EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE *mSpcrTable =3D NULL; + +/** + The constructor function of AcpiPlatormL Library. + + The constructor function caches the value of PCD entry + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +AcpiPlatformLibConstructor ( + VOID + ) +{ + EFI_STATUS Status; + EFI_HOB_GUID_TYPE *GuidHob; + + DYNAMIC_SI_LIBARY_PROTOCOL *DynamicSiLibraryProtocol =3D NULL; + + mCpuConfigLibConfigContextBuffer =3D (CPU_CONFIG_CONTEXT_BUFFER *) (UINT= N) PcdGet64 (PcdCpuConfigContextBuffer); + if (mCpuConfigLibConfigContextBuffer =3D=3D NULL) { + ASSERT_EFI_ERROR (RETURN_NOT_FOUND); + return RETURN_NOT_FOUND; + } + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, &D= ynamicSiLibraryProtocol); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + GuidHob =3D GetFirstGuidHob (&gEfiPlatformInfoGuid); + if (GuidHob =3D=3D NULL) { + ASSERT (GuidHob !=3D NULL); + return EFI_NOT_FOUND; + } + mPlatformInfo =3D GET_GUID_HOB_DATA (GuidHob); + + // + // Locate the IIO Protocol Interface + // + Status =3D gBS->LocateProtocol (&gEfiIioUdsProtocolGuid,NULL,&mIioUds); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D gBS->LocateProtocol (&gEfiCpuCsrAccessGuid, NULL, &mCpuCsrAcc= ess); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + mCpuCsrAccessVarPtr =3D DynamicSiLibraryProtocol->GetSysCpuCsrAccessVar = (); + mSystemMemoryMap =3D DynamicSiLibraryProtocol->GetSystemMemoryMapData (); + ASSERT (mSystemMemoryMap !=3D NULL); + + mMpService =3D NULL; + + Status =3D gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, &mMpSe= rvice); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // + // Determine the number of processors + // + mMpService->GetNumberOfProcessors ( + mMpService, + &mNumberOfCPUs, + &mNumberOfEnabledCPUs + ); + ASSERT (mNumberOfCPUs <=3D MAX_CPU_NUM && mNumberOfEnabledCPUs >=3D 1); + if (mNumberOfCPUs > MAX_CPU_NUM) { + mNumberOfCPUs =3D MAX_CPU_NUM; + } + + Status =3D gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, &mAcpi= Table); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + return EFI_SUCCESS; +} + + +/** + Platform hook to initialize Platform Specific ACPI Parameters + + @retval EFI_SUCCESS Platform specific parameters in mAcpiPara= meter + initialized successfully. + @retval EFI_INVALID_PARAMETER mAcpiParameter global was NULL. +**/ +EFI_STATUS +PlatformHookAfterAcpiParamInit ( + VOID + ) +{ + EFI_STATUS Status; + + Status =3D EFI_SUCCESS; + + if (mAcpiParameter =3D=3D NULL) { + ASSERT (mAcpiParameter !=3D NULL); + return EFI_INVALID_PARAMETER; + } + + DEBUG ((DEBUG_INFO, "ACPI Parameter Block Address: 0x%X\n", mAcpiParamet= er)); + + + // + // Call for Local APIC ID Reorder + // + Status =3D SortCpuLocalApicInTable (); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "[ACPI] ERROR: SortCpuLocalApicInTable failed: %r= \n", Status)); + return Status; + } + + return Status; +} + + +EFI_STATUS +AcpiPlatformHooksIsActiveTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + EFI_NFIT_TABLE_UPDATE_PROTOCOL *NfitTableUpdateProtocol; + EFI_ACPI_DESCRIPTION_HEADER *TableHeader; + EFI_STATUS Status; + SETUP_DATA SetupData; + SYSTEM_CONFIGURATION SystemConfiguration; + UINT8 *OemSkuAcpiName; + + Status =3D GetEntireConfig (&SetupData); + ASSERT_EFI_ERROR (Status); + CopyMem (&SystemConfiguration, &(SetupData.SystemConfig), sizeof(SYSTEM_= CONFIGURATION)); + + if (mSystemMemoryMap =3D=3D NULL) { + + ASSERT (FALSE); + return EFI_NOT_FOUND; + } + TableHeader =3D (EFI_ACPI_DESCRIPTION_HEADER *) Table; + if (TableHeader->Signature =3D=3D ACPI_PMTT_TABLE_SIGNATURE) { + if (!mSystemMemoryMap->DcpmmPresent) { + return EFI_NOT_FOUND; + } + } + + if (TableHeader->Signature =3D=3D EFI_BDAT_TABLE_SIGNATURE) { + if (mSocketMemoryConfiguration.bdatEn =3D=3D 0) { + return EFI_NOT_FOUND; + } + } + + if (TableHeader->Signature =3D=3D NVDIMM_PLATFORM_CONFIG_ATTRIBUTE_TABLE= _SIGNATURE) { + if (mSystemMemoryMap->DcpmmPresent =3D=3D 0) { + return EFI_NOT_FOUND; + } + } + + if (TableHeader->Signature =3D=3D NVDIMM_FW_INTERFACE_TABLE_SIGNATURE) { + Status =3D gBS->LocateProtocol (&gEfiNfitTableUpdateProtocolGuid, NULL= , &NfitTableUpdateProtocol); + if (EFI_ERROR (Status)){ + // If NfitTableUpdateProtocol is not found we assume no NVDIMM is pr= esent - it means don't publish NFIT + DEBUG ((DEBUG_ERROR, "NfitTableUpdateProtocol is not installed.\n")); + return EFI_NOT_FOUND; + } + } + if (TableHeader->Signature =3D=3D EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_RED= IRECTION_TABLE_SIGNATURE) { + // + // Initialize the SPCR table pointer. + // SPCR table is not ready yet, update it before booting. + // + mSpcrTable =3D (EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE *) Tabl= e; + return EFI_NOT_READY; + } + + if ((TableHeader->Signature =3D=3D EFI_ACPI_6_2_SYSTEM_LOCALITY_INFORMAT= ION_TABLE_SIGNATURE) || + (TableHeader->Signature =3D=3D EFI_ACPI_6_2_MAXIMUM_SYSTEM_CHARACTER= ISTICS_TABLE_SIGNATURE) || + (TableHeader->Signature =3D=3D EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY= _TABLE_SIGNATURE) || + TableHeader->Signature =3D=3D EFI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TAB= LE_SIGNATURE) { + // + // Only publish SRAT/SLIT/MSCT/HMAT if NUMA is enabled in setup. + // + if (!mSocketCommonRcConfiguration.NumaEn) { + + DEBUG ((DEBUG_INFO, "[ACPI] NUMA disabled, do not publish '%c%c%c%c'= table\n", + ((CHAR8*)&TableHeader->Signature)[0], ((CHAR8*)&TableHeader-= >Signature)[1], + ((CHAR8*)&TableHeader->Signature)[2], ((CHAR8*)&TableHeader-= >Signature)[3])); + return EFI_NOT_FOUND; + } + } + + if (TableHeader->Signature =3D=3D EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNAT= URE) { + return EFI_NOT_FOUND; + } + + if (TableHeader->Signature =3D=3D EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DES= CRIPTION_TABLE_SIGNATURE) { + OemSkuAcpiName =3D PcdGetPtr (PcdOemSkuAcpiName); + if (OemSkuAcpiName =3D=3D NULL) { + return EFI_UNSUPPORTED; + } + if ( (0 =3D=3D CompareMem (&(TableHeader->OemTableId), OemSkuAcpiName,= 8)) ) { + Status =3D PlatformGetAcpiFixTableDataPointer (&mAmlOffsetTablePoint= er); + if (!EFI_ERROR(Status)) { + DEBUG((DEBUG_INFO, "[ACPI] Platform DSDT Fixup table found\n")); + DEBUG((DEBUG_INFO, "[ACPI] Platform SRP: Using %a DSDT\n", OemSkuA= cpiName)); + return EFI_SUCCESS; + } else { + DEBUG((DEBUG_ERROR, "[ACPI] Platform DSDT Fixup table not found.\n= ")); + return EFI_UNSUPPORTED; + } + } else { + DEBUG ((DEBUG_INFO, "[ACPI] Platform DSDT OemSkuAcpiName '%c%c%c%c%c= %c%c%c':\n", + ((CHAR8*)OemSkuAcpiName)[0], ((CHAR8*)OemSkuAcpiName)[1], + ((CHAR8*)OemSkuAcpiName)[2], ((CHAR8*)OemSkuAcpiName)[3], + ((CHAR8*)OemSkuAcpiName)[4], ((CHAR8*)OemSkuAcpiName)[5], + ((CHAR8*)OemSkuAcpiName)[6], ((CHAR8*)OemSkuAcpiName)[7])); + + DEBUG ((DEBUG_INFO, " no match for OemTableId '%c%c%c%c%c%c%c%c' fro= m FwVol.\n", + ((CHAR8*)&TableHeader->OemTableId)[0], ((CHAR8*)&TableHeader= ->OemTableId)[1], + ((CHAR8*)&TableHeader->OemTableId)[2], ((CHAR8*)&TableHeader= ->OemTableId)[3], + ((CHAR8*)&TableHeader->OemTableId)[4], ((CHAR8*)&TableHeader= ->OemTableId)[5], + ((CHAR8*)&TableHeader->OemTableId)[6], ((CHAR8*)&TableHeader= ->OemTableId)[7])); + + return EFI_UNSUPPORTED; + } + } + + // + // Hooks for checking additional platform ACPI Table is active or not. + // If ACPI Table is not in list, it should be reported and returned EFI_= SUCCESS. + // + return PlatformAcpiReportHooksTableIsActive (Table); +} + + +/** + This function will update any runtime platform specific information. + This currently includes: + Setting OEM table values, ID, table ID, creator ID and creator revisio= n. + Enabling the proper processor entries in the APIC tables. + + @param Table - The table to update + + @retval EFI_SUCCESS - The function completed successfully. +**/ +EFI_STATUS +PlatformUpdateTables ( + IN OUT EFI_ACPI_COMMON_HEADER *Table, + IN OUT EFI_ACPI_TABLE_VERSION *Version + ) +{ + EFI_ACPI_DESCRIPTION_HEADER *TableHeader; + EFI_STATUS Status; + ACPI_APIC_STRUCTURE_PTR *ProcessorLocalApicEntry; + UINT64 TempOemTableId; + UINT32 Data32; + + DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &= DynamicSiLibraryProtocol2); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + TableHeader =3D NULL; + + ProcessorLocalApicEntry =3D NULL; + Status =3D EFI_SUCCESS; + + // + // By default, a table belongs in all ACPI table versions published. + // Some tables will override this because they have different versions o= f the table. + // + *Version =3D EFI_ACPI_TABLE_VERSION_2_0; + + if (Table->Signature !=3D EFI_ACPI_6_2_FIRMWARE_ACPI_CONTROL_STRUCTURE_S= IGNATURE && + Table->Signature !=3D EFI_ACPI_6_2_SECONDARY_SYSTEM_DESCRIPTION_TABL= E_SIGNATURE && + Table->Signature !=3D SIGNATURE_32('N', 'F', 'I', 'T') && + Table->Signature !=3D SIGNATURE_32('P', 'C', 'A', 'T') && + Table->Signature !=3D SIGNATURE_32('O', 'E', 'M', '1') && + Table->Signature !=3D SIGNATURE_32('O', 'E', 'M', '2') && + Table->Signature !=3D SIGNATURE_32('O', 'E', 'M', '3') && + Table->Signature !=3D SIGNATURE_32('O', 'E', 'M', '4')) + { + TableHeader =3D (EFI_ACPI_DESCRIPTION_HEADER *) Table; + // + // Update the OEMID and OEM Table ID. + // + TempOemTableId =3D PcdGet64 (PcdAcpiDefaultOemTableId); + + CopyMem (TableHeader->OemId, PcdGetPtr(PcdAcpiDefaultOemId), sizeof(Ta= bleHeader->OemId)); + CopyMem (&TableHeader->OemTableId, &TempOemTableId, sizeof(TableHeader= ->OemTableId)); + + // + // Update the creator ID + // + TableHeader->CreatorId =3D EFI_ACPI_CREATOR_ID; + + // + // Update the creator revision + // + TableHeader->CreatorRevision =3D EFI_ACPI_CREATOR_REVISION; + } + // + // Complete this function + // + + //ASSERT (mMaxNumberOfCPUs <=3D MAX_CPU_NUM && mNumberOfEnabledCPUs >=3D= 1); + + // + // Assign a invalid intial value for update + // + // + // Update the processors in the APIC table + // + DEBUG ((DEBUG_INFO, "[ACPI] Patching '%c%c%c%c' table...\n", + ((CHAR8*)&Table->Signature)[0], ((CHAR8*)&Table->Signature)[1], + ((CHAR8*)&Table->Signature)[2], ((CHAR8*)&Table->Signature)[3])); + switch (Table->Signature) { + + // + // Do not allow a prebuilt MADT, since it is built dynamically. + // + case EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE: + DEBUG ((DEBUG_ERROR, "[ACPI] ERROR: Prebuilt MADT found\n")); + Status =3D EFI_INVALID_PARAMETER; + ASSERT_EFI_ERROR (Status); + break; + + case EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE: + Status =3D PatchFadtTable (Table); + break; + + case EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE: + // + // Patch the memory resource + // + Status =3D PatchDsdtTable (Table); + break; + + case EFI_ACPI_6_2_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE: + Status =3D PatchSsdtTable (Table,Version); + break; + + case EFI_ACPI_6_2_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE: + // + // Adjust HPET Table to correct the Base Address + // Get the address bits in RCRB that configure HPET MMIO space + // and create an offset to the pre-defined HEPT base address + // + DynamicSiLibraryProtocol2->PchHpetBaseGet (&Data32); + // + // Add the offset to the base address and copy into HPET DSDT table + // + ((EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *) Table)->BaseAddr= essLower32Bit.Address =3D Data32; + break; + + case EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADD= RESS_DESCRIPTION_TABLE_SIGNATURE: + Status =3D PatchMcfgAcpiTable (Table); + break; + + case EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE: + Status =3D PatchSpcrAcpiTable (Table); + break; + + case ACPI_PMTT_TABLE_SIGNATURE: + if (!PcdGetBool (PcdPlatformNotSupportAcpiTable)) { + Status =3D PatchPlatformMemoryTopologyTable (Table); + } + break; + + case EFI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE: + if (!PcdGetBool (PcdPlatformNotSupportAcpiTable)) { + Status =3D PatchHmatAcpiTable (Table); + } + break; + + case EFI_ACPI_6_2_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE_SIGNATURE: + if (!PcdGetBool (PcdPlatformNotSupportAcpiTable)) { + Status =3D PatchMsctAcpiTable (Table); + } + break; + + case EFI_MIGT_ACPI_TABLE_SIGNATURE: + if (!PcdGetBool (PcdPlatformNotSupportAcpiTable)) { + if (PcdGetBool (ReservedB)) { + Status =3D PatchMigtAcpiTable (Table); + } + } + break; + + case EFI_BDAT_TABLE_SIGNATURE: + if (!PcdGetBool (PcdPlatformNotSupportAcpiBdatTable)) { + Status =3D PatchBdatAcpiTable (Table); + } + break; + + case NVDIMM_FW_INTERFACE_TABLE_SIGNATURE: + Status =3D UpdateNfitTable (Table); + break; + + case NVDIMM_PLATFORM_CONFIG_ATTRIBUTE_TABLE_SIGNATURE: + Status =3D UpdatePcatTable (Table); + break; + + //Patch Dynamic OEM SSDT table + case OEM1_SSDT_TABLE_SIGNATURE: + Status =3D PatchOem1SsdtTable (Table); //CPU EIST + break; + + case OEM2_SSDT_TABLE_SIGNATURE: + Status =3D PatchOem2SsdtTable (Table); //CPU HWP + break; + + case OEM3_SSDT_TABLE_SIGNATURE: + Status =3D PatchOem3SsdtTable (Table); //CPU TST + break; + + case OEM4_SSDT_TABLE_SIGNATURE: + Status =3D PatchOem4SsdtTable (Table); //CPU CST + break; + case ACPI_WSMT_SIGNATURE: + (((ACPI_WINDOWS_SMM_SECURITY_MITIGATIONS_TABLE *)Table)->ProtectionFla= gs.Flags) =3D (UINT32 ) (WSMT_PROTECTION_FLAG & PcdGet32(PcdWsmtProtectionF= lags)); + DEBUG ((DEBUG_INFO, "[WSMT] ProtectionFlags =3D 0x%x\n", (((ACPI_WINDOWS= _SMM_SECURITY_MITIGATIONS_TABLE *)Table)->ProtectionFlags.Flags))); + break; + + default: + // + // Hooks for Platform only table. If the ACPI Table is Platform only, = add this table in below hook. then continue to update other Table. + // + Status =3D PatchPlatformSpecificAcpiTableHooks (Table); + break; + } + // + // + // Update the hardware signature in the FACS structure + // + // + // + return Status; +} + +/** + Give the platform a chance to build tables. + + Some tables can be built from scratch more efficiently than being prebui= lt + and updated. This function builds any such tables for the platform. + + @retval EFI_SUCCESS Any platform tables were successfully built. +**/ +EFI_STATUS +PlatformBuildTables ( + VOID + ) +{ + EFI_STATUS ReturnStatus =3D EFI_SUCCESS; + EFI_STATUS Status; + + Status =3D InstallMadtFromScratch (); + if (EFI_ERROR (Status)) { + ReturnStatus =3D Status; + } + + if (mSocketCommonRcConfiguration.NumaEn) { + Status =3D InstallSlitTable (); + if (EFI_ERROR (Status)) { + ReturnStatus =3D Status; + } + + Status =3D InstallSratTable (); + if (EFI_ERROR (Status)) { + ReturnStatus =3D Status; + } + } + // + // Return the first error code that occured, or success. + // + return ReturnStatus; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLi= b/AcpiPlatformLib.inf b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlat= formTableLib/AcpiPlatformLib.inf new file mode 100644 index 0000000000..c571871930 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiP= latformLib.inf @@ -0,0 +1,127 @@ +## @file +# Library functions for ACPI Table Update library. +# +# @copyright +# Copyright 2015 - 2020 Intel Corporation.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +##########################################################################= ###### +# +# Defines Section - statements that will be processed to create a Makefile. +# +##########################################################################= ###### +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D AcpiPlatformTableLib + FILE_GUID =3D 09114814-BF6D-4B2D-BD61-C1F0668DE06E + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D AcpiPlatformTableLib + CONSTRUCTOR =3D AcpiPlatformLibConstructor + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D X64 +# + +##########################################################################= ###### +# +# Sources Section - list of files that are required for the build to succe= ed. +# +##########################################################################= ###### + +[Sources] + AcpiPlatformLibApic.c + AcpiPlatformLibBdat.c + AcpiPlatformLibDsdt.c + AcpiPlatformLibFadt.c + AcpiPlatformLibMcfg.c + AcpiPlatformLibMsct.c + AcpiPlatformLib.c + AcpiPlatformLibLocal.h + AcpiPlatformLibNfit.c + AcpiPlatformLibPcat.c + AcpiPlatformLibSlit.c + AcpiPlatformLibSrat.c + AcpiPlatformLibSsdt.c + AcpiPlatformLibMigt.c + AcpiPlatformLibPmtt.c + AcpiPlatformLibHmat.c + +##########################################################################= ###### +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +##########################################################################= ###### + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + WhitleyOpenBoardPkg/PlatformPkg.dec + WhitleySiliconPkg/SiliconPkg.dec + WhitleySiliconPkg/CpRcPkg.dec + WhitleySiliconPkg/Cpu/CpuRcPkg.dec + WhitleySiliconPkg/WhitleySiliconPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + PcdLib + MemoryAllocationLib + BuildAcpiTablesLib + CrcLib + UbaPlatLib + PlatformSpecificAcpiTableLib + CompressDxeLib + UefiDecompressLib + +[Protocols] + gDxePchPlatformPolicyProtocolGuid + gEfiNfitTableUpdateProtocolGuid + gSmbiosMemInfoProtocolGuid + gAcpiPlatformProtocolGuid + gEfiSmbiosProtocolGuid + gEfiCpuCsrAccessGuid + gDynamicSiLibraryProtocolGuid ## CONSUMES + gDynamicSiLibraryProtocol2Guid ## CONSUMES + +[Guids] + gEfiPlatformInfoGuid + gFpgaSocketVariableGuid + gEwlBdatSchemaGuid + gSpdBdatSchemaGuid + gSpdVersion1Guid + gSpdVariableGuid + gMemTrainingDataBdatSchemaGuid + gMemTrainingDataVersion1Guid + gMemTrainingDataHobGuid + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision + gPlatformTokenSpaceGuid.ReservedB + gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress + gOemSkuTokenSpaceGuid.PcdOemSkuAcpiName + gPlatformTokenSpaceGuid.PcdPlatformNotSupportAcpiTable + gPlatformTokenSpaceGuid.PcdPlatformNotSupportAcpiBdatTable + gPlatformModuleTokenSpaceGuid.PcdWsmtProtectionFlags + gPlatformTokenSpaceGuid.PcdHalfWidth + gCpuPkgTokenSpaceGuid.PcdCpuConfigContextBuffer ## CONSUMES + +[FixedPcd] + gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuSocketCount + gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuCoreCount + gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuThreadCount + gEfiCpRcPkgTokenSpaceGuid.SaveSpdToBdat + gEfiCpRcPkgTokenSpaceGuid.SaveMrcTrainingDataToBdat + +[Depex] + gDynamicSiLibraryProtocolGuid AND + gDynamicSiLibraryProtocol2Guid diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLi= b/AcpiPlatformLibApic.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPl= atformTableLib/AcpiPlatformLibApic.c new file mode 100644 index 0000000000..0718e81682 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiP= latformLibApic.c @@ -0,0 +1,735 @@ +/** @file + ACPI Platform Driver Hooks + + @copyright + Copyright 1996 - 2020 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// Statements that include other files +// +#include "AcpiPlatformLibLocal.h" + +extern EFI_PLATFORM_INFO *mPlatformInfo; +extern BIOS_ACPI_PARAM *mAcpiParameter; +extern EFI_ACPI_TABLE_PROTOCOL *mAcpiTable; +EFI_IIO_UDS_PROTOCOL *mIioUds =3D NULL; + +extern UINT32 mNumOfBitShift; + +extern BOOLEAN mX2ApicEnabled; +BOOLEAN mCpuOrderSorted =3D FALSE; + +extern CPU_CSR_ACCESS_VAR *mCpuCsrAccessVarPtr; +EFI_MP_SERVICES_PROTOCOL *mMpService; +CPU_ID_ORDER_MAP mCpuApicIdOrderTable[MAX_CPU_NUM]; +UINTN mNumberOfCPUs =3D 0; +UINTN mNumberOfEnabledCPUs =3D 0; + +UINT32 mEnabledProcessor[MAX_SOCKET]; + +extern UINT32 mCpuPCPSInfo[MAX_SOCKET]; +extern CPU_LOGICAL_THREAD_ID_TABLE mCpuThreadIdMsrTable[MAX_CPU_NUM]; + + +UINT32 mApicIdMap[MAX_SOCKET][MAX_CORE * MAX_THREAD]; + +UINT32 mThreadCount[MAX_SOCKET] =3D {0}; + +typedef struct { + UINT64 EnableMask; + UINT8 Id; + UINT32 GsiBase; +} IO_APIC_DESCRIPTOR; + +STATIC CONST IO_APIC_DESCRIPTOR IoApicDescList[] =3D { + {PCH_IOAPIC, PCH_IOAPIC_ID, PCH_INTERRUPT_BASE}, + {PC00_IOAPIC, PC00_IOAPIC_ID, PC00_INTERRUPT_BASE}, + {PC01_IOAPIC, PC01_IOAPIC_ID, PC01_INTERRUPT_BASE}, + {PC02_IOAPIC, PC02_IOAPIC_ID, PC02_INTERRUPT_BASE}, + {PC03_IOAPIC, PC03_IOAPIC_ID, PC03_INTERRUPT_BASE}, + {PC04_IOAPIC, PC04_IOAPIC_ID, PC04_INTERRUPT_BASE}, + {PC05_IOAPIC, PC05_IOAPIC_ID, PC05_INTERRUPT_BASE}, + {PC06_IOAPIC, PC06_IOAPIC_ID, PC06_INTERRUPT_BASE}, + {PC07_IOAPIC, PC07_IOAPIC_ID, PC07_INTERRUPT_BASE}, + {PC08_IOAPIC, PC08_IOAPIC_ID, PC08_INTERRUPT_BASE}, + {PC09_IOAPIC, PC09_IOAPIC_ID, PC09_INTERRUPT_BASE}, + {PC10_IOAPIC, PC10_IOAPIC_ID, PC10_INTERRUPT_BASE}, + {PC11_IOAPIC, PC11_IOAPIC_ID, PC11_INTERRUPT_BASE}, + {PC12_IOAPIC, PC12_IOAPIC_ID, PC12_INTERRUPT_BASE}, + {PC13_IOAPIC, PC13_IOAPIC_ID, PC13_INTERRUPT_BASE}, + {PC14_IOAPIC, PC14_IOAPIC_ID, PC14_INTERRUPT_BASE}, + {PC15_IOAPIC, PC15_IOAPIC_ID, PC15_INTERRUPT_BASE}, + {PC16_IOAPIC, PC16_IOAPIC_ID, PC16_INTERRUPT_BASE}, + {PC17_IOAPIC, PC17_IOAPIC_ID, PC17_INTERRUPT_BASE}, + {PC18_IOAPIC, PC18_IOAPIC_ID, PC18_INTERRUPT_BASE}, + {PC19_IOAPIC, PC19_IOAPIC_ID, PC19_INTERRUPT_BASE}, + {PC20_IOAPIC, PC20_IOAPIC_ID, PC20_INTERRUPT_BASE}, + {PC21_IOAPIC, PC21_IOAPIC_ID, PC21_INTERRUPT_BASE}, + {PC22_IOAPIC, PC22_IOAPIC_ID, PC22_INTERRUPT_BASE}, + {PC23_IOAPIC, PC23_IOAPIC_ID, PC23_INTERRUPT_BASE}, + {PC24_IOAPIC, PC24_IOAPIC_ID, PC24_INTERRUPT_BASE}, + {PC25_IOAPIC, PC25_IOAPIC_ID, PC25_INTERRUPT_BASE}, + {PC26_IOAPIC, PC26_IOAPIC_ID, PC26_INTERRUPT_BASE}, + {PC27_IOAPIC, PC27_IOAPIC_ID, PC27_INTERRUPT_BASE}, + {PC28_IOAPIC, PC28_IOAPIC_ID, PC28_INTERRUPT_BASE}, + {PC29_IOAPIC, PC29_IOAPIC_ID, PC29_INTERRUPT_BASE}, + {PC30_IOAPIC, PC30_IOAPIC_ID, PC30_INTERRUPT_BASE}, + {PC31_IOAPIC, PC31_IOAPIC_ID, PC31_INTERRUPT_BASE}, + {PC32_IOAPIC, PC32_IOAPIC_ID, PC32_INTERRUPT_BASE}, + {PC33_IOAPIC, PC33_IOAPIC_ID, PC33_INTERRUPT_BASE}, + {PC34_IOAPIC, PC34_IOAPIC_ID, PC34_INTERRUPT_BASE}, + {PC35_IOAPIC, PC35_IOAPIC_ID, PC35_INTERRUPT_BASE}, + {PC36_IOAPIC, PC36_IOAPIC_ID, PC36_INTERRUPT_BASE}, + {PC37_IOAPIC, PC37_IOAPIC_ID, PC37_INTERRUPT_BASE}, + {PC38_IOAPIC, PC38_IOAPIC_ID, PC38_INTERRUPT_BASE}, + {PC39_IOAPIC, PC39_IOAPIC_ID, PC39_INTERRUPT_BASE}, + {PC40_IOAPIC, PC40_IOAPIC_ID, PC40_INTERRUPT_BASE}, + {PC41_IOAPIC, PC41_IOAPIC_ID, PC41_INTERRUPT_BASE}, + {PC42_IOAPIC, PC42_IOAPIC_ID, PC42_INTERRUPT_BASE}, + {PC43_IOAPIC, PC43_IOAPIC_ID, PC43_INTERRUPT_BASE}, + {PC44_IOAPIC, PC44_IOAPIC_ID, PC44_INTERRUPT_BASE}, + {PC45_IOAPIC, PC45_IOAPIC_ID, PC45_INTERRUPT_BASE}, + {PC46_IOAPIC, PC46_IOAPIC_ID, PC46_INTERRUPT_BASE}, + {PC47_IOAPIC, PC47_IOAPIC_ID, PC47_INTERRUPT_BASE} +}; + +/** + Find OrderTable index which is matching input ApicId + + @param ApicId - input ApicId + + @retval Index - OrderTable index + @retval (UINT32) -1 - Not found +**/ +UINT32 +ApicId2OrderTableIndex ( + UINT32 ApicId + ) +{ + UINT32 Index; + + for (Index =3D 0; Index < MAX_CPU_NUM; Index++) { + if ((mCpuApicIdOrderTable[Index].Flags =3D=3D 1) && (mCpuApicIdOrderTa= ble[Index].ApicId =3D=3D ApicId)) { + return Index; + } + } + + return (UINT32) -1; +} + +/** + Display reordered Apic table for detected CPUs. + + @param None + + @retval None +**/ +VOID +DebugDisplayReOrderTable ( + VOID + ) +{ + UINT32 Index; + UINT32 TotalEnabledThreads =3D 0; + + DEBUG ((DEBUG_INFO, "Index AcpiProcId ApicId Flags Skt\n")); + for (Index =3D 0; Index < MAX_CPU_NUM; Index++) { + if (mCpuApicIdOrderTable[Index].ApicId =3D=3D (UINT32) -1) { + break; + } + TotalEnabledThreads++; + DEBUG ((DEBUG_INFO, " %02d 0x%02X 0x%02X %d %d\n", + Index, mCpuApicIdOrderTable[Index].AcpiProcesso= rId, + mCpuApicIdOrderTable[Index].ApicId, + mCpuApicIdOrderTable[Index].Flags, + mCpuApicIdOrderTable[Index].SocketNum)); + } + DEBUG ((DEBUG_INFO, "\n:ACPI: Total Enabled Threads =3D %d\n\n", TotalEn= abledThreads)); +} + +/** + Consolidate APIC ID order for all populated socket in mApicIdMap table + + @param None + + @retval None +**/ +VOID +UpdateApicIdMap ( + VOID + ) +{ + UINT32 SocketId; + UINT32 ThreadIndex; + UINT32 CurrProcessor; + + // + // init global mApicIdMap variable + // + SetMem32 ((VOID *)mApicIdMap, sizeof(mApicIdMap), 0xFFFFFFFF); + + for (SocketId =3D 0; SocketId < MAX_SOCKET; SocketId++) { + if ((mCpuCsrAccessVarPtr->socketPresentBitMap & (1 << SocketId)) =3D= =3D 0) { + continue; + } + + ThreadIndex =3D 0; + for (CurrProcessor =3D 0; CurrProcessor < MAX_CPU_NUM; CurrProcessor++= ) { + if (mCpuApicIdOrderTable[CurrProcessor].ApicId =3D=3D (UINT32) -1) { + break; + } + + if ((mCpuApicIdOrderTable[CurrProcessor].SocketNum =3D=3D SocketId) = && (ThreadIndex < (MAX_CORE * MAX_THREAD))) { + mApicIdMap[SocketId][ThreadIndex] =3D (UINT32) mCpuApicIdOrderTabl= e[CurrProcessor].ApicId & (UINT32) ~(SocketId<< mNumOfBitShift); + ThreadIndex++; + } + } + + if (ThreadIndex !=3D mThreadCount[SocketId]) { + DEBUG((DEBUG_ERROR, ":: Skt: %d - Enabled ThreadCount is incorrect!!= !\n")); + break; + } + } + + return; +} + +/** + Find the processor index of the thread running and obtain MSR 53 and Api= cId data + to populate mCpuThreadIdMsrTable array. + + @param None + + @retval None +**/ +VOID +GetThreadIdMsrValue ( + VOID + ) +{ + UINTN ProcessorNumber; + UINT64 LogicalIdMsrValue; + + mMpService->WhoAmI (mMpService, &ProcessorNumber); + LogicalIdMsrValue =3D AsmReadMsr64 (0x00000053); + mCpuThreadIdMsrTable[ProcessorNumber].ThreadIdValue =3D (UINT32) Logical= IdMsrValue; + mCpuThreadIdMsrTable[ProcessorNumber].CollocatedChaId =3D (UINT32) RShif= tU64(LogicalIdMsrValue, 32); + mCpuThreadIdMsrTable[ProcessorNumber].ApicId =3D mCpuConfigLibConfigCont= extBuffer->CollectedDataBuffer[ProcessorNumber].CpuMiscData.ApicID; +} + +/** + Sort CPU Local APIC Information. + + This function gets the CPU local APIC information from the MP service + protocol into the local table structure, and sorts it based on APIC ID. + + @retval EFI_SUCCESS Local APIC information was successfully sorted. +**/ +EFI_STATUS +SortCpuLocalApicInTable ( + VOID + ) +{ + EFI_STATUS Status; + EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer; + UINTN BufferSize; + UINT32 Index; + UINT32 Socket; + UINT32 CurrProcessor; + CPU_ID_ORDER_MAP *CpuIdMapPtr; + UINT32 CoreThreadMask; + UINT32 CoreThreadCount; + UINT32 BspApicId; + UINT32 LowestApicId; + UINT32 CurrentIndex; + UINT32 TargetIndex; + CPU_ID_ORDER_MAP TempEntry; + BOOLEAN SecondThreadExistent; + + BufferSize =3D 0; + Index =3D 0; + Status =3D EFI_SUCCESS; + + CoreThreadMask =3D (UINT32) ((1 << mNumOfBitShift) - 1); + CoreThreadCount =3D 0; + + if (!mCpuOrderSorted) { + // + // Init ProcessorBitMask table and EnabledProcessor table + // + for (Index =3D 0; Index < MAX_SOCKET; Index++) { + mAcpiParameter->ProcessorBitMask[Index] =3D 0; + mAcpiParameter->ProcessorBitMaskHi[Index] =3D 0; + mEnabledProcessor[Index] =3D 0; + mCpuPCPSInfo[Index] =3D 0; + } + + Index =3D 0; + SecondThreadExistent =3D FALSE; + for (CurrProcessor =3D 0; CurrProcessor < mNumberOfCPUs; CurrProcessor= ++) { + Status =3D mMpService->GetProcessorInfo ( + mMpService, + CurrProcessor, + &ProcessorInfoBuffer + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + continue; + } + + + if (ProcessorInfoBuffer.ProcessorId & 1) { // secondary thread + CpuIdMapPtr =3D &mCpuApicIdOrderTable[(Index - 1) + MAX_CPU_NUM / = 2]; + SecondThreadExistent=3D TRUE; + } else { // primary thread + CpuIdMapPtr =3D &mCpuApicIdOrderTable[Index]; + Index++; + } + + CpuIdMapPtr->ApicId =3D (UINT32) ProcessorInfoBuffer.ProcessorId; + CpuIdMapPtr->Flags =3D ((ProcessorInfoBuffer.StatusFlag & PROCESSO= R_ENABLED_BIT) !=3D 0); + CpuIdMapPtr->SocketNum =3D (UINT32) ProcessorInfoBuffer.Location.Pac= kage; + CpuIdMapPtr->AcpiProcessorId =3D (CpuIdMapPtr->SocketNum << mNumOfBi= tShift) + mThreadCount[CpuIdMapPtr->SocketNum]; + + mThreadCount[CpuIdMapPtr->SocketNum]++; + + if (CpuIdMapPtr->Flags =3D=3D 1) { + // + // Update EnabledProcessor table + // + mEnabledProcessor[CpuIdMapPtr->SocketNum]++; + mCpuPCPSInfo[CpuIdMapPtr->SocketNum]++; // count enabled processor= in current socket + + // + // Update processorbitMask + // + if (ProcessorInfoBuffer.Location.Core < 64) { + mAcpiParameter->ProcessorBitMask[CpuIdMapPtr->SocketNum] |=3D + LShiftU64 (1, ProcessorInfoBuffer.Location.Core); + } else { + mAcpiParameter->ProcessorBitMaskHi[CpuIdMapPtr->SocketNum] |=3D + LShiftU64 (1, ProcessorInfoBuffer.Location.Core - 64); + } + + if (ProcessorInfoBuffer.Location.Thread >=3D CoreThreadCount) { + CoreThreadCount =3D ProcessorInfoBuffer.Location.Thread + 1; + } + } + } //end for CurrentProcessor + + DEBUG (( + DEBUG_INFO, + "::ACPI:: APIC ID Order Table Init. CoreThreadMask =3D 0x%x, mN= umOfBitShift =3D %d, CoreThreadCount =3D %d\n", + CoreThreadMask, + mNumOfBitShift, + CoreThreadCount + )); + + DEBUG ((DEBUG_INFO, "::ACPI:: Socket ProcessorBitMaskHi ProcessorBit= Mask ProcessorApicIdBase\n")); + for (Index =3D 0; Index < MAX_SOCKET; Index++) { + DEBUG (( + DEBUG_INFO, + "::ACPI:: %d 0x%016lx %016lx 0x%x\n", + Index, + mAcpiParameter->ProcessorBitMaskHi[Index], + mAcpiParameter->ProcessorBitMask[Index], + mAcpiParameter->ProcessorApicIdBase[Index] + )); + } + AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, 1, NULL, NULL, NULL, &BspApicId); + + if (mCpuApicIdOrderTable[0].ApicId !=3D BspApicId) { + // + // check to see if 1st entry is BSP, if not swap it + // + CurrentIndex =3D ApicId2OrderTableIndex (BspApicId); + + if (CurrentIndex >=3D MAX_CPU_NUM) { + DEBUG ((DEBUG_ERROR, "BSP index is out of range\n")); + ASSERT (CurrentIndex < MAX_CPU_NUM); + } else { + LowestApicId =3D mCpuApicIdOrderTable[0].ApicId; + TargetIndex =3D 0; + CopyMem (&TempEntry, &mCpuApicIdOrderTable[CurrentIndex], sizeof(T= empEntry)); + CopyMem (&mCpuApicIdOrderTable[CurrentIndex], &mCpuApicIdOrderTabl= e[TargetIndex], sizeof(TempEntry)); + CopyMem (&mCpuApicIdOrderTable[TargetIndex], &TempEntry, sizeof(Te= mpEntry)); + + if (SecondThreadExistent) { + // + // Also swap BSP's companion thread (the second thread in same c= ore of BSP) + // + CurrentIndex =3D ApicId2OrderTableIndex (BspApicId + 1); + TargetIndex =3D ApicId2OrderTableIndex (LowestApicId + 1); + if ((CurrentIndex < MAX_CPU_NUM) && (TargetIndex < MAX_CPU_NUM))= { + CopyMem (&TempEntry, &mCpuApicIdOrderTable[CurrentIndex], size= of(TempEntry)); + CopyMem (&mCpuApicIdOrderTable[CurrentIndex], &mCpuApicIdOrder= Table[TargetIndex], sizeof(TempEntry)); + CopyMem (&mCpuApicIdOrderTable[TargetIndex], &TempEntry, sizeo= f(TempEntry)); + } + } + } + } + + // + // Make sure no holes between enabled threads + // + for (CurrProcessor =3D 0; CurrProcessor < MAX_CPU_NUM; CurrProcessor++= ) { + + if (mCpuApicIdOrderTable[CurrProcessor].Flags =3D=3D 0) { + // + // make sure disabled entry has ProcId set to FFs + // + mCpuApicIdOrderTable[CurrProcessor].ApicId =3D (UINT32) -1; + mCpuApicIdOrderTable[CurrProcessor].AcpiProcessorId =3D (UINT32) -= 1; + + for (Index =3D CurrProcessor + 1; Index < MAX_CPU_NUM; Index++) { + if (mCpuApicIdOrderTable[Index].Flags =3D=3D 1) { + // + // move enabled entry up + // + mCpuApicIdOrderTable[CurrProcessor].Flags =3D 1; + mCpuApicIdOrderTable[CurrProcessor].ApicId =3D mCpuApicIdOrder= Table[Index].ApicId; + mCpuApicIdOrderTable[CurrProcessor].AcpiProcessorId =3D mCpuAp= icIdOrderTable[Index].AcpiProcessorId; + mCpuApicIdOrderTable[CurrProcessor].SocketNum =3D mCpuApicIdOr= derTable[Index].SocketNum; + // + // disable moved entry + // + mCpuApicIdOrderTable[Index].Flags =3D 0; + mCpuApicIdOrderTable[Index].ApicId =3D (UINT32) -1; + mCpuApicIdOrderTable[Index].AcpiProcessorId =3D (UINT32) -1; + break; + } + } + } + } + + // + // keep for debug purpose + // + DEBUG ((DEBUG_INFO, "APIC ID Order Table ReOrdered\n")); + DebugDisplayReOrderTable (); + + // + // Re-sort AcpiProcessorId for all sockets + // + for (Socket =3D 0; Socket < MAX_SOCKET; Socket++) { + Index =3D 0; + + for (CurrProcessor =3D 0; CurrProcessor < MAX_CPU_NUM; CurrProcessor= ++) { + if (mCpuApicIdOrderTable[CurrProcessor].Flags && (mCpuApicIdOrderT= able[CurrProcessor].SocketNum =3D=3D Socket)) { + // + // re-assign AcpiProcessorId to match MADT (socket, thread) + // + mCpuApicIdOrderTable[CurrProcessor].AcpiProcessorId =3D (Socket = << mNumOfBitShift) + Index; + Index++; + } + } + } + + // + // keep for debug purpose + // + DEBUG ((DEBUG_INFO, "APIC ID Ord Tbl ReOrd aft Re-sort AcpiProcessorId= \n")); + DebugDisplayReOrderTable (); + + // + // Update mApicIdMap according the final mCpuApicIdOrderTable + // + UpdateApicIdMap (); + + for (Socket =3D 0; Socket < MAX_SOCKET; Socket++) { + for (Index=3D0; Index < (MAX_THREAD * MAX_CORE); Index++) { + if (mApicIdMap[Socket][Index] !=3D (UINT32) -1) { + DEBUG ((DEBUG_INFO, "mApicIdMap[%d][%d] =3D 0x%x\n", Socket, Ind= ex, mApicIdMap[Socket][Index])); + } + } + } + + // + // Initialize with safe defaults + // + for(CurrProcessor =3D 0; CurrProcessor < MAX_CPU_NUM; CurrProcessor++)= { + mCpuThreadIdMsrTable[CurrProcessor].ApicId =3D (UINT32)-1; + mCpuThreadIdMsrTable[CurrProcessor].ThreadIdValue =3D 0xFF; + mCpuThreadIdMsrTable[CurrProcessor].CollocatedChaId =3D 0xFF; + mCpuThreadIdMsrTable[CurrProcessor].SNCProximityDomain =3D 0; + } + // + // Collect MSR 53 value and ApicId for each thread + // + mMpService->StartupAllAPs (mMpService, (EFI_AP_PROCEDURE)GetThreadIdMs= rValue, FALSE, NULL, 0, NULL, NULL); + GetThreadIdMsrValue (); + + mCpuOrderSorted =3D TRUE; + } + + return Status; +} + +/** + Build from scratch and install the MADT. + + @retval EFI_SUCCESS The MADT was installed successfully. + @retval EFI_OUT_OF_RESOURCES Could not allocate required structures. +**/ +EFI_STATUS +InstallMadtFromScratch ( + VOID + ) +{ + EFI_STATUS Status; + UINTN Index; + EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *NewMadtTable; + UINTN TableHandle; + EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER MadtTableHeader; + EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_STRUCTURE ProcLocalApicStruct; + EFI_ACPI_6_2_IO_APIC_STRUCTURE IoApicStruct; + EFI_ACPI_6_2_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE IntSrcOverrideStruct; + EFI_ACPI_6_2_LOCAL_APIC_NMI_STRUCTURE LocalApciNmiStruct; + EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_STRUCTURE ProcLocalX2ApicStruc= t; + EFI_ACPI_6_2_LOCAL_X2APIC_NMI_STRUCTURE LocalX2ApicNmiStruct; + STRUCTURE_HEADER **MadtStructs; + UINTN MaxMadtStructCount; + UINTN MadtStructsIndex; + + NewMadtTable =3D NULL; + + MaxMadtStructCount =3D (UINT32) ( + MAX_CPU_NUM + // processor local APIC structures + MAX_CPU_NUM + // processor local x2APIC structures + MAX_IO_APICS_10NM + // IOAPIC structures + 2 + // interrupt source override structures + 1 + // local APIC NMI structures + 1 // local x2APIC NMI structures + ); // other structures are not used + + MadtStructs =3D (STRUCTURE_HEADER **) AllocateZeroPool (MaxMadtStructCou= nt * sizeof (STRUCTURE_HEADER *)); + if (MadtStructs =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "[ACPI](MADT) Could not allocate MADT structure p= ointer array\n")); + return EFI_OUT_OF_RESOURCES; + } + + // + // Initialize the next index into the structure pointer array. It is + // incremented every time a structure of any type is copied to the array. + // + MadtStructsIndex =3D 0; + + // + // Initialize MADT Header Structure + // + Status =3D InitializeMadtHeader (&MadtTableHeader); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "[ACPI](MADT) InitializeMadtHeader failed: %r\n",= Status)); + goto Done; + } + + DEBUG ((DEBUG_INFO, "[ACPI](MADT) Number of CPUs detected =3D %d \n", mN= umberOfCPUs)); + + // + // Build Processor Local APIC Structures and Processor Local X2APIC Stru= ctures + // + ProcLocalApicStruct.Type =3D EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC; + ProcLocalApicStruct.Length =3D sizeof (EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC= _STRUCTURE); + + ProcLocalX2ApicStruct.Type =3D EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC; + ProcLocalX2ApicStruct.Length =3D sizeof (EFI_ACPI_6_2_PROCESSOR_LOCAL_X2= APIC_STRUCTURE); + ProcLocalX2ApicStruct.Reserved[0] =3D 0; + ProcLocalX2ApicStruct.Reserved[1] =3D 0; + + for (Index =3D 0; Index < mNumberOfCPUs; Index++) { + // + // If x2APIC mode is not enabled, and if it is possible to express the + // APIC ID as a UINT8, use a processor local APIC structure. Otherwise, + // use a processor local x2APIC structure. + // + if (!mX2ApicEnabled && mCpuApicIdOrderTable[Index].ApicId < MAX_UINT8)= { + ProcLocalApicStruct.Flags =3D (UINT8) mCpuApicIdOrderTable= [Index].Flags; + ProcLocalApicStruct.ApicId =3D (UINT8) mCpuApicIdOrderTable= [Index].ApicId; + ProcLocalApicStruct.AcpiProcessorUid =3D (UINT8) mCpuApicIdOrderTabl= e[Index].AcpiProcessorId; + + ASSERT (MadtStructsIndex < MaxMadtStructCount); + Status =3D CopyStructure ( + &MadtTableHeader.Header, + (STRUCTURE_HEADER *) &ProcLocalApicStruct, + &MadtStructs[MadtStructsIndex++] + ); + } else { + ProcLocalX2ApicStruct.Flags =3D (UINT8) mCpuApicIdOrderTa= ble[Index].Flags; + ProcLocalX2ApicStruct.X2ApicId =3D mCpuApicIdOrderTable[Inde= x].ApicId; + ProcLocalX2ApicStruct.AcpiProcessorUid =3D mCpuApicIdOrderTable[Inde= x].AcpiProcessorId; + + ASSERT (MadtStructsIndex < MaxMadtStructCount); + Status =3D CopyStructure ( + &MadtTableHeader.Header, + (STRUCTURE_HEADER *) &ProcLocalX2ApicStruct, + &MadtStructs[MadtStructsIndex++] + ); + } + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "[ACPI](MADT) CopyMadtStructure (local APIC/x2A= PIC) failed: %r\n", Status)); + goto Done; + } + } + + // + // Build IOAPIC Structures + // + if (mIioUds =3D=3D NULL) { + Status =3D gBS->LocateProtocol (&gEfiIioUdsProtocolGuid,NULL,&mIioUds); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + goto Done; + } + } + + IoApicStruct.Type =3D EFI_ACPI_6_2_IO_APIC; + IoApicStruct.Length =3D sizeof (EFI_ACPI_6_2_IO_APIC_STRUCTURE); + IoApicStruct.Reserved =3D 0; + IoApicStruct.IoApicId =3D PCH_IOAPIC_ID; + IoApicStruct.IoApicAddress =3D mIioUds->IioUdsPtr->PlatformData.IIO_res= ource[0].StackRes[0].IoApicBase; + IoApicStruct.GlobalSystemInterruptBase =3D PCH_INTERRUPT_BASE; + ASSERT (MadtStructsIndex < MaxMadtStructCount); + Status =3D CopyStructure ( + &MadtTableHeader.Header, + (STRUCTURE_HEADER *) &IoApicStruct, + &MadtStructs[MadtStructsIndex++] + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "[ACPI](MADT) CopyMadtStructure (IOAPIC) failed: = %r\n", Status)); + goto Done; + } + DEBUG ((DEBUG_INFO, "[ACPI](MADT) Add IOAPIC id %d, addr 0x%x, Interrupt= base %d for PCH\n", IoApicStruct.IoApicId, IoApicStruct.IoApicAddress, IoA= picStruct.GlobalSystemInterruptBase)); + + // + // Build Interrupt Source Override Structures + // + IntSrcOverrideStruct.Type =3D EFI_ACPI_6_2_INTERRUPT_SOURCE_OVERRIDE; + IntSrcOverrideStruct.Length =3D sizeof (EFI_ACPI_6_2_INTERRUPT_SOURCE_OV= ERRIDE_STRUCTURE); + + // + // IRQ0=3D>IRQ2 Interrupt Source Override Structure + // + IntSrcOverrideStruct.Bus =3D 0x0; // Bus - ISA + IntSrcOverrideStruct.Source =3D 0x0; // Source - IRQ0 + IntSrcOverrideStruct.GlobalSystemInterrupt =3D 0x2; // Global System Int= errupt - IRQ2 + IntSrcOverrideStruct.Flags =3D 0x0; // Flags - Conforms = to specifications of the bus + + ASSERT (MadtStructsIndex < MaxMadtStructCount); + Status =3D CopyStructure ( + &MadtTableHeader.Header, + (STRUCTURE_HEADER *) &IntSrcOverrideStruct, + &MadtStructs[MadtStructsIndex++] + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "[ACPI](MADT) CopyMadtStructure (IRQ2 source over= ride) failed: %r\n", Status)); + goto Done; + } + + // + // IRQ9 (SCI Active High) Interrupt Source Override Structure + // + IntSrcOverrideStruct.Bus =3D 0x0; // Bus - ISA + IntSrcOverrideStruct.Source =3D 0x9; // Source - IRQ9 + IntSrcOverrideStruct.GlobalSystemInterrupt =3D 0x9; // Global System Int= errupt - IRQ9 + IntSrcOverrideStruct.Flags =3D 0xD; // Flags - Level-tig= gered, Active High + + ASSERT (MadtStructsIndex < MaxMadtStructCount); + Status =3D CopyStructure ( + &MadtTableHeader.Header, + (STRUCTURE_HEADER *) &IntSrcOverrideStruct, + &MadtStructs[MadtStructsIndex++] + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "[ACPI](MADT) CopyMadtStructure (IRQ9 source over= ride) failed: %r\n", Status)); + goto Done; + } + + // + // Build Local APIC NMI Structures + // + LocalApciNmiStruct.Type =3D EFI_ACPI_6_2_LOCAL_APIC_NMI; + LocalApciNmiStruct.Length =3D sizeof (EFI_ACPI_6_2_LOCAL_APIC_NMI_STRUCT= URE); + LocalApciNmiStruct.AcpiProcessorUid =3D 0xFF; // Applies to all pro= cessors + LocalApciNmiStruct.Flags =3D POLARITY_ACTIVE_HIGH | TRIGGERMODE_EDGE; /= / Flags - Edge-tiggered, Active High + LocalApciNmiStruct.LocalApicLint =3D 0x1; + + ASSERT (MadtStructsIndex < MaxMadtStructCount); + Status =3D CopyStructure ( + &MadtTableHeader.Header, + (STRUCTURE_HEADER *) &LocalApciNmiStruct, + &MadtStructs[MadtStructsIndex++] + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "[ACPI](MADT) CopyMadtStructure (APIC NMI) failed= : %r\n", Status)); + goto Done; + } + + // + // Build Local x2APIC NMI Structure + // + LocalX2ApicNmiStruct.Type =3D EFI_ACPI_6_2_LOCAL_X2APIC_NMI; + LocalX2ApicNmiStruct.Length =3D sizeof (EFI_ACPI_6_2_LOCAL_X2APIC_NMI_ST= RUCTURE); + LocalX2ApicNmiStruct.Flags =3D POLARITY_ACTIVE_HIGH | TRIGGERMODE_EDGE;= // Flags - Edge-tiggered, Active High + LocalX2ApicNmiStruct.AcpiProcessorUid =3D 0xFFFFFFFF; // Applies to all= processors + LocalX2ApicNmiStruct.LocalX2ApicLint =3D 0x01; + LocalX2ApicNmiStruct.Reserved[0] =3D 0x00; + LocalX2ApicNmiStruct.Reserved[1] =3D 0x00; + LocalX2ApicNmiStruct.Reserved[2] =3D 0x00; + + ASSERT (MadtStructsIndex < MaxMadtStructCount); + Status =3D CopyStructure ( + &MadtTableHeader.Header, + (STRUCTURE_HEADER *) &LocalX2ApicNmiStruct, + &MadtStructs[MadtStructsIndex++] + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "[ACPI](MADT) CopyMadtStructure (x2APIC NMI) fail= ed: %r\n", Status)); + goto Done; + } + + // + // Build Madt Structure from the Madt Header and collection of pointers = in MadtStructs[] + // + Status =3D BuildAcpiTable ( + (EFI_ACPI_DESCRIPTION_HEADER *) &MadtTableHeader, + sizeof (EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER), + MadtStructs, + MadtStructsIndex, + (UINT8 **)&NewMadtTable + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "[ACPI](MADT) BuildAcpiTable failed: %r\n", Statu= s)); + goto Done; + } + + // + // Publish Madt Structure to ACPI + // + Status =3D mAcpiTable->InstallAcpiTable ( + mAcpiTable, + NewMadtTable, + NewMadtTable->Header.Length, + &TableHandle + ); + +Done: + // + // Free memory + // + for (MadtStructsIndex =3D 0; MadtStructsIndex < MaxMadtStructCount; Madt= StructsIndex++) { + if (MadtStructs[MadtStructsIndex] !=3D NULL) { + FreePool (MadtStructs[MadtStructsIndex]); + } + } + + FreePool (MadtStructs); + + if (NewMadtTable !=3D NULL) { + FreePool (NewMadtTable); + } + + return Status; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLi= b/AcpiPlatformLibBdat.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPl= atformTableLib/AcpiPlatformLibBdat.c new file mode 100644 index 0000000000..09464b4a11 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiP= latformLibBdat.c @@ -0,0 +1,1574 @@ +/** @file + ACPI Platform Driver Hooks + + @copyright + Copyright 1996 - 2020 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// Statements that include other files +// +#include "AcpiPlatformLibLocal.h" +#include +#include +#include +#include +#include +#include + +extern struct SystemMemoryMapHob *mSystemMemoryMap; +extern EFI_IIO_UDS_PROTOCOL *mIioUds; + +#include + +#ifndef MAX_HOB_ENTRY_SIZE +#define MAX_HOB_ENTRY_SIZE 60*1024 +#endif + +/** + Save BSSA results to BDAT + + @param[in,out] BdatHeaderStructPtr - Pointer to BDAT Structure + @param[in] OffsetFromLastSchema- Offset (in bytes) from the last s= chema. Need it to update the schema offsets array. + @param[in] SchemaStartAddress - Starting address where the BSSA r= esult schema will be added + @param[in, out] SchemaIndex - Current schema index inside the B= DAT. Need it to update the schema offsets array. + @param[in] SchemaSize - The size of the BSSA results sche= ma. + @param[out] SchemaSpaceUsed - The numebr bytes were filled in a= ll schema + @param[out] LastSchemaSpaceUsed - The numebr bytes were filled in t= he last schema + + @retval EFI_SUCCESS - BSSA BDAT scehma created successfully + @retval !EFI_SUCCESS - BSSA BDAT scehma creation failed +**/ +EFI_STATUS +SaveBssaResultsToBdat ( + IN OUT BDAT_STRUCTURE *BdatHeaderStructPtr, + IN UINT32 OffsetFromLastSchema, + IN EFI_PHYSICAL_ADDRESS *SchemaStartAddress, + IN OUT UINT8 *SchemaIndex, + IN UINT32 SchemaSize, + OUT UINT32 *SchemaSpaceUsed, + OUT UINT32 *LastSchemaSpaceUsed + ); + +/** + Save EWL results to BDAT + + @param[in,out] BdatHeaderStructPtr - Pointer to BDAT Structure + @param[in] OffsetFromLastSchema- Offset (in bytes) from the last s= chema. Need it to update the schema offsets array. + @param[in] SchemaStartAddress - Starting address where the EWL sc= hema will be added + @param[in, out] SchemaIndex - Current schema index inside the B= DAT. Need it to update the schema offsets array. + @param[out] SchemaSpaceUsed - The numebr bytes were filled + + @retval EFI_SUCCESS - EWL BDAT scehma created successfully + @retval !EFI_SUCCESS - EWL BDAT scehma creation failed +**/ +EFI_STATUS +SaveEwlToBdat ( + IN OUT BDAT_STRUCTURE *BdatHeaderStructPtr, + IN UINT32 OffsetFromLastSchema, + IN EFI_PHYSICAL_ADDRESS *SchemaStartAddress, + IN OUT UINT8 *SchemaIndex, + OUT UINT32 *SchemaSpaceUsed + ); + +/** + Save SPD date structure to BDAT + + @param[in,out] BdatHeaderStructPtr - Pointer to BDAT Structure + @param[in] OffsetFromLastSchema- Offset (in bytes) from the last s= chema. Need it to update the schema offsets array. + @param[in] SchemaStartAddress - Starting address where the SPD da= ta schema will be added + @param[in, out] SchemaIndex - Current schema index inside the B= DAT. Need it to update the schema offsets array. + @param[out] SchemaSpaceUsed - The numebr bytes were filled + + @retval EFI_SUCCESS - SPD BDAT scehma created successfully + @retval !EFI_SUCCESS - SPD BDAT scehma creation failed +**/ +EFI_STATUS +SaveSpdToBdat ( + IN OUT BDAT_STRUCTURE *BdatHeaderStructPtr, + IN UINT32 OffsetFromLastSchema, + IN EFI_PHYSICAL_ADDRESS *SchemaStartAddress, + IN OUT UINT8 *SchemaIndex, + OUT UINT32 *SchemaSpaceUsed + ); + +/** + Save memory training date structure to BDAT + + @param[in,out] BdatHeaderStructPtr - Pointer to BDAT Structure + @param[in] OffsetFromLastSchema- Offset (in bytes) from the last s= chema. Need it to update the schema offsets array. + @param[in] SchemaStartAddress - Starting address where the memory= training data schema will be added + @param[in, out] SchemaIndex - Current schema index inside the B= DAT. Need it to update the schema offsets array. + @param[out] SchemaSpaceUsed - The numebr bytes were filled + + @retval EFI_SUCCESS - Memory training data BDAT scehma created successf= ully + @retval !EFI_SUCCESS - Memory training data BDAT scehma creation failed +**/ +EFI_STATUS +SaveTrainingDataToBdat ( + IN OUT BDAT_STRUCTURE *BdatHeaderStructPtr, + IN UINT32 OffsetFromLastSchema, + IN EFI_PHYSICAL_ADDRESS *SchemaStartAddress, + IN OUT UINT8 *SchemaIndex, + OUT UINT32 *SchemaSpaceUsed + ); + +/** + Get the size of SPD data structure not include the SPD BDAT schema heade= r. + + @retval UINT32 - Size of SPD data structure in bytes +**/ +UINT32 +GetSpdDataSize ( + VOID + ); + +/** + Read the SPD data for one dimm and fill up SPD entry inside SPD BDAT sch= ema space. + + @param[out] Address - Start Address of the buffer where the SP= D entry to be filled + @param[in] Socket - Socket number + @param[in] Channel - Channel number inside the Socket + @param[in] Dimm - Dimm slot number + @param[in] MaxSpdByteOffset - The max SPD byte offset. DDR4 is 512 + + @retval EFI_SUCCESS - SPD Structure filled successfully + @retval !EFI_SUCCESS - SPD structure creation failed +**/ +EFI_STATUS +FillSpdPerDimmEntry ( + OUT EFI_PHYSICAL_ADDRESS Address, + IN UINT8 Socket, + IN UINT8 Channel, + IN UINT8 Dimm, + IN UINT16 MaxSpdByteOffset + ); + +/** + Fill the SPD data structure inside the BDAT schema space. + + @param[out] StartAddress - Start Address of the buffer where S= PD data structure to be filled + @param[in] SpdDataSize - Size of SPD data structure includes= the header + + @retval EFI_SUCCESS - SPD Structure filled successfully + @retval !EFI_SUCCESS - SPD structure creation failed +**/ +EFI_STATUS +FillSpdSchema ( + OUT EFI_PHYSICAL_ADDRESS StartAddress, + IN UINT32 SpdDataSize + ); + +/** + Displays SPD content for debugging. + + @param[in] Address - The starting address of the SPD entry + + @retval N/A +**/ +VOID +DisplaySpdContents ( + IN EFI_PHYSICAL_ADDRESS Address + ); + +/** + Get Number of Schemas From BSSA HOB + + @retval UINT16 - Number of BSSA Schemas +**/ +UINT16 +GetNumberOfSchemasFromBssaHob ( + VOID + ) +{ + UINT32 GuidIdx =3D 0; + UINT16 NumberOfBssaSchemas =3D 0; + EFI_STATUS Status =3D EFI_SUCCESS; + DYNAMIC_SI_LIBARY_PROTOCOL *DynamicSiLibraryProtocol =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, &D= ynamicSiLibraryProtocol); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return 0; + } + + if (mSystemMemoryMap =3D=3D NULL) { + mSystemMemoryMap =3D DynamicSiLibraryProtocol->GetSystemMemoryMapData = (); + } + + ASSERT (mSystemMemoryMap !=3D NULL); + if (mSystemMemoryMap =3D=3D NULL) { + return 0; + } + + for (GuidIdx =3D 0; GuidIdx < mSystemMemoryMap->Reserved9; GuidIdx++) { + // + // No. of HOBS per GUID added up for all GUIDs created from calls to s= aveToBdat () + // + NumberOfBssaSchemas +=3D mSystemMemoryMap->Reserved7[GuidIdx]; + DEBUG ((DEBUG_VERBOSE, "GuidIdx =3D %d, total num hobs: %d\n", GuidIdx= , mSystemMemoryMap->Reserved7[GuidIdx])); + } + return NumberOfBssaSchemas; +} + +/** + Create BDAT Header with necessary information. + Allocate memory with BdatSize and if failure return status. + If Success return the pointer address for copying the schema information + + @param[out] BdatHeaderStructPtr - Pointer to BDAT Structure + @param[in] BdatSize - Size of BDAT Structure + @param[in] NumberOfSchema - Total nunber of of schema + + @retval EFI_SUCCESS - BDAT Structure created successfully + @retval !EFI_SUCCESS - BDAT structure creation failed +**/ +EFI_STATUS +CreateBdatHeader ( + OUT BDAT_STRUCTURE **BdatHeaderStructPtr, + IN UINT32 BdatSize, + IN UINT16 NumberOfSchema + ) +{ + EFI_TIME EfiTime; + UINT64 Address =3D 0xffffffff; + EFI_STATUS Status =3D EFI_SUCCESS; + + // + // Allocating RealTime Memory for BDAT. + // + + Status =3D gBS->AllocatePages ( + AllocateMaxAddress, + EfiACPIMemoryNVS, + EFI_SIZE_TO_PAGES(BdatSize), + &Address + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // The memory location where the HOB's are to be copied to + // + ZeroMem ((VOID *)Address, BdatSize); + + *BdatHeaderStructPtr =3D (BDAT_STRUCTURE *)Address; + + DEBUG ((DEBUG_VERBOSE, "\nBDAT Allocated Address =3D %x\n", Address)); + + // + // Create BIOS Data Signature + // + (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[0] =3D 'B'; + (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[1] =3D 'D'; + (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[2] =3D 'A'; + (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[3] =3D 'T'; + (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[4] =3D 'H'; + (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[5] =3D 'E'; + (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[6] =3D 'A'; + (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[7] =3D 'D'; + // + // Structure size + // + (*BdatHeaderStructPtr)->BdatHeader.BiosDataStructSize =3D BdatSize; + // + // Primary Version + // + (*BdatHeaderStructPtr)->BdatHeader.PrimaryVersion =3D BDAT_PRIMARY_VER; + // + // Secondary Version + // + (*BdatHeaderStructPtr)->BdatHeader.SecondaryVersion =3D BDAT_SECONDARY_V= ER; + // + // CRC16 value of the BDAT_STRUCTURE + // + (*BdatHeaderStructPtr)->BdatHeader.Crc16 =3D 0; + Status =3D CalculateCrc16 ( + (VOID *)(*BdatHeaderStructPtr), + BdatSize, + &(*BdatHeaderStructPtr)->BdatHeader.Crc16 + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + (*BdatHeaderStructPtr)->BdatHeader.Crc16 =3D 0xFFFF; + } + (*BdatHeaderStructPtr)->BdatSchemas.SchemaListLength =3D NumberOfSchema; + (*BdatHeaderStructPtr)->BdatSchemas.Reserved =3D 0; + (*BdatHeaderStructPtr)->BdatSchemas.Reserved1 =3D 0; + // + // Initialize the Time parameters in the SCHEMA_LIST_STRUCTURE + // + Status =3D gRT->GetTime (&EfiTime, NULL); + if (!EFI_ERROR (Status)) { + (*BdatHeaderStructPtr)->BdatSchemas.Year =3D EfiTime.Year; + (*BdatHeaderStructPtr)->BdatSchemas.Month =3D EfiTime.Month; + (*BdatHeaderStructPtr)->BdatSchemas.Day =3D EfiTime.Day; + (*BdatHeaderStructPtr)->BdatSchemas.Hour =3D EfiTime.Hour; + (*BdatHeaderStructPtr)->BdatSchemas.Minute =3D EfiTime.Minute; + (*BdatHeaderStructPtr)->BdatSchemas.Second =3D EfiTime.Second; + } + return Status; +} + +/** + Dump BDAT Table to serial log + + Example 1: There are 2 schema: BSSA RMT and EWL. + + Print BDAT Table + Address 0 1 2 3 4 5 6 7 8 9 A B = C D E F + 00000000 0x42 0x44 0x41 0x54 0x48 0x45 0x41 0x44 0x30 0x18 0x00 0x00 0xD= 7 0x7A 0x00 0x00 + 00000010 0x04 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0= 0 0x00 0x00 0x00 + 00000020 0x02 0x00 0x00 0x00 0xE4 0x07 0x08 0x0E 0x00 0x29 0x03 0x00 0x3= 4 0x00 0x00 0x00 + 00000030 0xFA 0x07 0x00 0x00 0x28 0xE9 0xF4 0x08 0x5F 0x0F 0xD4 0x46 0x8= 4 0x10 0x47 0x9F + 00000040 0xDA 0x27 0x9D 0xB6 0xC6 0x07 0x00 0x00 0x57 0x7F 0x00 0x00 0x0= 0 0x00 0x00 0xA5 + 00000050 0x98 0x88 0xFE 0x4C 0x00 0x00 0x00 0x0D 0xEB 0x7A 0x47 0x07 0xD= E 0x77 0x42 0xA4 + 00000060 0xE7 0x87 0x81 0x0B 0x10 0x00 0x31 0xF1 0x98 0x88 0xFE 0xF2 0x4= 5 0x81 0xD9 0xF4 + ... + ... + 000007F0 0x00 0x00 0x00 0x5A 0xA5 0x5A 0xA5 0x5A 0xA5 0x5A 0x2F 0x53 0xF= E 0xBF 0x3B 0xCA + 00000800 0x6C 0x41 0xA0 0xF6 0xFF 0xE4 0xE7 0x1E 0x3A 0x0D 0x36 0x10 0x0= 0 0x00 0x9F 0xEF + 00000810 0x70 0x33 0x71 0x75 0x05 0x38 0xB0 0x46 0x9F 0xED 0x60 0xF2 0x8= 2 0x48 0x6C 0xFC + 00000820 0x20 0x10 0x00 0x00 0x12 0x00 0x00 0x00 0x2E 0x81 0x50 0x51 0x0= 0 0x00 0x00 0x00 + 00000830 0x01 0x00 0x00 0x00 0x12 0x00 0x01 0x00 0x00 0x00 0x7E 0x07 0x1= 7 0x18 0x01 0xFF + 00000840 0xFF 0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0= 0 0x00 0x00 0x00 + + Example 2: There is 1 schema: EWL + Address 0 1 2 3 4 5 6 7 8 9 A B = C D E F + 00000000 0x42 0x44 0x41 0x54 0x48 0x45 0x41 0x44 0x66 0x10 0x00 0x00 0xA= 9 0x44 0x00 0x00 + 00000010 0x04 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0= 0 0x00 0x00 0x00 + 00000020 0x01 0x00 0x00 0x00 0xE4 0x07 0x08 0x0E 0x01 0x0F 0x2C 0x00 0x3= 0 0x00 0x00 0x00 + 00000030 0x2F 0x53 0xFE 0xBF 0x3B 0xCA 0x6C 0x41 0xA0 0xF6 0xFF 0xE4 0xE= 7 0x1E 0x3A 0x0D + 00000040 0x36 0x10 0x00 0x00 0x9F 0xEF 0x70 0x33 0x71 0x75 0x05 0x38 0xB= 0 0x46 0x9F 0xED + 00000050 0x60 0xF2 0x82 0x48 0x6C 0xFC 0x20 0x10 0x00 0x00 0x12 0x00 0x0= 0 0x00 0x2E 0x81 + 00000060 0x50 0x51 0x00 0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x12 0x00 0x0= 1 0x00 0x00 0x00 + 00000070 0x7E 0x07 0x17 0x18 0x01 0xFF 0xFF 0xFF 0x00 0x00 0x00 0x00 0x0= 0 0x00 0x00 0x00 + 00000080 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0= 0 0x00 0x00 0x00 + + @param[out] BdatHeaderStructPtr - Pointer to BDAT Structure + @param[in] BdatSize - Size of BDAT Structure + + @retval None +**/ +VOID +DumpBdatTable( + IN BDAT_STRUCTURE **BdatHeaderStructPtr, + IN UINT32 BdatSize +) +{ + UINT32 i =3D 0; + UINT8 *Table =3D NULL; + + Table =3D (UINT8 *)(*BdatHeaderStructPtr); + DEBUG ((DEBUG_VERBOSE, "\nPrint BDAT Table\n")); + + // + // Print address header + // + DEBUG ((DEBUG_VERBOSE, "Address ")); + for (i =3D 0; i < 16; i++) { + DEBUG ((DEBUG_VERBOSE, " %01x", i)); + } + + i =3D 0; + while (i < BdatSize) { + if ((i % 16) =3D=3D 0) { + DEBUG ((DEBUG_VERBOSE, "\n%08x ", (i / 16) * 16)); + } else { + DEBUG ((DEBUG_VERBOSE, " ")); + } + + DEBUG ((DEBUG_VERBOSE, "0x%02x", Table[i])); + + if (i =3D=3D BdatSize - 1) { + DEBUG ((DEBUG_VERBOSE, "\n")); + } + + i++; + + } + DEBUG ((DEBUG_VERBOSE, "\n")); +} + +/** + Copy BDAT Table pointer to scratchpad 5 register + + @param[in] BdatAddress - Bdat Table Address to be copied to Scratchpad 5= register + + @retval None +**/ +VOID +CopyBdatPointerToScratchPad5 ( + IN UINT64 BdatAddress + ) +{ + UINT8 Socket =3D 0; + EFI_STATUS Status =3D EFI_SUCCESS; + DYNAMIC_SI_LIBARY_PROTOCOL *DynamicSiLibraryProtocol =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, &D= ynamicSiLibraryProtocol); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return; + } + + // + // Copy BDAT base address to ScratchPad5 + // + for (Socket =3D 0; Socket < MAX_SOCKET; Socket++) { + if (mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].Valid) { + DynamicSiLibraryProtocol->WriteScratchpad5 (Socket, (UINT32) BdatAdd= ress); + DEBUG ((DEBUG_VERBOSE, "Scratchpad_Debug PatchBdaAcpiTable: Verify N= on Sticky Scratchpad5 0x%08x\n", BdatAddress)); + } + } +} + +/** + Update the BDAT ACPI table: Multiple instances of the BDAT DATA HOB ar= e placed into one contiguos memory range + + @param *TableHeader - The table to be set + + @retval EFI_SUCCESS - Returns Success +**/ +EFI_STATUS +PatchBdatAcpiTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + EFI_STATUS Status =3D EFI_SUCCESS; + EFI_PHYSICAL_ADDRESS Address =3D 0; + UINT32 Idx =3D 0; + UINT8 Checksum =3D 0; + BDAT_STRUCTURE *BdatHeaderStructPtr =3D NULL; + UINT32 TotalBDATstructureSize =3D 0; + UINT32 BdatHeaderSize =3D 0; + EFI_HOB_GUID_TYPE *GuidHob =3D NULL; + UINT16 NumberBssaSchemas =3D 0; + UINT16 TotalNumberSchemas =3D 0; + UINT32 BssaSchemaSize =3D 0; + EFI_BDAT_ACPI_DESCRIPTION_TABLE *BdatAcpiTable =3D NULL; + EWL_PRIVATE_DATA *EwlPrivateData =3D NULL; + EFI_GUID EWLDataGuid =3D EWL_ID_GUID; + UINT32 EwlSchemaSize =3D 0; + MEM_TRAINING_DATA_STRUCTURE *MemTrainingData =3D NULL; + MEM_TRAINING_DATA_HOB_HEADER *TrainingDataHobHeader =3D NULL; + UINT32 TrainingDataSchemaSize =3D 0; + UINT32 RemainingSchemaSpace =3D 0; + UINT32 SpdDataSize =3D 0; + UINT32 SpdSchemaSize =3D 0; + UINT8 SchemaIndex =3D 0; + UINT32 SpaceUsed =3D 0; + UINT32 LastSchemaSpaceUsed =3D 0; + UINT32 OffsetFromLastSchema =3D 0; + + BdatAcpiTable =3D (EFI_BDAT_ACPI_DESCRIPTION_TABLE *)Table; + DEBUG ((DEBUG_INFO, "\nPatchBdatAcpiTable Started\n")); + + // + // Gather BSSA schema info + // + NumberBssaSchemas =3D GetNumberOfSchemasFromBssaHob (); + + BssaSchemaSize =3D mSystemMemoryMap->Reserved6 + (NumberBssaSchemas * si= zeof (BDAT_SCHEMA_HEADER_STRUCTURE)); //Total size of all HOBs created by S= aveToBdat() + NumberBssaSchemas*headerPerSchema + DEBUG ((DEBUG_VERBOSE, "NumberBssaSchemas =3D %d, total BSSA schema size= : %d\n", NumberBssaSchemas, BssaSchemaSize)); + + TotalNumberSchemas =3D NumberBssaSchemas; + + TotalBDATstructureSize +=3D BssaSchemaSize; + + // + // Gather EWL schema info + // + GuidHob =3D GetFirstGuidHob (&EWLDataGuid); + if (GuidHob !=3D NULL) { + DEBUG ((DEBUG_VERBOSE, "Found EWL with GUID %g\n", &EWLDataGuid)); + + TotalNumberSchemas +=3D 1; + + EwlPrivateData =3D GET_GUID_HOB_DATA (GuidHob); + + EwlSchemaSize =3D sizeof (BDAT_SCHEMA_HEADER_STRUCTURE) + EwlPrivateDa= ta->status.Header.Size; + + DEBUG ((DEBUG_VERBOSE, "EWL schema size: %d\n", EwlSchemaSize)); + + TotalBDATstructureSize +=3D EwlSchemaSize; + } + + // + // Gather SPD schema info + // + SpdSchemaSize =3D 0; + if (PcdGetBool (SaveSpdToBdat)) { + SpdDataSize =3D GetSpdDataSize (); + + if (SpdDataSize > 0) { + TotalNumberSchemas +=3D 1; + SpdSchemaSize =3D sizeof (BDAT_SCHEMA_HEADER_STRUCTURE) + SpdDataSiz= e; + DEBUG ((DEBUG_VERBOSE, "SPD data schema size: %d\n", SpdSchemaSize)); + + TotalBDATstructureSize +=3D SpdSchemaSize; + } + } // PcdGetBool (SaveSpdToBdat) + + // + // Gather Memory training data schema info + // + TrainingDataSchemaSize =3D 0; + if (PcdGetBool (SaveMrcTrainingDataToBdat)) { + GuidHob =3D GetFirstGuidHob (&gMemTrainingDataHobGuid); + if (GuidHob !=3D NULL) { + DEBUG ((DEBUG_VERBOSE, "Found memory training data HOB with GUID %g= \n", &gMemTrainingDataHobGuid)); + + TotalNumberSchemas +=3D 1; + + TrainingDataHobHeader =3D GET_GUID_HOB_DATA (GuidHob); + + MemTrainingData =3D (MEM_TRAINING_DATA_STRUCTURE *)((EFI_PHYSICAL_AD= DRESS)TrainingDataHobHeader + sizeof (MEM_TRAINING_DATA_HOB_HEADER)); + + TrainingDataSchemaSize =3D sizeof (BDAT_SCHEMA_HEADER_STRUCTURE) + M= emTrainingData->Header.Size; + + DEBUG ((DEBUG_VERBOSE, "Memory training data schema size: %d\n", Tra= iningDataSchemaSize)); + + TotalBDATstructureSize +=3D TrainingDataSchemaSize; + } + } // PcdGetBool (SaveMrcTrainingDataToBdat) + + BdatHeaderSize =3D sizeof (BDAT_STRUCTURE) + (TotalNumberSchemas * (size= of (UINT32))); + TotalBDATstructureSize +=3D BdatHeaderSize; + + // + // This variable is used to keep track the remain space in the BDAT payl= oad (schema section) to + // prevent overflow the allocated RT BDAT buffer. + // + RemainingSchemaSpace =3D TotalBDATstructureSize - BdatHeaderSize; + + DEBUG ((DEBUG_INFO, "Total BDAT size:%d, BDAT header size: %d, Total sch= ema:%d \n", TotalBDATstructureSize, BdatHeaderSize, TotalNumberSchemas)); + + Status =3D CreateBdatHeader (&BdatHeaderStructPtr, TotalBDATstructureSiz= e, TotalNumberSchemas); + if (EFI_ERROR (Status)) { + return Status; + } + + DEBUG ((DEBUG_INFO, "BdatRegionAddress =3D 0x%x\n", (UINT64)BdatHeaderSt= ructPtr)); + CopyBdatPointerToScratchPad5 ((UINT64)BdatHeaderStructPtr); + + // + // Update BDAT ACPI table + // + BdatAcpiTable->BdatGas.Address =3D (UINT64)BdatHeaderStructPtr; + + // + // Starting address of the first schema + // + Address =3D (EFI_PHYSICAL_ADDRESS)BdatHeaderStructPtr + BdatHeaderSize; + + // + // Saving to RT Memory BDAT Data received from HOBs generated due to BSS= A call/calls to SaveToBdat() + // + SpaceUsed =3D 0; + + // + // The first schema starts right after the BDAT header structure + // + LastSchemaSpaceUsed =3D BdatHeaderSize; // It will used as the OffsetFr= omLastSchema for the next schema if BSSA is not available + OffsetFromLastSchema =3D BdatHeaderSize; + + if (BssaSchemaSize > 0) { + + Status =3D SaveBssaResultsToBdat (BdatHeaderStructPtr, OffsetFromLastS= chema, &Address, &SchemaIndex, BssaSchemaSize, &SpaceUsed, &LastSchemaSpace= Used); + if (Status !=3D EFI_SUCCESS) { + DEBUG ((DEBUG_ERROR, "Faield to add BSSA result to BDAT\n")); + } + } + + // + // Update the starting address of next schema and remaining space. + // + Address +=3D SpaceUsed; + RemainingSchemaSpace -=3D SpaceUsed; + OffsetFromLastSchema =3D LastSchemaSpaceUsed; + + // + // Saving to RT Memory BDAT Data received from EWL HOB + // + SpaceUsed =3D 0; + + if (EwlSchemaSize > 0) { + + if (RemainingSchemaSpace < EwlSchemaSize) { + DEBUG ((DEBUG_ERROR, "Not enough space to add EWL schema.\n")); + goto End; + } + + Status =3D SaveEwlToBdat (BdatHeaderStructPtr, OffsetFromLastSchema ,&= Address, &SchemaIndex, &SpaceUsed); + + if (Status !=3D EFI_SUCCESS) { + DEBUG ((DEBUG_ERROR, "Failed to add EWL to BDAT.\n")); + } + + } + + // + // Update the starting address of next schema and remaining space. + // + Address +=3D SpaceUsed; + RemainingSchemaSpace -=3D SpaceUsed; + OffsetFromLastSchema =3D SpaceUsed; + + // + // Add SPD schema + // + SpaceUsed =3D 0; + + if (SpdSchemaSize > 0) { + + if (RemainingSchemaSpace < SpdSchemaSize) { + DEBUG ((DEBUG_ERROR, "Not enough space to add SPD schema.\n")); + goto End; + } + + Status =3D SaveSpdToBdat (BdatHeaderStructPtr, OffsetFromLastSchema, &= Address, &SchemaIndex, &SpaceUsed); + + if (Status !=3D EFI_SUCCESS) { + DEBUG ((DEBUG_ERROR, "Failed to add SPD to BDAT.\n")); + } + + } + + // + // Update the starting address of next schema and remaining space. + // + Address +=3D SpaceUsed; + RemainingSchemaSpace -=3D SpaceUsed; + OffsetFromLastSchema =3D SpaceUsed; + + // + // Add memory training data schema + // + SpaceUsed =3D 0; + + if (TrainingDataSchemaSize > 0) { + + if (RemainingSchemaSpace < TrainingDataSchemaSize) { + DEBUG ((DEBUG_ERROR, "Not enough space to add memory training data s= chema.\n")); + goto End; + } + + Status =3D SaveTrainingDataToBdat (BdatHeaderStructPtr, OffsetFromLast= Schema, &Address, &SchemaIndex, &SpaceUsed); + + if (Status !=3D EFI_SUCCESS) { + DEBUG ((DEBUG_ERROR, "Failed to add memory training data to BDAT.\n"= )); + } + } + + // + // Update the starting address of next schema and remaining space. + // + Address +=3D SpaceUsed; + RemainingSchemaSpace -=3D SpaceUsed; + OffsetFromLastSchema =3D SpaceUsed; + + DEBUG ((DEBUG_VERBOSE, "Final SchemaIndex:%d RemainingSchemaSpace:%d\n",= SchemaIndex, RemainingSchemaSpace)); + + End: + + // + // Update checksum + // + BdatAcpiTable->Header.Checksum =3D 0; + Checksum =3D 0; + for(Idx =3D 0; Idx < sizeof(EFI_BDAT_ACPI_DESCRIPTION_TABLE); Idx++) { + Checksum =3D Checksum + (UINT8) (((UINT8 *)(BdatAcpiTable))[Idx]); + } + BdatAcpiTable->Header.Checksum =3D (UINT8) (0 - Checksum); + + DumpBdatTable (&BdatHeaderStructPtr, TotalBDATstructureSize); + + return Status; +} + + +/** + Displays SPD content for debugging. + + @param[in] Address - The starting address of the SPD entry + + @retval N/A +**/ +VOID +DisplaySpdContents ( + IN EFI_PHYSICAL_ADDRESS Address + ) +{ + UINT16 Index; + MEM_SPD_ENTRY_TYPE0 *EntryHeaderPtr; + + EntryHeaderPtr =3D (MEM_SPD_ENTRY_TYPE0 *)Address; + + // + // Print the Socket, Channel and Dimm information. + // + DEBUG ((DEBUG_VERBOSE, "START_PRINT_SPD S%dC%dD%d:\n", + EntryHeaderPtr->MemoryLocation.Socket, + EntryHeaderPtr->MemoryLocation.Channel, + EntryHeaderPtr->MemoryLocation.Dimm)); + + // + // Print the Column Number of the SPD data. + // + for (Index =3D 0; Index < 0x10; Index++) { + DEBUG ((DEBUG_VERBOSE, " %02x", Index)); + } + + Address +=3D sizeof (MEM_SPD_ENTRY_TYPE0); + + for (Index =3D 0; Index < EntryHeaderPtr->NumberOfBytes; Index++) { + + // + // Print the Carriage Return and Byte Index of SPD data. + // + if ((Index % 0x10) =3D=3D 0) { + + // + // Split the SPD data for every 256 bytes + // + if (((Index % 0x100) =3D=3D 0) && (Index !=3D 0)) { + DEBUG ((DEBUG_VERBOSE, "\n")); + } + + DEBUG ((DEBUG_VERBOSE, "\n%02x:", (UINT8) (Index & 0x00F0))); + } + + DEBUG ((DEBUG_VERBOSE, " %02x", *(UINT8 *)(Address + (EFI_PHYSICAL_ADD= RESS)Index))); + } + + DEBUG ((DEBUG_VERBOSE, "\n")); + + + DEBUG ((DEBUG_VERBOSE, "STOP_PRINT_SPD\n")); + +} // DisplaySpdContents + +/** + Get the size of SPD data structure not include the SPD BDAT schema heade= r. + + @retval UINT32 - Size of SPD data structure in bytes +**/ +UINT32 +GetSpdDataSize ( + VOID + ) +{ + UINT32 SchemaSize =3D 0; + UINT8 Socket; + UINT8 Channel; + UINT8 Dimm; + UINT32 SpdBytesPerDimm =3D 0; + UINT8 NumberOfDimmPresent =3D 0; + + EFI_STATUS Status =3D EFI_SUCCESS; + DYNAMIC_SI_LIBARY_PROTOCOL *DynamicSiLibraryProtocol =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, &D= ynamicSiLibraryProtocol); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return 0; + } + + if (mSystemMemoryMap =3D=3D NULL) { + mSystemMemoryMap =3D DynamicSiLibraryProtocol->GetSystemMemoryMapData = (); + } + + if (mSystemMemoryMap =3D=3D NULL) { + return 0; + } + + ASSERT (mSystemMemoryMap->DramType =3D=3D SPD_TYPE_DDR4); + SpdBytesPerDimm =3D MAX_SPD_BYTE_DDR4; + + for (Socket =3D 0; Socket < MAX_SOCKET; Socket++) { + for (Channel =3D 0; Channel < MAX_CH; Channel++) { + for (Dimm =3D 0; Dimm < MAX_DIMM; Dimm++) { + if (mSystemMemoryMap->Socket[Socket].ChannelInfo[Channel].DimmInfo= [Dimm].Present !=3D 0) { + NumberOfDimmPresent +=3D 1; + } + } + } + } + + // + // Total entries + // + SchemaSize =3D (SpdBytesPerDimm + sizeof (MEM_SPD_ENTRY_TYPE0)) * Number= OfDimmPresent; + + // + // Add the SPD raw data header + // + SchemaSize +=3D sizeof (MEM_SPD_RAW_DATA_HEADER); + + return SchemaSize; + +} + + +/** + Read the SPD data for one dimm and fill up SPD entry inside SPD BDAT sch= ema space. + + @param[out] Address - Start Address of the buffer where the SP= D entry to be filled + @param[in] Socket - Socket number + @param[in] Channel - Channel number inside the Socket + @param[in] Dimm - Dimm slot number + @param[in] MaxSpdByteOffset - The max SPD byte offset. DDR4 is 512 + + @retval EFI_SUCCESS - SPD Structure filled successfully + @retval !EFI_SUCCESS - SPD structure creation failed +**/ +EFI_STATUS +FillSpdPerDimmEntry ( + OUT EFI_PHYSICAL_ADDRESS Address, + IN UINT8 Socket, + IN UINT8 Channel, + IN UINT8 Dimm, + IN UINT16 MaxSpdByteOffset + ) +{ + UINT16 SpdByteOffset =3D 0; + UINT8 SpdData =3D 0; + MEM_SPD_ENTRY_TYPE0 *EntryHeaderPtr; + EFI_STATUS Status =3D EFI_SUCCESS; + + DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 =3D NULL; + + DEBUG ((DEBUG_VERBOSE, "Fill Spd entry for Socket:%d Channel:%d Dimm:%d = at location:0x%x \n", Socket, Channel, Dimm, Address)); + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &= DynamicSiLibraryProtocol2); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + EntryHeaderPtr =3D (MEM_SPD_ENTRY_TYPE0 *)Address; + + // + // Add the entry header. We use type 0. + // + EntryHeaderPtr->Header.Type =3D MemSpdDataType0; + EntryHeaderPtr->Header.Size =3D sizeof (MEM_SPD_ENTRY_TYPE0) + MaxSpdByt= eOffset; + + EntryHeaderPtr->MemoryLocation.Socket =3D Socket; + EntryHeaderPtr->MemoryLocation.Channel =3D Channel; + EntryHeaderPtr->MemoryLocation.Dimm =3D Dimm; + + EntryHeaderPtr->NumberOfBytes =3D MaxSpdByteOffset; + + Address +=3D sizeof (MEM_SPD_ENTRY_TYPE0); + + for (SpdByteOffset =3D 0; SpdByteOffset < MaxSpdByteOffset; SpdByteOffse= t++) { + Status =3D DynamicSiLibraryProtocol2->SpdReadByte (Socket, Channel, Di= mm, SpdByteOffset, &SpdData); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "Failed to read SPD data at Socket:%d Channel:%d= Dimm:%d SpdByteOffset:%d Status:0x%x\n", + Socket, Channel, Dimm, SpdByteOffset, Status)); + return Status; + } + + *(UINT8 *)Address =3D SpdData; + Address +=3D 1; + } // SpdByteOffset + + return Status; +} + +/** + Fill the SPD data structure inside the BDAT schema space. + + @param[out] StartAddress - Start Address of the buffer where S= PD data structure to be filled + @param[in] SpdDataSize - Size of SPD data structure includes= the header + + @retval EFI_SUCCESS - SPD Structure filled successfully + @retval !EFI_SUCCESS - SPD structure creation failed +**/ +EFI_STATUS +FillSpdSchema ( + OUT EFI_PHYSICAL_ADDRESS StartAddress, + IN UINT32 SpdDataSize + ) +{ + UINT8 Socket; + UINT8 Channel; + UINT8 Dimm; + UINT16 MaxSpdByteOffset =3D 0; + UINT32 RemainedSpace; + EFI_PHYSICAL_ADDRESS Address; + MEM_SPD_RAW_DATA_HEADER *SpdDataHeaderStructPtr; + EFI_STATUS Status =3D EFI_SUCCESS; + + DYNAMIC_SI_LIBARY_PROTOCOL *DynamicSiLibraryProtocol =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, &D= ynamicSiLibraryProtocol); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + if (mSystemMemoryMap =3D=3D NULL) { + mSystemMemoryMap =3D DynamicSiLibraryProtocol->GetSystemMemoryMapData = (); + } + + if (mSystemMemoryMap =3D=3D NULL) { + return EFI_DEVICE_ERROR;; + } + if (StartAddress =3D=3D 0) { + return EFI_INVALID_PARAMETER; + } + + RemainedSpace =3D SpdDataSize; + Address =3D StartAddress; + SpdDataHeaderStructPtr =3D (MEM_SPD_RAW_DATA_HEADER *)StartAddress; + + // + // Fill up the header of the SPD data strcuture + // + SpdDataHeaderStructPtr->MemSpdGuid =3D gSpdVersion1Guid; + SpdDataHeaderStructPtr->Size =3D SpdDataSize; + SpdDataHeaderStructPtr->Reserved =3D 0; + + Address +=3D sizeof (MEM_SPD_RAW_DATA_HEADER); + RemainedSpace -=3D sizeof (MEM_SPD_RAW_DATA_HEADER); + + ASSERT (mSystemMemoryMap->DramType =3D=3D SPD_TYPE_DDR4); + MaxSpdByteOffset =3D MAX_SPD_BYTE_DDR4; + + // + // Iterate through all populated DIMMs and add them + // + for (Socket =3D 0; Socket < MAX_SOCKET; Socket++) { + for (Channel =3D 0; Channel < MAX_CH; Channel++) { + for (Dimm =3D 0; Dimm < MAX_DIMM; Dimm++) { + + if (mSystemMemoryMap->Socket[Socket].ChannelInfo[Channel].DimmInfo= [Dimm].Present !=3D 0) { + + if (RemainedSpace < sizeof (MEM_SPD_ENTRY_TYPE0) + MaxSpdByteOff= set) { + DEBUG ((DEBUG_ERROR, "Run out of allocated SPD data space. Rem= ainedSpace:%d required space:%d\n", + RemainedSpace, sizeof (MEM_SPD_ENTRY_TYPE0) + MaxSpdByteOffs= et)); + return RETURN_OUT_OF_RESOURCES; + } + + Status =3D FillSpdPerDimmEntry (Address, Socket, Channel, Dimm, = MaxSpdByteOffset); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed to read SPD data at Socket:%d Cha= nnel:%d Dimm:%d Status:0x%x.\n", Socket, Channel, Dimm, Status)); + return Status; + } + + DisplaySpdContents (Address); + + Address +=3D sizeof (MEM_SPD_ENTRY_TYPE0) + MaxSpdByteOffset; + RemainedSpace -=3D sizeof (MEM_SPD_ENTRY_TYPE0) + MaxSpdByteOffs= et; + + } + } // Dimm + } // Channel + } // Socket + + // + // Update CRC + // + SpdDataHeaderStructPtr->Crc =3D 0; + SpdDataHeaderStructPtr->Crc =3D CalculateCrc32 ((VOID *) SpdDataHeaderSt= ructPtr, SpdDataHeaderStructPtr->Size); + + return EFI_SUCCESS; + +} + +/** + Save BSSA results to BDAT + + @param[in,out] BdatHeaderStructPtr - Pointer to BDAT Structure + @param[in] OffsetFromLastSchema- Offset (in bytes) from the last s= chema. Need it to update the schema offsets array. + @param[in] SchemaStartAddress - Starting address where the BSSA r= esult schema will be added + @param[in, out] SchemaIndex - Current schema index inside the B= DAT. Need it to update the schema offsets array. + @param[in] SchemaSize - The size of the BSSA results sche= ma. + @param[out] SchemaSpaceUsed - The numebr bytes were filled in a= ll schema + @param[out] LastSchemaSpaceUsed - The numebr bytes were filled in t= he last schema + + @retval EFI_SUCCESS - BSSA BDAT scehma created successfully + @retval !EFI_SUCCESS - BSSA BDAT scehma creation failed +**/ +EFI_STATUS +SaveBssaResultsToBdat ( + IN OUT BDAT_STRUCTURE *BdatHeaderStructPtr, + IN UINT32 OffsetFromLastSchema, + IN EFI_PHYSICAL_ADDRESS *SchemaStartAddress, + IN OUT UINT8 *SchemaIndex, + IN UINT32 SchemaSize, + OUT UINT32 *SchemaSpaceUsed, + OUT UINT32 *LastSchemaSpaceUsed + ) +{ + EFI_STATUS Status =3D EFI_SU= CCESS; + UINT32 *SchemaAddrLocationArray =3D NULL; + UINT32 CurrentHobSize =3D 0; + EFI_HOB_GUID_TYPE *GuidHob =3D NULL; + VOID *HobData =3D NULL; + UINT32 PreviousSchemaSize =3D 0; + EFI_GUID gEfiMemoryMapDataHobBdatBssaGuid =3D = {0}; + UINT32 GuidIdx =3D 0; + UINT32 HobIdx =3D 0; + UINT32 RemainingHobSizeBssaSchema =3D 0; + BDAT_SCHEMA_HEADER_STRUCTURE *BssaSchemaHeaderPtr =3D NULL; + EFI_PHYSICAL_ADDRESS Address =3D 0; + + if ((BdatHeaderStructPtr =3D=3D NULL) || (SchemaStartAddress =3D=3D NULL= ) || (SchemaIndex =3D=3D NULL) || (SchemaSpaceUsed =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + RemainingHobSizeBssaSchema =3D SchemaSize; + Address =3D *SchemaStartAddress; + *SchemaSpaceUsed =3D 0; + + // + // Update the schema offset array for its first BSSA schema + // + SchemaAddrLocationArray =3D (UINT32 *)((EFI_PHYSICAL_ADDRESS)BdatHeaderS= tructPtr + sizeof(BDAT_STRUCTURE)); + + if (*SchemaIndex < BdatHeaderStructPtr->BdatSchemas.SchemaListLength) { + if (*SchemaIndex =3D=3D 0) { + SchemaAddrLocationArray[*SchemaIndex] =3D OffsetFromLastSchema; + } + else { + SchemaAddrLocationArray[*SchemaIndex] =3D SchemaAddrLocationArray[*S= chemaIndex - 1] + OffsetFromLastSchema; + } + } + + for (GuidIdx =3D 0; GuidIdx < mSystemMemoryMap->Reserved9; GuidIdx++) { + + gEfiMemoryMapDataHobBdatBssaGuid =3D mSystemMemoryMap->Reserved8[Guid= Idx]; //get first GUID instance + GuidHob =3D GetFirstGuidHob (&gEfiMemoryMapDataHobBdatBssaGuid); + + for (HobIdx =3D 0; HobIdx < mSystemMemoryMap->Reserved7[GuidIdx]; HobI= dx++) { //looping through all HOBs linked to that GUID + + ASSERT (GuidHob !=3D NULL); + if (GuidHob =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + HobData =3D GET_GUID_HOB_DATA (GuidHob); + CurrentHobSize =3D GET_GUID_HOB_DATA_SIZE (GuidHob); + DEBUG ((DEBUG_VERBOSE, "Initial HOB size %d; remaining HOB size %d\= n", CurrentHobSize, RemainingHobSizeBssaSchema)); + + // + // Setting the header first + // + if (RemainingHobSizeBssaSchema < sizeof(BDAT_SCHEMA_HEADER_STRUCTURE= )) { + // + // Nothing we can do, break execution + // + DEBUG ((DEBUG_WARN, "Not enough space to add schema header to BIOS= SSA result\n")); + RemainingHobSizeBssaSchema =3D 0; + break; + } + + // + // Each HOB has a header added to it (BDAT_SCHEMA_HEADER_STRUCTURE) + // + Address =3D Address + (EFI_PHYSICAL_ADDRESS)PreviousSchemaSize; + + BssaSchemaHeaderPtr =3D (BDAT_SCHEMA_HEADER_STRUCTURE *)Address; + BssaSchemaHeaderPtr->SchemaId =3D gEfiMemoryMapDataHobBdatBssaGuid; + RemainingHobSizeBssaSchema -=3D sizeof(BDAT_SCHEMA_HEADER_STRUCTURE); + *SchemaSpaceUsed =3D *SchemaSpaceUsed + sizeof(BDAT_SCHEMA_HEADER_ST= RUCTURE); + + Address =3D Address + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE); + + // + // CRC16 value of the BDAT_SCHEMA_HEADER_STRUCTURE + // + BssaSchemaHeaderPtr->Crc16 =3D 0; + Status =3D CalculateCrc16 ( + (VOID *) BssaSchemaHeaderPtr, + sizeof (BDAT_SCHEMA_HEADER_STRUCTURE), + &BssaSchemaHeaderPtr->Crc16 + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + BssaSchemaHeaderPtr->Crc16 =3D 0xFFFF; + } + + if (RemainingHobSizeBssaSchema < CurrentHobSize) { + DEBUG ((DEBUG_WARN, "Not enough space to add complete BIOS SSA res= ult\n")); + CurrentHobSize =3D RemainingHobSizeBssaSchema; + } + + // + // HOB size won't overflow a UINT32. + // + BssaSchemaHeaderPtr->DataSize =3D (UINT32)CurrentHobSize + sizeof(BD= AT_SCHEMA_HEADER_STRUCTURE); + DEBUG ((DEBUG_VERBOSE, "Setting schema %g size to %d\n", &(BssaSchem= aHeaderPtr->SchemaId), BssaSchemaHeaderPtr->DataSize)); + // + // HOB size won't overflow a UINT32. + // + PreviousSchemaSize =3D (UINT32)CurrentHobSize + sizeof(BDAT_SCHEMA_H= EADER_STRUCTURE); + + // + // Copy HOB to RT Memory + // + CopyMem ((VOID *)Address, (VOID *)HobData, (UINT32)CurrentHobSize); + // + // HOB size won't overflow a UINT32. + // + DEBUG ((DEBUG_VERBOSE, "HOB size %d; remaining SSA HOB size %d\n", = CurrentHobSize, RemainingHobSizeBssaSchema)); + RemainingHobSizeBssaSchema -=3D (UINT32)CurrentHobSize; + *SchemaSpaceUsed =3D *SchemaSpaceUsed + (UINT32)CurrentHobSize; + + *SchemaIndex =3D *SchemaIndex + 1; + + if (RemainingHobSizeBssaSchema =3D=3D 0) { + break; + } + + GuidHob =3D GET_NEXT_HOB (GuidHob); // Increment to next HOB + GuidHob =3D GetNextGuidHob (&gEfiMemoryMapDataHobBdatBssaGuid, GuidH= ob); // Now search for next instance of the BDAT HOB + if (GuidHob =3D=3D NULL) { + break; + } + + // + // Update the schema offset arrary + // + if (*SchemaIndex < BdatHeaderStructPtr->BdatSchemas.SchemaListLength= ) { + SchemaAddrLocationArray[*SchemaIndex] =3D SchemaAddrLocationArray[= *SchemaIndex - 1] + PreviousSchemaSize; + } + } + + if (RemainingHobSizeBssaSchema =3D=3D 0) { + break; + } + + } + + *LastSchemaSpaceUsed =3D PreviousSchemaSize; + + return EFI_SUCCESS; +} // SaveBssaResultsToBdat + + +/** + Save EWL results to BDAT + + @param[in,out] BdatHeaderStructPtr - Pointer to BDAT Structure + @param[in] OffsetFromLastSchema- Offset (in bytes) from the last s= chema. Need it to update the schema offsets array. + @param[in] SchemaStartAddress - Starting address where the EWL sc= hema will be added + @param[in, out] SchemaIndex - Current schema index inside the B= DAT. Need it to update the schema offsets array. + @param[out] SchemaSpaceUsed - The numebr bytes were filled + + @retval EFI_SUCCESS - EWL BDAT scehma created successfully + @retval !EFI_SUCCESS - EWL BDAT scehma creation failed +**/ +EFI_STATUS +SaveEwlToBdat ( + IN OUT BDAT_STRUCTURE *BdatHeaderStructPtr, + IN UINT32 OffsetFromLastSchema, + IN EFI_PHYSICAL_ADDRESS *SchemaStartAddress, + IN OUT UINT8 *SchemaIndex, + OUT UINT32 *SchemaSpaceUsed + ) +{ + EFI_STATUS Status =3D EFI_SU= CCESS; + UINT32 *SchemaAddrLocationArray =3D NULL; + EFI_HOB_GUID_TYPE *GuidHob =3D NULL; + EFI_PHYSICAL_ADDRESS Address =3D 0; + EWL_PRIVATE_DATA *EwlPrivateData =3D NULL; + EFI_GUID EWLDataGuid =3D EWL_ID= _GUID; + BDAT_SCHEMA_HEADER_STRUCTURE *EwlSchemaHeaderPtr =3D NULL; + UINT32 EwlSize =3D 0; + + if ((BdatHeaderStructPtr =3D=3D NULL) || (SchemaStartAddress =3D=3D NULL= ) || (SchemaIndex =3D=3D NULL) || (SchemaSpaceUsed =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + Address =3D *SchemaStartAddress; + *SchemaSpaceUsed =3D 0; + + DEBUG ((DEBUG_VERBOSE, "\nStarting to copy EWL schema at Address =3D 0x%= x\n", Address)); + + // + // Update the schema offset arrary + // + SchemaAddrLocationArray =3D (UINT32 *)((EFI_PHYSICAL_ADDRESS)BdatHeaderS= tructPtr + sizeof(BDAT_STRUCTURE)); + + if (*SchemaIndex < BdatHeaderStructPtr->BdatSchemas.SchemaListLength) { + if (*SchemaIndex =3D=3D 0) { + SchemaAddrLocationArray[*SchemaIndex] =3D OffsetFromLastSchema; + } + else { + SchemaAddrLocationArray[*SchemaIndex] =3D SchemaAddrLocationArray[*S= chemaIndex - 1] + OffsetFromLastSchema; + } + } + + EwlSchemaHeaderPtr =3D (BDAT_SCHEMA_HEADER_STRUCTURE *)Address; + EwlSchemaHeaderPtr->SchemaId =3D gEwlBdatSchemaGuid; + *SchemaSpaceUsed =3D *SchemaSpaceUsed + sizeof(BDAT_SCHEMA_HEADER_STRUCT= URE); + + // + // CRC16 value of the BDAT_SCHEMA_HEADER_STRUCTURE + // + EwlSchemaHeaderPtr->Crc16 =3D 0; + Status =3D CalculateCrc16 ( + (VOID *)EwlSchemaHeaderPtr, + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE), + &EwlSchemaHeaderPtr->Crc16 + ); + + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + EwlSchemaHeaderPtr->Crc16 =3D 0xFFFF; + } + + GuidHob =3D GetFirstGuidHob (&EWLDataGuid); + EwlPrivateData =3D GET_GUID_HOB_DATA (GuidHob); + + EwlSize =3D EwlPrivateData->status.Header.Size; + + EwlSchemaHeaderPtr->DataSize =3D EwlSize + sizeof(BDAT_SCHEMA_HEADER_STR= UCTURE); + + // + // Copy EWL HOB to RT Memory + // + Address =3D Address + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE); + CopyMem ((VOID *)Address, (VOID *)&(EwlPrivateData->status), EwlSize); + *SchemaSpaceUsed =3D *SchemaSpaceUsed + EwlSize; + + *SchemaIndex =3D *SchemaIndex + 1; + + return EFI_SUCCESS; +} //SaveEwlToBdat + +/** + Check if current boot is slow boot or not + + @retval TRUE - Slow boot path + @retval FALSE - not slow boot path + **/ +BOOLEAN +IsSlowBoot ( + VOID + ) +{ + EFI_STATUS Status =3D EFI_SUCCESS; + DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &= DynamicSiLibraryProtocol2); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return TRUE; + } + + return DynamicSiLibraryProtocol2->IsSlowBoot (); +} // IsSlowBoot + +/** + Save SPD date structure to BDAT + + @param[in,out] BdatHeaderStructPtr - Pointer to BDAT Structure + @param[in] OffsetFromLastSchema- Offset (in bytes) from the last s= chema. Need it to update the schema offsets array. + @param[in] SchemaStartAddress - Starting address where the SPD da= ta schema will be added + @param[in, out] SchemaIndex - Current schema index inside the B= DAT. Need it to update the schema offsets array. + @param[out] SchemaSpaceUsed - The numebr bytes were filled + + @retval EFI_SUCCESS - SPD BDAT scehma created successfully + @retval !EFI_SUCCESS - SPD BDAT scehma creation failed +**/ +EFI_STATUS +SaveSpdToBdat ( + IN OUT BDAT_STRUCTURE *BdatHeaderStructPtr, + IN UINT32 OffsetFromLastSchema, + IN EFI_PHYSICAL_ADDRESS *SchemaStartAddress, + IN OUT UINT8 *SchemaIndex, + OUT UINT32 *SchemaSpaceUsed + ) +{ + EFI_STATUS Status =3D EFI_SU= CCESS; + UINT32 *SchemaAddrLocationArray =3D NULL; + UINT32 SpdDataSize =3D 0; + EFI_PHYSICAL_ADDRESS Address =3D 0; + BDAT_SCHEMA_HEADER_STRUCTURE *SpdSchemaHeaderPtr =3D NULL; +// UINT16 *SpdVariableName =3D L"Sp= dData"; + VOID *VariableData =3D NULL; + BOOLEAN SaveToVariable =3D TRUE; + UINTN CompareValue; + + if ((BdatHeaderStructPtr =3D=3D NULL) || (SchemaStartAddress =3D=3D NULL= ) || (SchemaIndex =3D=3D NULL) || (SchemaSpaceUsed =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + Address =3D *SchemaStartAddress; + *SchemaSpaceUsed =3D 0; + + // + // Add SPD schema + // + DEBUG ((DEBUG_VERBOSE, "\nStarting to add SPD schema at Address =3D 0x%= x\n", Address)); + + // + // Update the schema offset arrary + // + SchemaAddrLocationArray =3D (UINT32 *)((EFI_PHYSICAL_ADDRESS)BdatHeaderS= tructPtr + sizeof(BDAT_STRUCTURE)); + + if (*SchemaIndex < BdatHeaderStructPtr->BdatSchemas.SchemaListLength) { + if (*SchemaIndex =3D=3D 0) { + SchemaAddrLocationArray[*SchemaIndex] =3D OffsetFromLastSchema; + } + else { + SchemaAddrLocationArray[*SchemaIndex] =3D SchemaAddrLocationArray[*S= chemaIndex - 1] + OffsetFromLastSchema; + } + } + + SpdSchemaHeaderPtr =3D (BDAT_SCHEMA_HEADER_STRUCTURE *)Address; + SpdSchemaHeaderPtr->SchemaId =3D gSpdBdatSchemaGuid; + + // + // CRC16 value of the BDAT_SCHEMA_HEADER_STRUCTURE + // + SpdSchemaHeaderPtr->Crc16 =3D 0; + Status =3D CalculateCrc16 ( + (VOID *)SpdSchemaHeaderPtr, + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE), + &SpdSchemaHeaderPtr->Crc16 + ); + + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + SpdSchemaHeaderPtr->Crc16 =3D 0xFFFF; + } + + Address =3D Address + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE); + *SchemaSpaceUsed =3D *SchemaSpaceUsed + sizeof(BDAT_SCHEMA_HEADER_STRUCT= URE); + + SpdDataSize =3D GetSpdDataSize (); + + if (IsSlowBoot ()) { + // + // Read SPD via Smbus, fill up the SPD data structure. + // + FillSpdSchema (Address, SpdDataSize); + + // + // Save the SPD data structure to EFI variables to save fast boot time + // + // Before save variable, read and comapre to current data. If they are= the same, then + // don't save it. + // If fail to read the variable(the variable doesn't exist), save vari= able. + // + + SaveToVariable =3D TRUE; + + VariableData =3D AllocatePool (SpdDataSize); + if (VariableData =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "Not able to allocate space to store SPD variab= le data.\n")); + Status =3D EFI_OUT_OF_RESOURCES; + goto End; + } + +// Status =3D LoadCompressedVariable (SpdVariableName, gSpdVariableGuid= , VariableData, SpdDataSize); + + if (!EFI_ERROR (Status)) { + CompareValue =3D CompareMem ((VOID *)Address, VariableData, SpdDataS= ize); + if (CompareValue =3D=3D 0) { + SaveToVariable =3D FALSE; + DEBUG ((DEBUG_VERBOSE, "No change to the SPD data, don't save vari= able.\n")); + } + } + + if (SaveToVariable) { +// Status =3D CompressAndSaveToVariable (SpdVariableName, gSpdVariabl= eGuid, (VOID *)Address, SpdDataSize); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed to save SPD data to variable.\n")); + goto End; + } + + DEBUG ((DEBUG_VERBOSE, "Save SPD data to EFI variable.\n")); + } + } else { + // + // Fast boot, read the SPD data from vaiable + // +// Status =3D LoadCompressedVariable (SpdVariableName, gSpdVariableGuid= , (VOID *)Address, SpdDataSize); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed to load SPD data from variable.\n")); + goto End; + } + DEBUG ((DEBUG_VERBOSE, "Fill with SPD data from EFI variable.\n")); + } + + End: + + if (VariableData !=3D NULL) { + FreePool (VariableData); + } + + SpdSchemaHeaderPtr->DataSize =3D SpdDataSize + sizeof (BDAT_SCHEMA_HEADE= R_STRUCTURE); + *SchemaSpaceUsed =3D *SchemaSpaceUsed + SpdDataSize; + + *SchemaIndex =3D *SchemaIndex + 1; + return Status; +} //SaveSpdToBdat + +/** + Save memory training date structure to BDAT + + @param[in,out] BdatHeaderStructPtr - Pointer to BDAT Structure + @param[in] OffsetFromLastSchema- Offset (in bytes) from the last s= chema. Need it to update the schema offsets array. + @param[in] SchemaStartAddress - Starting address where the memory= training data schema will be added + @param[in, out] SchemaIndex - Current schema index inside the B= DAT. Need it to update the schema offsets array. + @param[out] SchemaSpaceUsed - The numebr bytes were filled + + @retval EFI_SUCCESS - Memory training data BDAT scehma created successf= ully + @retval !EFI_SUCCESS - Memory training data BDAT scehma creation failed +**/ +EFI_STATUS +SaveTrainingDataToBdat ( + IN OUT BDAT_STRUCTURE *BdatHeaderStructPtr, + IN UINT32 OffsetFromLastSchema, + IN EFI_PHYSICAL_ADDRESS *SchemaStartAddress, + IN OUT UINT8 *SchemaIndex, + OUT UINT32 *SchemaSpaceUsed + ) +{ + EFI_STATUS Status =3D EFI_SU= CCESS; + UINT32 *SchemaAddrLocationArray =3D NULL; + EFI_HOB_GUID_TYPE *GuidHob =3D NULL; + EFI_PHYSICAL_ADDRESS Address =3D 0; + MEM_TRAINING_DATA_HEADER *TrainingDataHeader =3D NULL; + MEM_TRAINING_DATA_HOB_HEADER *TrainingDataHobHeader =3D NULL; + EFI_GUID TrainingDataGuid =3D gMemTr= ainingDataHobGuid; + BDAT_SCHEMA_HEADER_STRUCTURE *SchemaHeaderPtr =3D NULL; + INT32 RemainingDataSize =3D 0; + UINT32 HobSize =3D 0; + UINT32 TrainingDataSize =3D 0; + UINT8 HobIndex =3D 0; + + if ((BdatHeaderStructPtr =3D=3D NULL) || (SchemaStartAddress =3D=3D NULL= ) || (SchemaIndex =3D=3D NULL) || (SchemaSpaceUsed =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + Address =3D *SchemaStartAddress; + *SchemaSpaceUsed =3D 0; + + DEBUG ((DEBUG_VERBOSE, "\nStarting to copy memory training data schema a= t Address =3D 0x%x\n", Address)); + + // + // Update the schema offset arrary + // + SchemaAddrLocationArray =3D (UINT32 *)((EFI_PHYSICAL_ADDRESS)BdatHeaderS= tructPtr + sizeof(BDAT_STRUCTURE)); + + if (*SchemaIndex < BdatHeaderStructPtr->BdatSchemas.SchemaListLength) { + if (*SchemaIndex =3D=3D 0) { + SchemaAddrLocationArray[*SchemaIndex] =3D OffsetFromLastSchema; + } + else { + SchemaAddrLocationArray[*SchemaIndex] =3D SchemaAddrLocationArray[*S= chemaIndex - 1] + OffsetFromLastSchema; + } + } + + SchemaHeaderPtr =3D (BDAT_SCHEMA_HEADER_STRUCTURE *)Address; + SchemaHeaderPtr->SchemaId =3D gMemTrainingDataBdatSchemaGuid; + *SchemaSpaceUsed =3D *SchemaSpaceUsed + sizeof(BDAT_SCHEMA_HEADER_STRUCT= URE); + + // + // CRC16 value of the BDAT_SCHEMA_HEADER_STRUCTURE + // + SchemaHeaderPtr->Crc16 =3D 0; + Status =3D CalculateCrc16 ( + (VOID *)SchemaHeaderPtr, + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE), + &SchemaHeaderPtr->Crc16 + ); + + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + SchemaHeaderPtr->Crc16 =3D 0xFFFF; + } + + GuidHob =3D GetFirstGuidHob (&TrainingDataGuid); + + ASSERT (GuidHob !=3D NULL); + if (GuidHob =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "Not found training data HOB with GUID:%g\n", &Tr= ainingDataGuid)); + return EFI_NOT_FOUND; + } + + TrainingDataHobHeader =3D GET_GUID_HOB_DATA (GuidHob); + TrainingDataSize =3D TrainingDataHobHeader->Size - sizeof (MEM_TRAINING_= DATA_HOB_HEADER); // This is the size of data to copy to the RT memory. + + TrainingDataHeader =3D (MEM_TRAINING_DATA_HEADER *)((EFI_PHYSICAL_ADDRES= S)TrainingDataHobHeader + sizeof (MEM_TRAINING_DATA_HOB_HEADER)); + + HobSize =3D GET_GUID_HOB_DATA_SIZE (GuidHob); + ASSERT (TrainingDataSize <=3D HobSize); + + HobIndex +=3D 1; + DEBUG ((DEBUG_VERBOSE, "Memory training data structre size:%d\n", Traini= ngDataHeader->Size)); + SchemaHeaderPtr->DataSize =3D TrainingDataHeader->Size + sizeof(BDAT_SCH= EMA_HEADER_STRUCTURE); + + // + // This is the total data size in the training data structure. + // + RemainingDataSize =3D (INT32) TrainingDataHeader->Size; + + DEBUG ((DEBUG_VERBOSE, "Remaining training data:%d\n", RemainingDataSize= )); + // + // Copy training data HOBs to RT Memory + // + Address =3D Address + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE); + CopyMem ((VOID *)Address, (VOID *)TrainingDataHeader, TrainingDataSize); + + *SchemaSpaceUsed =3D *SchemaSpaceUsed + TrainingDataSize; + + Address =3D Address + TrainingDataSize; + RemainingDataSize -=3D TrainingDataSize; + + while (RemainingDataSize > 0) { + + GuidHob =3D GET_NEXT_HOB (GuidHob); // Increment to next HOB + GuidHob =3D GetNextGuidHob (&TrainingDataGuid, GuidHob); // Now searc= h for next instance of the BDAT HOB + + ASSERT (GuidHob !=3D NULL); + if (GuidHob =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "Not found training data HOB with GUID:%g\n", &= TrainingDataGuid)); + return EFI_NOT_FOUND; + } + + TrainingDataHobHeader =3D GET_GUID_HOB_DATA (GuidHob); + TrainingDataSize =3D TrainingDataHobHeader->Size - sizeof (MEM_TRAININ= G_DATA_HOB_HEADER); // This is the size of data to copy to the RT memory. + + HobSize =3D GET_GUID_HOB_DATA_SIZE (GuidHob); + ASSERT (TrainingDataSize <=3D HobSize); + + HobIndex +=3D 1; + + // + // Copy training data HOBs to RT Memory + // + CopyMem ((VOID *)Address, (VOID *)((EFI_PHYSICAL_ADDRESS)TrainingDataH= obHeader + sizeof (MEM_TRAINING_DATA_HOB_HEADER)), TrainingDataSize); + + *SchemaSpaceUsed =3D *SchemaSpaceUsed + TrainingDataSize; + + Address =3D Address + TrainingDataSize; + RemainingDataSize -=3D TrainingDataSize; + DEBUG ((DEBUG_VERBOSE, "Remaining training data:%d after copying Hob:%= d \n", RemainingDataSize, HobIndex)); + } + + // + // Update training data header structure CRC, after all the training dat= a were copied from HOBs to a RT contiguous memory region. + // + TrainingDataHeader->Crc =3D 0; + TrainingDataHeader->Crc =3D CalculateCrc32 ((VOID *) TrainingDataHeader,= TrainingDataHeader->Size); + + *SchemaIndex =3D *SchemaIndex + 1; + + return EFI_SUCCESS; +} //SaveTrainingDataToBdat diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLi= b/AcpiPlatformLibDsdt.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPl= atformTableLib/AcpiPlatformLibDsdt.c new file mode 100644 index 0000000000..29722c1269 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiP= latformLibDsdt.c @@ -0,0 +1,673 @@ +/** @file + ACPI Platform Driver Hooks + + @copyright + Copyright 1996 - 2020 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// Statements that include other files +// +#include "AcpiPlatformLibLocal.h" + + +#define CPM_MMIO_SIZE 0x100000000 // 4G MMIO resource fo= r CPM +#define HQM_MMIO_SIZE 0x400000000 // 16G MMIO resource f= or HQM + +extern BIOS_ACPI_PARAM *mAcpiParameter; +extern struct SystemMemoryMapHob *mSystemMemoryMap; +extern EFI_IIO_UDS_PROTOCOL *mIioUds; +extern CPU_CSR_ACCESS_VAR *mCpuCsrAccessVarPtr; + +extern SOCKET_MP_LINK_CONFIGURATION mSocketMpLinkConfiguration; +extern SOCKET_IIO_CONFIGURATION mSocketIioConfiguration; +extern SOCKET_POWERMANAGEMENT_CONFIGURATION mSocketPowermanagementConfigur= ation; + +extern BOOLEAN mCpuOrderSorted; +extern UINT32 mApicIdMap[MAX_SOCKET][MAX_CORE * MAX_THREAD]; +extern UINT32 mNumOfBitShift; +extern CPU_ID_ORDER_MAP mCpuApicIdOrderTable[MAX_CPU_NUM]; + + +AML_OFFSET_TABLE_ENTRY *mAmlOffsetTablePointer =3D NULL; + +/** + Check current thread status + + @param ApicId - current thread ApicId + + @retval EFI_SUCCESS Returns Success if current thread is active + @retval EFI_UNSUPPORTED Table is not supported +**/ +EFI_STATUS +CheckCurrentThreadStatus ( + UINT32 ApicId + ) +{ + UINT32 Index; + + for (Index =3D 0; Index < MAX_CPU_NUM; Index++) { + if ((mCpuApicIdOrderTable[Index].Flags =3D=3D 1) && (mCpuApicIdOrderTa= ble[Index].ApicId =3D=3D ApicId)) { + return EFI_SUCCESS; + } + } + return EFI_UNSUPPORTED; +} + + +/** + Get socket, stack and optionaly port index from PCI device path. + + The PCI device path is typically: + '_SB_.PCxy.FIXz' for PCIe stack object + '_SB_.UCxy.FIXz' for UBOX stack object + '_SB_.PCxy.RPya' for PCIe bridge root port object + where x and y are hex digits, and 'a' is a letter like 'A', 'B',..,'H'. + + NOTE: 'xy' is decimal number of subsequent PCIe stack, not including UBO= X. + For UBOX UCxy, 'x' is socket, 'y' is stack. + + @param[in] DevPathPtr - PCI device path, e.g. '_SB_.PC00.FIX1' + @param[out] SocketPtr - Buffer for socket index. + @param[out] StackPtr - Buffer for stack index. + @param[out] PortkPtr - Buffer for port index. +**/ +VOID +AcpiPciDevPath2SktStkPort ( + IN CHAR8 *DevPathPtr, + OUT UINT8 *SocketPtr, + OUT UINT8 *StackPtr, + OUT UINT8 *PortPtr + ) +{ + UINT16 SysStackNo; + UINT8 SocketNo =3D 0xFF; + UINT8 StackNo =3D 0xFF; + UINT8 PortNo =3D 0xFF; + + if (PortPtr !=3D NULL) { + // + // Device path should contain bridge root port object, let's verify. + // + if (AsciiStrLen (DevPathPtr) < 3*4 + 2 || + DevPathPtr[10] !=3D 'R' || DevPathPtr[12] !=3D 'P' || DevPathPtr= [13] < 'A' || DevPathPtr[13] > 'H') { + + goto ErrExit; + } + PortNo =3D DevPathPtr[13] - 'A'; + } + if (AsciiStrLen (DevPathPtr) < 2*4 + 1 || DevPathPtr[7] < '0' || DevPat= hPtr[8] < '0') { + + goto ErrExit; + } + switch (DevPathPtr[5] << 8 | DevPathPtr[6]) { + + case ('P' << 8 | 'C'): + if (DevPathPtr[7] > '9' || DevPathPtr[8] > '9') { + + goto ErrExit; + } + SysStackNo =3D (DevPathPtr[7] - '0') * 10; + SysStackNo +=3D DevPathPtr[8] - '0'; + SocketNo =3D (UINT8)(SysStackNo / MAX_IIO_STACK); + StackNo =3D (UINT8)(SysStackNo % MAX_IIO_STACK); + break; + + case ('U' << 8 | 'C'): + if (DevPathPtr[7] <=3D '9') { + + SocketNo =3D DevPathPtr[7] - '0'; + + } else if (DevPathPtr[7] <=3D 'F') { + + if (DevPathPtr[7] < 'A') { + + goto ErrExit; + } + SocketNo =3D 10 + DevPathPtr[7] - 'A'; + + } else if (DevPathPtr[7] <=3D 'f') { + + if (DevPathPtr[7] < 'a') { + + goto ErrExit; + } + SocketNo =3D 10 + DevPathPtr[7] - 'a'; + + } else { + goto ErrExit; + } + if (DevPathPtr[8] <=3D '9') { + + StackNo =3D DevPathPtr[8] - '0'; + + } else if (DevPathPtr[8] <=3D 'F') { + + if (DevPathPtr[8] < 'A') { + + goto ErrExit; + } + StackNo =3D 10 + DevPathPtr[8] - 'A'; + + } else { + goto ErrExit; + } + break; + + default: + ErrExit: + DEBUG ((DEBUG_ERROR, "[ACPI] ERROR: String '%a' is not valid PCI sta= ck name, ", DevPathPtr)); + DEBUG ((DEBUG_ERROR, "expect _SB_.PCxy.FIXz, or _SB_.UCxv.FIXz, or _= SB_.PCxy.RPya\n")); + break; + } + if (SocketPtr !=3D NULL) { + *SocketPtr =3D SocketNo; + } + if (StackPtr !=3D NULL) { + *StackPtr =3D StackNo; + } + if (PortPtr !=3D NULL) { + *PortPtr =3D PortNo; + } + return; +} + + +/** + Update the DSDT table + + @param[in,out] *Table - The table to be set + + @retval EFI_SUCCESS - DSDT updated + @retval EFI_INVALID_PARAMETER - DSDT not updated +**/ +EFI_STATUS +PatchDsdtTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + EFI_STATUS Status; + UINT8 *DsdtPointer; + UINT32 *Signature; + UINT32 *Signature2; + UINT32 Fixes; + UINT32 NodeIndex; + UINT8 Counter; + UINT16 i; // DSDT_PLATEXRP_OffsetTable LUT entri= es extends beyond 256! + UINT8 BusBase =3D 0, BusLimit =3D 0; + UINT16 IoBase =3D 0, IoLimit =3D 0; + UINT32 MemBase32 =3D 0, MemLimit32 =3D 0; + UINT64 MemBase64 =3D 0, MemLimit64 =3D 0; + AML_RESOURCE_ADDRESS16 *AmlResourceAddress16Pointer; + AML_RESOURCE_ADDRESS32 *AmlResourceAddress32Pointer; + AML_RESOURCE_ADDRESS64 *AmlResourceAddress64Pointer; + EFI_ACPI_DESCRIPTION_HEADER *TableHeader; + UINT32 AdjustSize =3D 0; + UINT32 CpuSkt =3D 0; + UINT32 CpuIndex =3D 0; + ACPI_NAMEPACK_DWORD *NamePtr; + UINT8 *CurrPtr; + UINT8 *EndPtr; + const UINT32 *ApicMapPtr; + UINT8 Socket; + UINT8 Stack; + UINT8 UboxStack; + UINT8 PropagateSerrOption; + UINT8 PropagatePerrOption; + + Status =3D GetOptionData (&gEfiSetupVariableGuid, OFFSET_OF(SYSTEM_CONFI= GURATION, PropagateSerr), &PropagateSerrOption, sizeof(PropagateSerrOption)= ); + if (EFI_ERROR (Status)) { + mAcpiParameter->PropagateSerrOption =3D 1; + } else { + mAcpiParameter->PropagateSerrOption =3D PropagateSerrOption; + } + + Status =3D GetOptionData (&gEfiSetupVariableGuid, OFFSET_OF(SYSTEM_CONFI= GURATION, PropagatePerr), &PropagatePerrOption, sizeof(PropagatePerrOption)= ); + if (EFI_ERROR (Status)) { + mAcpiParameter->PropagatePerrOption =3D 1; + } else { + mAcpiParameter->PropagatePerrOption =3D PropagatePerrOption; + } + + TableHeader =3D (EFI_ACPI_DESCRIPTION_HEADER *)Table; + + if (mAmlOffsetTablePointer =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + mAcpiParameter->SocketBitMask =3D mCpuCsrAccessVarPtr->socketPresentBitM= ap; + + for (Socket =3D 0; Socket < MAX_SOCKET; Socket++) { + if (!mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].Valid) { + mAcpiParameter->IioPresentBitMask[Socket] =3D 0; + continue; + } + mAcpiParameter->IioPresentBitMask[Socket] =3D mIioUds->IioUdsPtr->Plat= formData.CpuQpiInfo[Socket].stackPresentBitmap; + for (Stack =3D 0; Stack < MAX_LOGIC_IIO_STACK; Stack++) { + + mAcpiParameter->BusBase[Socket][Stack] =3D mIioUds->IioUdsPtr->Platf= ormData.IIO_resource[Socket].StackRes[Stack].BusBase; + DEBUG ((DEBUG_INFO, "[ACPI](DSDT) [%d.%d] BusBase: 0x%02X\n", Socket= , Stack, mAcpiParameter->BusBase[Socket][Stack])); + } + } // for (Socket...) + + // + // Update IIO PCIe Root Port PCIe Capability offset + // for 10nm process CPUs with PCIe GEN4/GEN5 controller, PCIe Capability= offset is at 0x40 + // + mAcpiParameter->IioPcieRpCapOffset =3D 0x40; + + // + // Initialize TsegSize - 1MB aligned. + // + Fixes =3D 0; + // + // Loop through the AML looking for values that we must fix up. + // + for (i =3D 0; mAmlOffsetTablePointer[i].Pathname !=3D 0; i++) { + // + // Point to offset in DSDT for current item in AmlOffsetTable. + // + DsdtPointer =3D (UINT8 *) (TableHeader) + mAmlOffsetTablePointer[i].Of= fset; + + if (mAmlOffsetTablePointer[i].Opcode =3D=3D AML_DWORD_PREFIX) { + // + // If Opcode is 0x0C, then operator is Name() or OperationRegion(). + // (TableHeader + AmlOffsetTable.Offset) is at offset for value to c= hange. + // + // The assert below confirms that AML structure matches the offsets = table. + // If not then patching the AML would just corrupt it and result in = OS failure. + // If you encounter this assert something went wrong in *.offset.h f= iles + // generation. Remove the files and rebuild. + // + ASSERT (DsdtPointer[-1] =3D=3D mAmlOffsetTablePointer[i].Opcode); + // + // AmlOffsetTable.Value has FIX tag, so check that to decide what to= modify. + // + Signature =3D (UINT32 *) (&mAmlOffsetTablePointer[i].Value); + switch (*Signature) { + // + // Due to iASL compiler change and DSDT patch design change, if th= ese items need support + // then the ASI files will need to conform to the format requires = for iASL to add the items + // to the offset table, and we will need to filter them out when i= ASL is executed. + // + // "FIX0" OperationRegion() in Acpi\AcpiTables\Dsdt\CommonPlatform= .asi + // + case (SIGNATURE_32 ('F', 'I', 'X', '0')): + *(UINT32*)DsdtPointer =3D (UINT32)(UINTN)mAcpiParameter; + Fixes++; + break; + + default: + DEBUG ((DEBUG_ERROR, "[ACPI](DSDT) WARNING: Object '%a' with opc= ode 0x%02X not patched\n", + mAmlOffsetTablePointer[i].Pathname, mAmlOffsetTablePoint= er[i].Opcode)); + break; + } + } else if (mAmlOffsetTablePointer[i].Opcode =3D=3D AML_INDEX_OP) { + // + // If Opcode is 0x88, then operator is WORDBusNumber() or WORDIO(). + // (TableHeader + AmlOffsetTable.Offset) must be cast to AML_RESOURC= E_ADDRESS16 to change values. + // + AmlResourceAddress16Pointer =3D (AML_RESOURCE_ADDRESS16 *) (DsdtPoin= ter); + // + // The assert below confirms that AML structure matches the offsets = table. + // If not then patching the AML would just corrupt it and result in = OS failure. + // If you encounter this assert something went wrong in *.offset.h f= iles + // generation. Remove the files and rebuild. + // + ASSERT (AmlResourceAddress16Pointer->DescriptorType =3D=3D mAmlOffse= tTablePointer[i].Opcode); + + // + // Last 4 chars of AmlOffsetTable.Pathname has FIX tag. + // + Signature =3D (UINT32 *) (mAmlOffsetTablePointer[i].Pathname + Ascii= StrLen(mAmlOffsetTablePointer[i].Pathname) - 4); + Signature2 =3D (UINT32 *) (mAmlOffsetTablePointer[i].Pathname + Asci= iStrLen(mAmlOffsetTablePointer[i].Pathname) - 9); + switch (*Signature) { + // + // "FIX1" BUS resource for PCXX in Acpi\AcpiTables\Dsdt\SysBus.asi= and PCXX.asi + // + case (SIGNATURE_32 ('F', 'I', 'X', '1')): + AcpiPciDevPath2SktStkPort (mAmlOffsetTablePointer[i].Pathname, &= Socket, &Stack, NULL); + + BusBase =3D mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket= ].StackRes[Stack].BusBase; + BusLimit =3D mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socke= t].StackRes[Stack].BusLimit; + + AmlResourceAddress16Pointer->Granularity =3D 0; + if ((BusLimit > BusBase)) { + AmlResourceAddress16Pointer->Minimum =3D (UINT16) BusBase; + AmlResourceAddress16Pointer->Maximum =3D (UINT16) BusLimit; + AmlResourceAddress16Pointer->AddressLength =3D (UINT16) (BusLi= mit - BusBase + 1); + } + + Fixes++; + break; + + // + // "FIXB" BUS resource for FpgaKtiXX in Acpi\AcpiTables\Dsdt\FpgaK= tiXX.asi + // + case (SIGNATURE_32 ('F', 'I', 'X', 'B')): + break; + + // + // "FIX2" IO resource for for PCXX in Acpi\AcpiTables\Dsdt\SysBus.= asi and PCXX.asi + // + case (SIGNATURE_32 ('F', 'I', 'X', '2')): + AcpiPciDevPath2SktStkPort (mAmlOffsetTablePointer[i].Pathname, &= Socket, &Stack, NULL); + + IoBase =3D mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket]= .StackRes[Stack].PciResourceIoBase; + IoLimit =3D mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket= ].StackRes[Stack].PciResourceIoLimit; + if (IoLimit > IoBase) { + AmlResourceAddress16Pointer->Minimum =3D (UINT16) IoBase; + AmlResourceAddress16Pointer->Maximum =3D (UINT16) IoLimit; + AmlResourceAddress16Pointer->AddressLength =3D (UINT16) (IoLim= it - IoBase + 1); + } + AmlResourceAddress16Pointer->Granularity =3D 0; + + Fixes++; + break; + + // + // "FIX9" BUS resource for UNXX in Acpi\AcpiTables\Dsdt\Uncore.asi + // + case (SIGNATURE_32('F', 'I', 'X', '9')) : + AcpiPciDevPath2SktStkPort (mAmlOffsetTablePointer[i].Pathname, &= Socket, &Stack, NULL); + UboxStack =3D UBOX_STACK; + BusBase =3D mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket= ].StackRes[UboxStack].BusBase; + BusLimit =3D mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socke= t].StackRes[UboxStack].BusLimit; + if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackR= es[UboxStack].Personality !=3D TYPE_UBOX || + BusBase > BusLimit) { + + DEBUG ((DEBUG_ERROR, "[ACPI](DSDT) ERROR: Stack [%d.%d] of typ= e %d is not UBOX, '%a' not patched\n", + Socket, UboxStack, mIioUds->IioUdsPtr->PlatformData.II= O_resource[Socket].StackRes[UboxStack].Personality, + mAmlOffsetTablePointer[i].Pathname)); + break; + } + AmlResourceAddress16Pointer->Granularity =3D 0; + if (Stack & 1) { + AmlResourceAddress16Pointer->Minimum =3D BusLimit; + AmlResourceAddress16Pointer->Maximum =3D BusLimit; + } else { + AmlResourceAddress16Pointer->Minimum =3D BusBase; + AmlResourceAddress16Pointer->Maximum =3D BusBase; + } + AmlResourceAddress16Pointer->AddressLength =3D 1; + mAcpiParameter->BusBase[Socket][Stack] =3D (UINT8)AmlResourceAdd= ress16Pointer->Minimum; + mAcpiParameter->IioPresentBitMask[Socket] |=3D 1 << Stack; + Fixes++; + break; + + // + // "FIX6" IO resource for PCXX in Acpi\AcpiTables\Dsdt\PCXX.asi + // + case (SIGNATURE_32 ('F', 'I', 'X', '6')): + AcpiPciDevPath2SktStkPort (mAmlOffsetTablePointer[i].Pathname, &= Socket, &Stack, NULL); + AmlResourceAddress16Pointer->Granularity =3D 0; + if ((mSocketMpLinkConfiguration.LegacyVgaSoc =3D=3D Socket) && + (mSocketMpLinkConfiguration.LegacyVgaStack =3D=3D Stack)){ + + AmlResourceAddress16Pointer->Minimum =3D (UINT16) 0x03b0; + AmlResourceAddress16Pointer->Maximum =3D (UINT16) 0x03bb; + AmlResourceAddress16Pointer->AddressLength =3D (UINT16) 0x000C; + } + Fixes++; + break; + + // + // "FIX7" IO resource for PCXX in Acpi\AcpiTables\Dsdt\PCXX.asi + // + case (SIGNATURE_32 ('F', 'I', 'X', '7')): + AcpiPciDevPath2SktStkPort (mAmlOffsetTablePointer[i].Pathname, &= Socket, &Stack, NULL); + AmlResourceAddress16Pointer->Granularity =3D 0; + if ((mSocketMpLinkConfiguration.LegacyVgaSoc =3D=3D Socket) && + (mSocketMpLinkConfiguration.LegacyVgaStack =3D=3D Stack)) { + + AmlResourceAddress16Pointer->Minimum =3D (UINT16) 0x03c0; + AmlResourceAddress16Pointer->Maximum =3D (UINT16) 0x03df; + AmlResourceAddress16Pointer->AddressLength =3D (UINT16) 0x0020; + } + Fixes++; + break; + + default: + DEBUG ((DEBUG_ERROR, "[ACPI](DSDT) WARNING: Object '%a' with opc= ode 0x%02X not patched\n", + mAmlOffsetTablePointer[i].Pathname, mAmlOffsetTablePoint= er[i].Opcode)); + break; + } + } else if (mAmlOffsetTablePointer[i].Opcode =3D=3D AML_SIZE_OF_OP) { + // + // If Opcode is 0x87, then operator is DWORDMemory(). + // (TableHeader + AmlOffsetTable.Offset) must be cast to AML_RESOURC= E_ADDRESS32 to change values. + // + AmlResourceAddress32Pointer =3D (AML_RESOURCE_ADDRESS32 *) (DsdtPoin= ter); + // + // The assert below confirms that AML structure matches the offsets = table. + // If not then patching the AML would just corrupt it and result in = OS failure. + // If you encounter this assert something went wrong in *.offset.h f= iles + // generation. Remove the files and rebuild. + // + ASSERT (AmlResourceAddress32Pointer->DescriptorType =3D=3D mAmlOffse= tTablePointer[i].Opcode); + // + // Last 4 chars of AmlOffsetTable.Pathname has FIX tag. + // + Signature =3D (UINT32 *) (mAmlOffsetTablePointer[i].Pathname + Ascii= StrLen(mAmlOffsetTablePointer[i].Pathname) - 4); + Signature2 =3D (UINT32 *) (mAmlOffsetTablePointer[i].Pathname + Asci= iStrLen(mAmlOffsetTablePointer[i].Pathname) - 9); + switch (*Signature) { + // + // "FIX3" PCI32 resource for PCXX in Acpi\AcpiTables\Dsdt\SysBus.a= si and PCXX.asi + // + case (SIGNATURE_32 ('F', 'I', 'X', '3')): + AcpiPciDevPath2SktStkPort (mAmlOffsetTablePointer[i].Pathname, &= Socket, &Stack, NULL); + + MemBase32 =3D mIioUds->IioUdsPtr->PlatformData.IIO_resource[Sock= et].StackRes[Stack].PciResourceMem32Base; + MemLimit32 =3D mIioUds->IioUdsPtr->PlatformData.IIO_resource[Soc= ket].StackRes[Stack].PciResourceMem32Limit; + + if (MemLimit32 > MemBase32) { + AmlResourceAddress32Pointer->Minimum =3D (UINT32) MemBase32; + AmlResourceAddress32Pointer->Maximum =3D (UINT32) MemLimit32; + AmlResourceAddress32Pointer->AddressLength =3D (UINT32) (MemLi= mit32 - MemBase32 + 1); + } + AmlResourceAddress32Pointer->Granularity =3D 0; + + Fixes++; + break; + + // + // "FIX5" IO resource for PCXX in Acpi\AcpiTables\Dsdt\PCXX.asi + // + case (SIGNATURE_32 ('F', 'I', 'X', '5')): + AcpiPciDevPath2SktStkPort (mAmlOffsetTablePointer[i].Pathname, &= Socket, &Stack, NULL); + AmlResourceAddress32Pointer->Granularity =3D 0; + if ((mSocketMpLinkConfiguration.LegacyVgaSoc =3D=3D Socket) && + (mSocketMpLinkConfiguration.LegacyVgaStack =3D=3D Stack)) { + AmlResourceAddress32Pointer->Minimum =3D 0x000a0000; + AmlResourceAddress32Pointer->Maximum =3D 0x000bffff; + AmlResourceAddress32Pointer->AddressLength =3D 0x00020000; + } + Fixes++; + break; + + // + // "FIXZ" IO resource for FpgaBusXX in Acpi\AcpiTables\Dsdt\FpgaBu= sXX.asi + // + case (SIGNATURE_32 ('F', 'I', 'X', 'Z')): + break; + + default: + DEBUG ((DEBUG_ERROR, "[ACPI](DSDT) WARNING: Object '%a' with opc= ode 0x%02X not patched\n", + mAmlOffsetTablePointer[i].Pathname, mAmlOffsetTablePoint= er[i].Opcode)); + break; + } + } else if (mAmlOffsetTablePointer[i].Opcode =3D=3D AML_CREATE_DWORD_FI= ELD_OP) { + // + // If Opcode is 0x8A, then operator is QWORDMemory(). + // (TableHeader + AmlOffsetTable.Offset) must be cast to AML_RESOURC= E_ADDRESS64 to change values. + // + AmlResourceAddress64Pointer =3D (AML_RESOURCE_ADDRESS64 *) (DsdtPoin= ter); + // + // The assert below confirms that AML structure matches the offsets = table. + // If not then patching the AML would just corrupt it and result in = OS failure. + // If you encounter this assert something went wrong in *.offset.h f= iles + // generation. Remove the files and rebuild. + // + ASSERT (AmlResourceAddress64Pointer->DescriptorType =3D=3D mAmlOffse= tTablePointer[i].Opcode); + // + // Last 4 chars of AmlOffsetTable.Pathname has FIX tag. + // + Signature =3D (UINT32 *) (mAmlOffsetTablePointer[i].Pathname + Ascii= StrLen(mAmlOffsetTablePointer[i].Pathname) - 4); + Signature2 =3D (UINT32 *) (mAmlOffsetTablePointer[i].Pathname + Asci= iStrLen(mAmlOffsetTablePointer[i].Pathname) - 9); + switch (*Signature) { + // + // "FIX4" PCI64 resource for PCXX in Acpi\AcpiTables\Dsdt\SysBus.a= si and PCXX.asi + // + case (SIGNATURE_32 ('F', 'I', 'X', '4')): + if (mSocketIioConfiguration.Pci64BitResourceAllocation) { + + AcpiPciDevPath2SktStkPort (mAmlOffsetTablePointer[i].Pathname,= &Socket, &Stack, NULL); + MemBase64 =3D mIioUds->IioUdsPtr->PlatformData.IIO_resource[So= cket].StackRes[Stack].PciResourceMem64Base; + MemLimit64 =3D mIioUds->IioUdsPtr->PlatformData.IIO_resource[S= ocket].StackRes[Stack].PciResourceMem64Limit; + if (MemLimit64 > MemBase64) { + AmlResourceAddress64Pointer->Granularity =3D 0; + AmlResourceAddress64Pointer->Minimum =3D (UINT64) MemBase64; + AmlResourceAddress64Pointer->Maximum =3D (UINT64) MemLimit64; + AmlResourceAddress64Pointer->AddressLength =3D (UINT64) (Mem= Limit64 - MemBase64 + 1); + } + + Fixes++; + } + break; + + default: + DEBUG ((DEBUG_ERROR, "[ACPI](DSDT) WARNING: Object '%a' with opc= ode 0x%02X not patched\n", + mAmlOffsetTablePointer[i].Pathname, mAmlOffsetTablePoint= er[i].Opcode)); + break; + } + } else { + DEBUG ((DEBUG_ERROR, "[ACPI](DSDT) WARNING: Object '%a' with opcode = 0x%02X not patched\n", + mAmlOffsetTablePointer[i].Pathname, mAmlOffsetTablePointer[i= ].Opcode)); + } + } + + // CurrPtr =3D beginning of table + // + CurrPtr =3D (UINT8 *) TableHeader; + + // EndPtr =3D beginning of table + length of table + // + EndPtr =3D (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); + + // Subtract from End Ptr the largest data item we read from table + // so we don't try to access data beyond end of table + // + EndPtr -=3D 9; + + for (DsdtPointer =3D CurrPtr; DsdtPointer <=3D EndPtr; DsdtPointer++) { + + // + // fix CpuMemHp.asi, force no same ASL code string as it... + // + if ((DsdtPointer[0] =3D=3D 'C') && (DsdtPointer[6] =3D=3D 0x4) && (Ds= dtPointer[5] =3D=3D 0x10)) { + if (mCpuOrderSorted) { + CpuSkt =3D (UINT32) DsdtPointer[4]; + AdjustSize =3D 0; + if ((DsdtPointer[1] > '0') && (DsdtPointer[1] <=3D '9')) { + AdjustSize =3D (UINT32) ((DsdtPointer[1] -'0') * 0x100); + } else if ((DsdtPointer[1] >=3D 'A') && (DsdtPointer[1] <=3D 'F'))= { + AdjustSize =3D (UINT32) ((DsdtPointer[1] -'A' + 10) * 0x100); + } + + CpuIndex =3D AdjustSize; + + AdjustSize =3D 0; + if ((DsdtPointer[2] > '0') && (DsdtPointer[2] <=3D '9')) { + AdjustSize =3D (UINT32) ((DsdtPointer[2] -'0') * 0x10); + } else if ((DsdtPointer[2] >=3D 'A') && (DsdtPointer[2] <=3D 'F'))= { + AdjustSize =3D (UINT32) ((DsdtPointer[2] -'A' + 10) * 0x10); + } + + CpuIndex +=3D AdjustSize; + + AdjustSize =3D 0; + if ((DsdtPointer[3] > '0') && (DsdtPointer[3] <=3D '9')) { + AdjustSize =3D (UINT32) (DsdtPointer[3] -'0'); + } else if ((DsdtPointer[3] >=3D 'A') && (DsdtPointer[3] <=3D 'F'))= { + AdjustSize =3D (UINT32) (DsdtPointer[3] -'A' + 10); + } + + CpuIndex +=3D AdjustSize; + + NodeIndex =3D (UINT32) (CpuSkt << mNumOfBitShift) + mApicIdMap[Cpu= Skt][CpuIndex] ; + + DsdtPointer[4] =3D (UINT8) 0xFF; + if (((mCpuCsrAccessVarPtr->socketPresentBitMap >> CpuSkt) & BIT0) = =3D=3D 1) { + if (CheckCurrentThreadStatus (NodeIndex) =3D=3D EFI_SUCCESS) { + DsdtPointer[4] =3D (UINT8) (NodeIndex & 0xFF); + } + } + + // + // Update IO Address + // + *(UINT16 *)(DsdtPointer+5) =3D (UINT16)(PM_BASE_ADDRESS + 0x10); + } + } + + for (Socket =3D 0; Socket < MAX_SOCKET; Socket++) { + + if ((mCpuCsrAccessVarPtr->socketPresentBitMap & (BIT0 << Socket)) = =3D=3D 0) { + continue; + } + // + // Find APT##socket name + // + if ((DsdtPointer[0] =3D=3D 'A') && (DsdtPointer[1] =3D=3D 'P') && (D= sdtPointer[2] =3D=3D 'T') && (DsdtPointer[3] =3D=3D '0' + Socket)) { + NamePtr =3D ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (DsdtPointer); + ApicMapPtr =3D mApicIdMap[Socket]; + if (NamePtr->StartByte !=3D AML_NAME_OP) { + continue; + } + + Counter =3D DsdtPointer[8]; + ASSERT (Counter >=3D (UINT32) (MAX_THREAD * MAX_CORE)); + DEBUG ((DEBUG_INFO, "\n::ACPI:: Found 'APT%x'...Counter =3D DsdtP= ointer[7] =3D %x\n\n", Socket, Counter)); + for (i =3D 0; i < (MAX_THREAD * MAX_CORE); i++) { + DEBUG ((DEBUG_VERBOSE, "Before override, DsdtPointer[%x] =3D %x= , ", i, DsdtPointer[i+9])); + DsdtPointer[i+9] =3D (UINT8)ApicMapPtr[i]; + DEBUG ((DEBUG_VERBOSE, "Then override value =3D %x \n", DsdtPoi= nter[i+9])); + } + } + } + // + // Fix up _S3 + // + if ((DsdtPointer[0] =3D=3D '_') && (DsdtPointer[1] =3D=3D 'S') && (Dsd= tPointer[2] =3D=3D '3')) { + NamePtr =3D ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (DsdtPointer); + if (NamePtr->StartByte !=3D AML_NAME_OP) { + continue; + } + + if (!mSocketPowermanagementConfiguration.AcpiS3Enable) { + // + // S3 disabled + // + DsdtPointer[0] =3D 'D'; + } + } + // + // Fix up _S4 + // + if ((DsdtPointer[0] =3D=3D '_') && (DsdtPointer[1] =3D=3D 'S') && (Dsd= tPointer[2] =3D=3D '4')) { + NamePtr =3D ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (DsdtPointer); + if (NamePtr->StartByte !=3D AML_NAME_OP) { + continue; + } + if (!mSocketPowermanagementConfiguration.AcpiS4Enable) { + // + // S4 disabled + // + DsdtPointer[0] =3D 'D'; + } + } + } + return EFI_SUCCESS; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLi= b/AcpiPlatformLibFadt.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPl= atformTableLib/AcpiPlatformLibFadt.c new file mode 100644 index 0000000000..4cdb540a6a --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiP= latformLibFadt.c @@ -0,0 +1,75 @@ +/** @file + ACPI Platform Driver Hooks + + @copyright + Copyright 1996 - 2018 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// Statements that include other files +// +#include "AcpiPlatformLibLocal.h" +#include + +extern UINT8 mKBPresent; +extern UINT8 mMousePresent; +extern SOCKET_PROCESSORCORE_CONFIGURATION mSocketProcessorCoreConfigurat= ion; +extern SOCKET_POWERMANAGEMENT_CONFIGURATION mSocketPowermanagementConfigur= ation; + + +EFI_STATUS +PatchFadtTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + UINT16 LegacyDevice; + EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader; + EFI_STATUS Status; + UINT8 PcieGlobalAspm; + + Status =3D GetOptionData (&gEfiSocketIioVariableGuid, OFFSET_OF(SOCKET_I= IO_CONFIGURATION, PcieGlobalAspm), &PcieGlobalAspm, sizeof(UINT8)); + if (EFI_ERROR (Status)) { + PcieGlobalAspm =3D 0x2; + } + + // + // Patch FADT for legacy free + // + LegacyDevice =3D 0; + FadtHeader =3D (EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE *) Table; + + // + // Control of setting ASPM disabled bit in FADT + // + switch (mSocketPowermanagementConfiguration.NativeAspmEnable) { + + case 0: + LegacyDevice |=3D (1 << 4); + break; + + case 1: + LegacyDevice &=3D ~(1 << 4); + break; + + case 2: + if (PcieGlobalAspm =3D=3D 0) { + LegacyDevice |=3D (1 << 4); + } else { + LegacyDevice &=3D ~(1 << 4); + } + break; + + default: + LegacyDevice &=3D ~(1 << 4); + DEBUG ((DEBUG_ERROR, "\n Native ASPM =3D %d is not valid (expected val= ues are 0, 1, 2). \n", mSocketPowermanagementConfiguration.NativeAspmEnable= )); + ASSERT (0); + break; + } + + FadtHeader->IaPcBootArch =3D LegacyDevice; + FadtHeader->Flags |=3D (mSocketProcessorCoreConfiguration.ForcePhysicalM= odeEnable) ? EFI_ACPI_6_2_FORCE_APIC_PHYSICAL_DESTINATION_MODE : 0; + + return EFI_SUCCESS; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLi= b/AcpiPlatformLibHmat.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPl= atformTableLib/AcpiPlatformLibHmat.c new file mode 100644 index 0000000000..277c956196 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiP= latformLibHmat.c @@ -0,0 +1,1710 @@ +/** @file + ACPI Platform Library HMAT + + @copyright + Copyright 2016 - 2020 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// Statements that include other files +// +#include "AcpiPlatformLibLocal.h" +#include +#include +#include + +// +// The represented latency/bandwidth in 'System Locality Latency and Bandw= idth +// Information Structure' is expressed in multiples of Entry Base Unit. +// Unit of latency is picoseconds and bandwidth is megabytes per second +// Below #defines are be base units and values for calcualting the latency= /bandwidth +// For example: read latency of DDRT is 180ns which is 180000 picoseconds. +// This is expressed as DDRT_LATENCY_BASE_UNIT of 1000 and DDRT_READ_LATEN= CY of 180 +// + +#define MEMORY_LATENCY_BASE_UNIT 100 +#define MEMORY_BANDWIDTH_BASE_UNIT 1 +#define DDR2LMCACHE_LATENCY_BASE_UNIT 100 +#define DDR2LMCACHE_BANDWIDTH_BASE_UNIT 1 + +#define XSOCKET_LATENCY_BASE_UNIT 100 +#define XSOCKET_BANDWIDTH_BASE_UNIT 1 + +// +// DDRT values +// +#define DDRT_ACCESS_LATENCY 0 +#define DDRT_1LM_READ_LATENCY 2535 +#define DDRT_2LM_READ_LATENCY 3285 +#define DDRT_1LM_WRITE_LATENCY 2535 +#define DDRT_2LM_WRITE_LATENCY 3285 +#define DDRT_ACCESS_BANDWIDTH 0 +#define DDRT_1LM_READ_BANDWIDTH 4625 +#define DDRT_2LM_READ_BANDWIDTH 4625 +#define DDRT_1LM_WRITE_BANDWIDTH 1375 +#define DDRT_2LM_WRITE_BANDWIDTH 1375 + +// +// X-SOCKET values +// +#define XSOCKET_DDRT_1LM_ACCESS_LATENCY 0 +#define XSOCKET_DDRT_1LM_READ_LATENCY 3160 +#define XSOCKET_DDRT_1LM_WRITE_LATENCY 3160 +#define XSOCKET_DDRT_1LM_ACCESS_BANDWIDTH 0 +#define XSOCKET_DDRT_1LM_READ_BANDWIDTH 4625 +#define XSOCKET_DDRT_1LM_WRITE_BANDWIDTH 1375 + +#define XSOCKET_DDRT_2LM_ACCESS_LATENCY 0 +#define XSOCKET_DDRT_2LM_READ_LATENCY 3885 +#define XSOCKET_DDRT_2LM_WRITE_LATENCY 3885 +#define XSOCKET_DDRT_2LM_ACCESS_BANDWIDTH 0 +#define XSOCKET_DDRT_2LM_READ_BANDWIDTH 4625 +#define XSOCKET_DDRT_2LM_WRITE_BANDWIDTH 1375 + +// +// DDR values 1LM or flat mode +// +#define DDR_ACCESS_LATENCY 0 +#define DDR_READ_LATENCY 760 +#define DDR_WRITE_LATENCY 760 +#define DDR_ACCESS_BANDWIDTH 0 +#define DDR_READ_BANDWIDTH 17900 +#define DDR_WRITE_BANDWIDTH 19100 + +// +// X-Socket DDR values 1LM or flat mode +// +#define XSOCKET_DDR_ACCESS_LATENCY 0 +#define XSOCKET_DDR_READ_LATENCY 1356 +#define XSOCKET_DDR_WRITE_LATENCY 1356 +#define XSOCKET_DDR_ACCESS_BANDWIDTH 0 +#define XSOCKET_DDR_READ_BANDWIDTH 17900 +#define XSOCKET_DDR_WRITE_BANDWIDTH 19100 + +// +// DDR/X-Socket DDR values 2LM when acting as cache +// +#define DDR2LMCACHE_ACCESS_LATENCY 0 +#define DDR2LMCACHE_READ_LATENCY 760 +#define DDR2LMCACHE_WRITE_LATENCY 760 +#define DDR2LMCACHE_ACCESS_BANDWIDTH 0 +#define DDR2LMCACHE_READ_BANDWIDTH 17900 +#define DDR2LMCACHE_WRITE_BANDWIDTH 12691 + + +extern struct SystemMemoryMapHob *mSystemMemoryMap; +extern EFI_IIO_UDS_PROTOCOL *mIioUds; +extern SOCKET_MEMORY_CONFIGURATION mSocketMemoryConfiguration; +extern CPU_CSR_ACCESS_VAR *mCpuCsrAccessVarPtr; + +UINT8 SkippedEntries =3D 0; + +typedef enum { + DDR =3D 0x00, + DDRT, + DDR2LMCACHE +} MemoryType; + + +/** + Dump HMAT Header + + @param [in] HdrPtr Pointer to HMAT Header + + @retval None +**/ +VOID +DumpHeader ( + EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_HEADER *HdrPtr + ) +{ + DEBUG ((DEBUG_INFO, "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D HMAT header =3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D\n")); + DEBUG ((DEBUG_INFO, " Signature: %.4a\n", (CHAR8 *)&HdrPtr->He= ader.Signature)); + DEBUG ((DEBUG_INFO, " Length: %d\n", HdrPtr->Header.Lengt= h)); + DEBUG ((DEBUG_INFO, " Revision: %Xh\n", HdrPtr->Header.Revis= ion)); + DEBUG ((DEBUG_INFO, " Checksum: N/A - CHECKSUM ADDED LATER\n")= ); + DEBUG ((DEBUG_INFO, " OemId: %.6a\n", HdrPtr->Header.OemId= )); + DEBUG ((DEBUG_INFO, " OemTableId: %.8a\n", (CHAR8 *)&HdrPtr->He= ader.OemTableId)); + DEBUG ((DEBUG_INFO, " OemRevision: %Xh\n", HdrPtr->Header.OemRe= vision)); + DEBUG ((DEBUG_INFO, " CreatorId: %.4a\n", (CHAR8 *)&HdrPtr->He= ader.CreatorId)); + DEBUG ((DEBUG_INFO, " CreatorRevision: %Xh\n", HdrPtr->Header.Creat= orRevision)); + DEBUG ((DEBUG_INFO, "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n")); + DEBUG ((DEBUG_INFO, "\n")); +} + +/** + Dump MSARS Structure + + @param [in] MsarsPtr Pointer to MSARS Structure + + @retval None +**/ +VOID +DumpMsars ( + MEMORY_SUBSYSTEM_ADDRESS_RANGE_STRUCTURE *MsarsPtr + ) +{ + DEBUG ((DEBUG_INFO, "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D MSARS Table =3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D\n")); + DEBUG ((DEBUG_INFO, " Type: %d\n", Msar= sPtr->Type)); + DEBUG ((DEBUG_INFO, " Length: %d\n", Msar= sPtr->Length)); + DEBUG ((DEBUG_INFO, " ProcessorDomainValid: %d\n", Msar= sPtr->Flags.Bits.ProcessorDomainValid)); + DEBUG ((DEBUG_INFO, " MemoryDomainValid: %d\n", Msar= sPtr->Flags.Bits.MemoryDomainValid)); + DEBUG ((DEBUG_INFO, " ReservationHint: %d\n", Msar= sPtr->Flags.Bits.ReservationHint)); + DEBUG ((DEBUG_INFO, " ProcessorProximityDomain: %Xh\n", Msar= sPtr->ProcessorProximityDomain)); + DEBUG ((DEBUG_INFO, " MemoryProximityDomain: %Xh\n", Msar= sPtr->MemoryProximityDomain)); + DEBUG ((DEBUG_INFO, " SystemPhysicalAddressRangeBase: %llXh\n", Msar= sPtr->AddrBase)); + DEBUG ((DEBUG_INFO, " SystemPhysicalAddressRangeLength: %llXh\n", Msar= sPtr->AddrLength)); + DEBUG ((DEBUG_INFO, "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n")); + DEBUG ((DEBUG_INFO, "\n")); +} + +/** + Dump HSCIS Structure + + @param [in] MscisPtr Pointer to HSCIS Structure + + @retval None +**/ +VOID +DumpMscis ( + MEMORY_SIDE_CACHE_INFORMATION_STRUCTURE *MscisPtr + ) +{ + UINT8 SmbiosHandleIndex; + + DEBUG ((DEBUG_INFO, "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D MSCIS Table =3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D\n")); + DEBUG ((DEBUG_INFO, " Type: %d\n", Msci= sPtr->Type)); + DEBUG ((DEBUG_INFO, " Length: %d\n", Msci= sPtr->Length)); + DEBUG ((DEBUG_INFO, " MemoryProximityDomain: %Xh\n", Msci= sPtr->MemoryProximityDomain)); + DEBUG ((DEBUG_INFO, " MemorySideCacheSize: %llXh\n", Msci= sPtr->MemorySideCacheSize)); + DEBUG ((DEBUG_INFO, " TotalCacheLevels: %d\n", Msci= sPtr->CacheAttributes.Bits.TotalCacheLevels)); + DEBUG ((DEBUG_INFO, " CacheLevel: %d\n", Msci= sPtr->CacheAttributes.Bits.CacheLevel)); + DEBUG ((DEBUG_INFO, " CacheAssociativity: %d\n", Msci= sPtr->CacheAttributes.Bits.CacheAssociativity)); + DEBUG ((DEBUG_INFO, " WritePolicy: %d\n", Msci= sPtr->CacheAttributes.Bits.WritePolicy)); + DEBUG ((DEBUG_INFO, " CacheLineSize: %d\n", Msci= sPtr->CacheAttributes.Bits.CacheLineSize)); + DEBUG ((DEBUG_INFO, " NumSmbiosHandles: %d\n", Msci= sPtr->NumSmbiosHandles)); + + for (SmbiosHandleIndex =3D 0; SmbiosHandleIndex < MscisPtr->NumSmbiosHan= dles; SmbiosHandleIndex++) { + DEBUG ((DEBUG_INFO, " SmbiosHandle[%d]: %xh\n", S= mbiosHandleIndex + 1 ,MscisPtr->SmbiosHandles[SmbiosHandleIndex])); + } + DEBUG ((DEBUG_INFO, "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n")); + DEBUG ((DEBUG_INFO, "\n")); +} + +/** + Dump LBIS Structure + + @param [in] LbisPtr Pointer to LBIS Structure + + @retval None +**/ +VOID +DumpLbis ( + LATENCY_BANDWIDTH_INFO_STRUCTURE *LbisPtr + ) +{ + UINTN Index, Index1; + UINT32 *TargetProximityDomainList; + UINT16 *Entry; + + DEBUG ((DEBUG_INFO, "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D MLBIS Table =3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D\n")); + DEBUG ((DEBUG_INFO, " Type: %d\n", Lbis= Ptr->Type)); + DEBUG ((DEBUG_INFO, " Length: %d\n", Lbis= Ptr->Length)); + DEBUG ((DEBUG_INFO, " Flags: %d\n", Lbis= Ptr->Flags)); + DEBUG ((DEBUG_INFO, " DataType: %d\n", Lbis= Ptr->DataType)); + DEBUG ((DEBUG_INFO, " InitiatorProximityDomainsNumber: %d\n", Lbis= Ptr->InitiatorProximityDomainsNumber)); + DEBUG ((DEBUG_INFO, " TargetProximityDomainsNumber: %d\n", Lbis= Ptr->TargetProximityDomainsNumber)); + DEBUG ((DEBUG_INFO, " EntryBaseUnit: %lXh\n", Lbis= Ptr->EntryBaseUnit)); + DEBUG ((DEBUG_INFO, " InitiatorProximityDomainList:\n")); + + for (Index =3D 0; Index < LbisPtr->InitiatorProximityDomainsNumber; Inde= x++) { + DEBUG ((DEBUG_INFO, " %d ", LbisPtr->InitiatorProximityDomainList[Ind= ex])); + } + TargetProximityDomainList =3D (UINT32*)&(LbisPtr->InitiatorProximityDoma= inList[Index]); + DEBUG ((DEBUG_INFO, "\n")); + + DEBUG ((DEBUG_INFO, " TargetProximityDomainList:\n")); + for (Index =3D 0; Index < LbisPtr->TargetProximityDomainsNumber; Index++= ) { + DEBUG ((DEBUG_INFO, " %d ", TargetProximityDomainList[Index])); + } + Entry =3D (UINT16*)(TargetProximityDomainList + Index); + DEBUG ((DEBUG_INFO, "\n")); + + DEBUG ((DEBUG_INFO, "RelativeDistanceEntry:\n")); + for (Index =3D 0; Index < LbisPtr->InitiatorProximityDomainsNumber; Inde= x++) { + for (Index1 =3D 0; Index1 < LbisPtr->TargetProximityDomainsNumber; Ind= ex1++) { + DEBUG ((DEBUG_INFO, " %d ", *(Entry + (Index * LbisPtr->TargetProxi= mityDomainsNumber) + Index1))); + } + DEBUG ((DEBUG_INFO, "\n")); + } + DEBUG ((DEBUG_INFO, "\n")); + DEBUG ((DEBUG_INFO, "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n")); + DEBUG ((DEBUG_INFO, "\n")); +} + + +/** + Dump HMAT table + + @param [in] HmatAcpiTable Pointer to HMAT table. + + @retval None +**/ +VOID +DumpHmat ( + EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE *HmatAcpiTable + ) +{ + UINT32 TotalLength =3D HmatAcpiTable->HmatHeader.Header.Length; + UINT8 *Table =3D (UINT8 *)HmatAcpiTable; + UINT32 Length; + UINT16 Type; + + DumpHeader (&HmatAcpiTable->HmatHeader); + Length =3D sizeof (EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_HEADER); + + Table +=3D Length; + TotalLength -=3D Length; + + // + // Dump tables + // + while (TotalLength) { + Type =3D ((MEMORY_SUBSYSTEM_ADDRESS_RANGE_STRUCTURE *)Table)->Type; + // + // For HBM will need to add LBIS structure + // + if (Type =3D=3D MEMORY_SUBSYSTEM_ADDRESS_RANGE_STRUCTURE_TYPE) { + DumpMsars ((MEMORY_SUBSYSTEM_ADDRESS_RANGE_STRUCTURE *)Table); + } else if (Type =3D=3D MEMORY_SIDE_CACHE_INFORMATION_STRUCTURE_TYPE) { + DumpMscis ((MEMORY_SIDE_CACHE_INFORMATION_STRUCTURE *)Table); + } else { + DumpLbis ((LATENCY_BANDWIDTH_INFO_STRUCTURE *)Table); + } + + // + // Goto next entry + // + Length =3D ((MEMORY_SUBSYSTEM_ADDRESS_RANGE_STRUCTURE *)Table)->Length; + Table +=3D Length; + TotalLength -=3D Length; + } +} + +/** + Update SMBIOS handles and number of SMBIOS handles which is related to s= pecified NodeId to MEMORY_DOMAIN_LIST_INFO + + SMBIOS Type 17 handles are formed in sequence order. First handle is S0 = C0 D0, Second handle is S0 C0 D1 and so on. + So we loop in this order to find the handles of DDR which is part of the= specific 2LM cache memory. + + @param [in] HmatData Points to HMAT structure + @param [in] NodeId SMBIOS handles related to this NodeId will be r= etrieved + + @retval None +**/ +VOID +UpdateSmbiosHandles( + IN HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *HmatData, + IN UINT32 NodeId, + IN UINT8 Socket, + IN UINT32 ImcBitMap + ) +{ + EFI_STATUS Status; + STATIC EFI_SMBIOS_PROTOCOL *Smbios =3D NULL; + SMBIOS_TABLE_TYPE17 *Type17Record; + EFI_SMBIOS_TABLE_HEADER *SmbiosRecord; + EFI_SMBIOS_HANDLE SmbiosHandle; + EFI_SMBIOS_TYPE SmbiosType; + UINT8 Loop =3D 1; + UINT8 SlotsPerImc =3D MAX_DIMM * MAX_MC_CH; + UINT8 DimmsPerImc =3D 0; + + Status =3D gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &Smbios); + if (EFI_ERROR (Status)) { + return ; + } + + SmbiosHandle =3D SMBIOS_HANDLE_PI_RESERVED; + SmbiosType =3D 17; + + // + // Adjust ImcBitMap according to the socket number + // + if (Socket !=3D 0) { + ImcBitMap <<=3D (Socket * SlotsPerImc); + } + + if (!PcdGetBool (PcdHalfWidth)) { + DimmsPerImc =3D SlotsPerImc; + } else { + DimmsPerImc =3D SlotsPerImc - 1; + } + + do { + Status =3D Smbios->GetNext(Smbios, &SmbiosHandle, &SmbiosType, &Smbios= Record, NULL); + if (!EFI_ERROR (Status) && (SmbiosHandle !=3D SMBIOS_HANDLE_PI_RESERVE= D)) { + Type17Record =3D (SMBIOS_TABLE_TYPE17 *)SmbiosRecord; + + // + // 1) check whether the Memory device of this record is cache capabl= e(ie, 2LM DDR cache) and + // 2) this memory handle is to the current looping IMC + // + if ((Type17Record->TypeDetail.CacheDram) && (ImcBitMap & BIT0)) { + HmatData->MemoryDomainList[NodeId].SmbiosHandles[HmatData->Memor= yDomainList[NodeId].NumSmbiosHandles] =3D Type17Record->Hdr.Handle ; + HmatData->MemoryDomainList[NodeId].NumSmbiosHandles++; + } + } + // + // if loop done for this IMC then move for next + // + if (Loop % DimmsPerImc =3D=3D 0) { + ImcBitMap >>=3D 1; + } + ++Loop; + } while (!EFI_ERROR (Status) && (SmbiosHandle !=3D SMBIOS_HANDLE_PI_RESE= RVED) && (ImcBitMap !=3D 0)); +} + +/** + Remove slack by moving this substructure lower which removes unused memo= ry. + + @param [in] SlackSize Points to cumulative unused memory size + @param [in] Src Points to memory to move + @param [in] SrcLen Size of memory to move + + @retval None +**/ +VOID +RemoveSlack ( + IN UINTN *SlackSize, + IN VOID *Src, + IN UINTN SrcLen + ) +{ + VOID *Dst; + + Dst =3D (UINT8 *)Src - (*SlackSize); + CopyMem (Dst, Src, SrcLen); +} + +/** + Calculate the Memory Proximity Domain Number and generate its associate = list. + + @param [in, out] HmatData Pointer to HMAT_PROXIMITY_DOMAIN_= DATA_STRUCTURE to be filled + + @retval None. +**/ +VOID +GetMemoryDomains ( + IN OUT HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *HmatData +) +{ + UINT64 MemorySideCacheSize; + UINT32 NodeId; + UINT32 LastDomainId =3D 0; + UINT8 Index; + UINT8 PrevIndex; + UINT8 LastIndex =3D 0; + UINT8 Mc; + UINT8 Socket; + UINT8 McBitmap[EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS]; + UINT32 PmemEntry[EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS]; + UINT64 MemoryAddressStore[EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS]; + UINT64 MemoryAddress; + UINT8 MaxEnabledImc =3D 0; + UINTN ImcIndex; + UINT8 MemSocketBitmap =3D 0; + UINT8 NoMemSocketBitmap; + BOOLEAN SkipEntry; + BOOLEAN UpdateSmbiosHandle =3D FALSE; + + EFI_STATUS Status =3D EFI_SUCCESS; + DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &= DynamicSiLibraryProtocol2); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return; + } + + HmatData->MemoryDomainNumber =3D 0; + + ZeroMem (McBitmap, sizeof(McBitmap)); + ZeroMem (MemoryAddressStore, sizeof(MemoryAddressStore)); + + // + // Memory Proximity Domain must match the Domain in the SRAT Memory Affi= nity structure + // + for (Index =3D 0; Index < mSystemMemoryMap->numberEntries; Index++) { + // + // Skip any memory region marked reserved + // + if (DynamicSiLibraryProtocol2->IsMemTypeReserved (mSystemMemoryMap->El= ement[Index].Type)) { + continue; + } + + if (!DynamicSiLibraryProtocol2->IsMemTypeVolatile (mSystemMemoryMap->E= lement[Index].Type)) { + // + // Skip all non volatile regions + // + PmemEntry[SkippedEntries] =3D Index; + SkippedEntries++; + continue; + } + + SkipEntry =3D FALSE; + + MemoryAddress =3D LShiftU64 (mSystemMemoryMap->Element[Index].BaseAddr= ess, MEM_ADDR_SHFT_VAL); + + // + // Skip duplicate entries + // + if (Index) { + for (PrevIndex =3D 0; PrevIndex < Index; PrevIndex++) { + if (MemoryAddress =3D=3D MemoryAddressStore[PrevIndex]) { + SkipEntry =3D TRUE; + break; + } + } + } + if (SkipEntry) { + continue; + } + + MemoryAddressStore[Index] =3D MemoryAddress; + LastIndex =3D Index; + + for (ImcIndex =3D 0, MaxEnabledImc =3D 0; ImcIndex < MAX_IMC; ImcIndex= ++) { + if (mSystemMemoryMap->Socket[mSystemMemoryMap->Element[Index].Socket= Id].imcEnabled[ImcIndex] !=3D 0) { + MaxEnabledImc ++; + } + } + + // + // Update bitmap for sockets with memory populated + // + MemSocketBitmap |=3D BIT0 << mSystemMemoryMap->Element[Index].SocketId; + + // + // Get memory domain (must match SRAT memory domain) + // + NodeId =3D ProximityDomainOf ( + mSystemMemoryMap->Element[Index].SocketId, + mSystemMemoryMap->Element[Index].Type, + MaxEnabledImc, + HmatData->SncEnabled, + HmatData->SncNumOfCluster, + mSystemMemoryMap->Element[Index].ImcInterBitmap, + mSystemMemoryMap->volMemMode, + LastDomainId + ); + + NodeId =3D (NodeId * HmatData->VirtualNumOfCluster) + (Index % HmatDat= a->VirtualNumOfCluster); + + if (LastDomainId < NodeId) { + LastDomainId =3D NodeId; + } + + if (NodeId >=3D EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS) { + DEBUG ((DEBUG_ERROR, "[ACPI] (HMAT) ERROR: Invalid Memory Proximity = Domain (0x%x)\n", NodeId)); + ASSERT (FALSE); + } + + // + // Update map of indexes included in this memory domain + // + HmatData->MemoryDomainList[NodeId].MemMapIndexMap |=3D LShiftU64 (BIT0= , Index); + + // + // Update Memory domain count and set domain to valid + // Prevent counting repeated entries with the same Proximity Domain ID + // + if ((Index =3D=3D 0) || (HmatData->MemoryDomainList[NodeId].Valid =3D= =3D 0)) { + HmatData->MemoryDomainNumber++; + HmatData->MemoryDomainList[NodeId].PhysicalSocketId =3D mSystemMemor= yMap->Element[Index].SocketId; + HmatData->MemoryDomainList[NodeId].Valid =3D 1; + McBitmap[NodeId] =3D 0; + } + + if (HmatData->MemoryDomainList[NodeId].Valid) { + if (mSystemMemoryMap->Element[Index].Type =3D=3D MemType2lmDdrCacheM= emoryMode) { + // + // Set up side cache info for 2LM + // + HmatData->MemoryDomainList[NodeId].Cacheable =3D 1; + + // + // Calculate MemorySideCacheSize + // MemorySideCacheSize for each MC is the DDR4 memSize + // + MemorySideCacheSize =3D 0; + UpdateSmbiosHandle =3D FALSE; + + for (Mc =3D 0; Mc < MAX_IMC; Mc++) { + if ((mSystemMemoryMap->Element[Index].ImcInterBitmap & (BIT0 << = Mc)) && !(McBitmap[NodeId] & (BIT0 << Mc))) { + UpdateSmbiosHandle =3D TRUE; + if (mSystemMemoryMap->volMemMode =3D=3D VOL_MEM_MODE_2LM) { + MemorySideCacheSize +=3D mSystemMemoryMap->Socket[mSystemMem= oryMap->Element[Index].SocketId].imc[Mc].MemSize; + } else{ // VOL_MEM_MODE_MIX_1LM2LM + MemorySideCacheSize +=3D mSystemMemoryMap->DdrCacheSize[mSys= temMemoryMap->Element[Index].SocketId][Mc]; + } + } + } + + if (UpdateSmbiosHandle) { + UpdateSmbiosHandles ( + HmatData, + NodeId, + mSystemMemoryMap->Element[Index].SocketId, + mSystemMemoryMap->Element[Index].ImcInterBitmap + ); + } + HmatData->MemoryDomainList[NodeId].MemorySideCacheSize +=3D Memory= SideCacheSize; + } + McBitmap[NodeId] |=3D mSystemMemoryMap->Element[Index].ImcInterBitma= p; + } + + DEBUG ((DEBUG_INFO, "MemoryDomainList[%x] Valid =3D %x Cacheable =3D %= x MemorySideCacheSize =3D %x\n", + NodeId, + HmatData->MemoryDomainList[NodeId].Valid, + HmatData->MemoryDomainList[NodeId].Cacheable, + HmatData->MemoryDomainList[NodeId].MemorySideCacheSize + )); + } + + // + // Update LastDomainId for enabled sockets with no memory + // + NoMemSocketBitmap =3D mCpuCsrAccessVarPtr->socketPresentBitMap & ~MemSoc= ketBitmap; + for (Socket =3D 0; Socket < MAX_SOCKET; Socket++) { + if ((BIT0 << Socket) & NoMemSocketBitmap) { + LastDomainId +=3D HmatData->SncNumOfCluster; + } + } + + // + // Add skipped entries + // + for (Index =3D 0; Index < SkippedEntries; Index++) { + SkipEntry =3D FALSE; + MemoryAddress =3D LShiftU64 (mSystemMemoryMap->Element[PmemEntry[Index= ]].BaseAddress, MEM_ADDR_SHFT_VAL); + + // + // Skip duplicate entries + // + for (PrevIndex =3D 0; PrevIndex < LastIndex; PrevIndex++) { + if (MemoryAddress =3D=3D MemoryAddressStore[PrevIndex]) { + SkipEntry =3D TRUE; + break; + } + } + if (SkipEntry) { + continue; + } + + MemoryAddressStore[LastIndex++] =3D MemoryAddress; + + // + // Get memory domain (must match SRAT memory domain) + // + NodeId =3D ProximityDomainOf ( + mSystemMemoryMap->Element[PmemEntry[Index]].SocketId, + mSystemMemoryMap->Element[PmemEntry[Index]].Type, + MaxEnabledImc, + HmatData->SncEnabled, + HmatData->SncNumOfCluster, + mSystemMemoryMap->Element[PmemEntry[Index]].ImcInterBitmap, + mSystemMemoryMap->volMemMode, + LastDomainId + ); + NodeId =3D (NodeId * HmatData->VirtualNumOfCluster) + (Index % HmatDat= a->VirtualNumOfCluster); + + if (LastDomainId < NodeId) { + LastDomainId =3D NodeId; + } + + if (NodeId >=3D EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS) { + DEBUG ((DEBUG_ERROR, "[ACPI] (HMAT) ERROR: Invalid Memory Proximity = Domain (0x%x)\n", NodeId)); + ASSERT (FALSE); + } + + // + // Update map of indexes included in this memory domain + // + HmatData->MemoryDomainList[NodeId].MemMapIndexMap |=3D LShiftU64 (BIT0= , PmemEntry[Index]); + + // + // Update Memory domain count and set domain to valid + // Prevent counting repeated entries with the same Proximity Domain ID + // + if ((PmemEntry[Index] =3D=3D 0) || (HmatData->MemoryDomainList[NodeId]= .Valid =3D=3D 0)) { + HmatData->MemoryDomainNumber++; + HmatData->MemoryDomainList[NodeId].PhysicalSocketId =3D mSystemMemor= yMap->Element[PmemEntry[Index]].SocketId; + HmatData->MemoryDomainList[NodeId].Valid =3D 1; + } + + DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) MemoryDomainList[%x] Valid =3D %x C= acheable =3D %x MemorySideCacheSize =3D %x\n", + NodeId, + HmatData->MemoryDomainList[NodeId].Valid, + HmatData->MemoryDomainList[NodeId].Cacheable, + HmatData->MemoryDomainList[NodeId].MemorySideCacheSize + )); + } +} + +/** + Calculate the Processor Proximity Domain Number and generate its associa= te list. + + @param [in, out] HmatData Pointer to HMAT_PROXIMITY_DOMAIN_= DATA_STRUCTURE to be filled + + @retval None. +**/ +VOID +GetProcessorDomains ( + IN OUT HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *HmatData + ) +{ + UINT32 NodeId; + UINT8 Index; + INTN FirstImc; + UINT8 SocketId; + UINT8 SocketLogicalId; + UINT8 MemSocketBitmap; + UINT8 NoMemSocketBitmap; + + EFI_STATUS Status =3D EFI_SUCCESS; + DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &= DynamicSiLibraryProtocol2); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return; + } + + MemSocketBitmap =3D 0; + NoMemSocketBitmap =3D 0; + HmatData->ProcessorDomainNumber =3D 0; + + // + // Processor Proximity Domain must match the Domain in the SRAT APIC or = X2APIC Affinity Structure + // + for (Index =3D 0; Index < mSystemMemoryMap->numberEntries; Index++) { + // + // Skip any memory region marked reserved or FPGA + // + if (DynamicSiLibraryProtocol2->IsMemTypeReserved (mSystemMemoryMap->El= ement[Index].Type) || DynamicSiLibraryProtocol2->IsMemTypeFpga (mSystemMemo= ryMap->Element[Index].Type)) { + continue; + } + + SocketId =3D mSystemMemoryMap->Element[Index].SocketId; + SocketLogicalId =3D GetSocketLogicalId (SocketId); + + // + // Get processor proximity domain + // + if (HmatData->SncEnabled || HmatData->VirtualNumaEnabled) { + FirstImc =3D LowBitSet32 (mSystemMemoryMap->Element[Index].ImcInterB= itmap); + if (FirstImc =3D=3D -1) { + FirstImc =3D 0; + } + // + // Find the 1st IMC according the interbitmap + // + if (MAX_IMC <=3D HmatData->SncNumOfCluster) { + NodeId =3D (SocketLogicalId * HmatData->SncNumOfCluster) + (UINT32= )FirstImc; + } else { + NodeId =3D (SocketLogicalId * HmatData->SncNumOfCluster) + ((UINT3= 2)FirstImc) / HmatData->SncNumOfCluster; + } + + NodeId =3D (NodeId * HmatData->VirtualNumOfCluster) + (Index % HmatD= ata->VirtualNumOfCluster); + + DEBUG ((DEBUG_INFO, "%a: SocketId: 0x%x SncNumOfCluster: 0x%x ImcInt= erBitmap:0x%x and NodeId:0x%x\n", + __FUNCTION__, mSystemMemoryMap->Element[Index].SocketId, HmatDat= a->SncNumOfCluster, mSystemMemoryMap->Element[Index].ImcInterBitmap, NodeId= )); + } else { + NodeId =3D SocketLogicalId; + } + + if (NodeId >=3D EFI_ACPI_HMAT_NUMBER_OF_PROCESSOR_DOMAINS) { + DEBUG ((DEBUG_ERROR, "[ACPI] (HMAT) ERROR: Invalid Processor Proximi= ty Domain (0x%x)\n", NodeId)); + return; + } + + // + // Update processor domain count and set domain to valid + // Prevent counting repeated entries with the same Proximity Domain ID + // + if ((Index =3D=3D 0) || (HmatData->ProcessorDomainList[NodeId] =3D=3D = 0)) { + HmatData->ProcessorDomainNumber++; + HmatData->ProcessorDomainSocketIdList[NodeId] =3D SocketId; + HmatData->ProcessorDomainList[NodeId] =3D 1; // Domain is valid + MemSocketBitmap |=3D (BIT0 << mSystemMemoryMap->Element[Index].Socke= tId); + } + + DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) ProcessorDomainList[%x] Valid =3D %= x\n", NodeId, HmatData->ProcessorDomainList[NodeId])); + } + + // + // Update processor domain for enabled sockets without memory + // + NoMemSocketBitmap =3D mCpuCsrAccessVarPtr->socketPresentBitMap & ~MemSoc= ketBitmap; + for (SocketId =3D 0; SocketId < MAX_SOCKET; SocketId++) { + if ((BIT0 << SocketId) & NoMemSocketBitmap) { + for (Index =3D 0; Index < (HmatData->SncNumOfCluster * HmatData->Vir= tualNumOfCluster); Index++) { + NodeId =3D GetSocketLogicalId (SocketId) * HmatData->SncNumOfClust= er * HmatData->VirtualNumOfCluster + Index; + HmatData->ProcessorDomainNumber++; + HmatData->ProcessorDomainSocketIdList[NodeId] =3D SocketId; + HmatData->ProcessorDomainList[NodeId] =3D 1; + } + } + } +} + +/** + Initialize HMAT Data to be consumed when populating tables. + This Functions allocates buffer for HMAT Data, so it is caller responsib= ility to free it. + + @param None. + + @retval Pointer to allocated HMAT Data if it was initialized c= orrectly. + @retval NULL if not allocated and not initialized correctly. +**/ +UINTN * +InitializeHmatData ( + VOID +) +{ + HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *HmatData =3D NULL; + + HmatData =3D AllocateZeroPool (sizeof (HMAT_PROXIMITY_DOMAIN_DATA_STRUCT= URE)); + if (HmatData =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "[ACPI] (HMAT) ERROR: Could not allocate HmatData= structure pointer\n")); + return (UINTN *) HmatData; + } + + if (mIioUds->IioUdsPtr->SystemStatus.OutSncEn) { + HmatData->SncEnabled =3D 1; + HmatData->SncNumOfCluster =3D mIioUds->IioUdsPtr->SystemStatus.OutNumO= fCluster; + } else { + HmatData->SncNumOfCluster =3D 1; + } + + if (mSystemMemoryMap->VirtualNumaEnable) { + HmatData->VirtualNumaEnabled =3D 1; + HmatData->VirtualNumOfCluster =3D mSystemMemoryMap->VirtualNumOfCluste= r; + } else { + HmatData->VirtualNumOfCluster =3D 1; + } + + GetProcessorDomains (HmatData); + GetMemoryDomains (HmatData); + + return (UINTN *)HmatData; +} + +/** + Patch HMAT MSARS substructure. + + @param [in, out] HmatAcpiTable Points to HMAT table to be modified + @param [in, out] SlackSize Points to cumulative slack size + @param [in] HmatData HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE t= o be consumed + + @retval None +**/ +VOID +PatchHmatMsars ( + IN OUT EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE *HmatAcpiTable, + IN OUT UINTN *SlackSize, + IN HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *HmatData + ) +{ + UINT32 Index; + UINT32 PrevIndex; + UINT32 MemoryNodeId; + UINT32 ProcessorNodeId; + UINT32 Count =3D 0; + UINT32 UnusedCount; + UINT8 MemoryNodeValid; + UINT16 ProcessorNodeValid; + UINT64 MemoryAddress; + BOOLEAN SkipEntry; + INTN FirstImc; + UINT8 SocketLogicalId; + + EFI_STATUS Status =3D EFI_SUCCESS; + DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &= DynamicSiLibraryProtocol2); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return; + } + + + DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) Populating Memory Subsystem Address R= ange Structure\n")); + for (Index =3D 0; Index < mSystemMemoryMap->numberEntries; Index++) { + // + // Skip any memory region marked reserved + // + DEBUG ((DEBUG_INFO, "[ACPI] mSystemMemoryMap->Element[%d].Type =3D 0x%= x\n",Index, mSystemMemoryMap->Element[Index].Type)); + if (DynamicSiLibraryProtocol2->IsMemTypeReserved (mSystemMemoryMap->El= ement[Index].Type)) { + continue; + } + + if (Count >=3D EFI_ACPI_HMAT_MSARS_COUNT) { + DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) Invalid MSARS entry with Index = =3D 0x%x\n", Count)); + ASSERT (FALSE); + break; + } + + SkipEntry =3D FALSE; + + // + // Skip duplicate entries + // + MemoryAddress =3D LShiftU64 (mSystemMemoryMap->Element[Index].BaseAddr= ess, MEM_ADDR_SHFT_VAL); + if (Count) { + for (PrevIndex =3D 0; PrevIndex < Count; PrevIndex++) { + if (MemoryAddress =3D=3D HmatAcpiTable->Msars[PrevIndex].AddrBase)= { + SkipEntry =3D TRUE; + break; + } + } + } + if (SkipEntry) { + continue; + } + + // + // Find memory domain for this index + // + for (MemoryNodeId =3D 0; MemoryNodeId < EFI_ACPI_HMAT_NUMBER_OF_MEMORY= _DOMAINS; MemoryNodeId++) { + if (HmatData->MemoryDomainList[MemoryNodeId].MemMapIndexMap & LShift= U64(BIT0, Index)) { + break; + } + } + + // + // Fill in valid field + // + if (MemoryNodeId < EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS) { + MemoryNodeValid =3D HmatData->MemoryDomainList[MemoryNodeId].Valid; + } else { + MemoryNodeValid =3D 0; + } + + // + // Get processor domain for this index + // + if (DynamicSiLibraryProtocol2->IsMemTypeFpga (mSystemMemoryMap->Elemen= t[Index].Type)) { + ProcessorNodeValid =3D 0; // There is no processor for FPGA. + ProcessorNodeId =3D 0; // This field will be ingored for FPGA. + } else { + SocketLogicalId =3D GetSocketLogicalId (mSystemMemoryMap->Element[In= dex].SocketId); + if (HmatData->SncEnabled || HmatData->VirtualNumaEnabled) { + FirstImc =3D LowBitSet32 (mSystemMemoryMap->Element[Index].ImcInte= rBitmap); + if (FirstImc =3D=3D -1) { + FirstImc =3D 0; + } + // + // Find the 1st IMC according the interbitmap + // + if (MAX_IMC <=3D HmatData->SncNumOfCluster) { + ProcessorNodeId =3D (SocketLogicalId * HmatData->SncNumOfCluster= ) + (UINT32)FirstImc; + } else { + ProcessorNodeId =3D (SocketLogicalId * HmatData->SncNumOfCluster= ) + ((UINT32)FirstImc) / HmatData->SncNumOfCluster; + } + ProcessorNodeId =3D (ProcessorNodeId * HmatData->VirtualNumOfClust= er) + (Index % HmatData->VirtualNumOfCluster); + DEBUG ((DEBUG_INFO, "%a: SocketId: 0x%x SncNumOfCluster: 0x%x ImcI= nterBitmap:0x%x and NodeId:0x%x \n", + __FUNCTION__, mSystemMemoryMap->Element[Index].SocketId, HmatDat= a->SncNumOfCluster, mSystemMemoryMap->Element[Index].ImcInterBitmap, Proces= sorNodeId)); + } else { + ProcessorNodeId =3D SocketLogicalId; + } + + // + // Fill in valid field + // + if (ProcessorNodeId < EFI_ACPI_HMAT_NUMBER_OF_PROCESSOR_DOMAINS) { + ProcessorNodeValid =3D HmatData->ProcessorDomainList[ProcessorNode= Id]; + } else { + ProcessorNodeValid =3D 0; + } + } + + // + // The HOB has base addr in 64 MB chunks + // + HmatAcpiTable->Msars[Count].AddrBase =3D MemoryAddress; + HmatAcpiTable->Msars[Count].AddrLength =3D LShiftU64 (mSystemMemoryMap= ->Element[Index].ElementSize, MEM_ADDR_SHFT_VAL); + + HmatAcpiTable->Msars[Count].Flags.Value =3D 0; + + // + // Fill in Proximity Domains + // + HmatAcpiTable->Msars[Count].ProcessorProximityDomain =3D ProcessorNode= Id; + HmatAcpiTable->Msars[Count].Flags.Bits.ProcessorDomainValid =3D Proces= sorNodeValid; + HmatAcpiTable->Msars[Count].MemoryProximityDomain =3D MemoryNodeId; + HmatAcpiTable->Msars[Count].Flags.Bits.MemoryDomainValid =3D MemoryNod= eValid; + + DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) MSARS[%x] AddrBase =3D 0x%lx, AddrL= ength =3D 0x%lx, MemDomain =3D %x, ProcDomain =3D %x\n", + Count, + HmatAcpiTable->Msars[Count].AddrBase, + HmatAcpiTable->Msars[Count].AddrLength, + MemoryNodeId, + ProcessorNodeId + )); + Count++; + } + + // + // Update SlackSize for unused MSARS entries + // + UnusedCount =3D EFI_ACPI_HMAT_MSARS_COUNT - Count; + *SlackSize +=3D UnusedCount * sizeof(HmatAcpiTable->Msars[0]); +} + +/** + Prints HMAT LATENCY_BANDWIDTH_INFO_STRUCTURE for debug purposes. + + @param [in] Lbis Points to HMAT LATENCY_BANDWIDTH_INFO_STRU= CTURE to be printed. + + @retval None. +**/ +VOID +PrintLbisHmat ( + IN LATENCY_BANDWIDTH_INFO_STRUCTURE *Lbis + ) +{ + UINT32 Row =3D 0; + UINT32 Col =3D 0; + UINT32 RowBaseIndex =3D 0; + UINT16 *Entry; + + Entry =3D (UINT16 *) Lbis->RelativeDistanceEntry; + DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) SLLBIS Data: ")); + DEBUG ((DEBUG_INFO, "InitiatorNumber =3D %d, TargetNumber =3D %d. ", Lbi= s->InitiatorProximityDomainsNumber, Lbis->TargetProximityDomainsNumber)); + DEBUG ((DEBUG_INFO, "Entry Base Unit =3D %d \n", Lbis->EntryBaseUnit)); + + DEBUG ((DEBUG_INFO, " ")); + for (Col =3D 0; Col < Lbis->TargetProximityDomainsNumber; Col++) { + DEBUG ((DEBUG_INFO, "%02d ", Lbis->TargetProximityDomainList[Co= l])); + } + DEBUG ((DEBUG_INFO, "\n")); + for (Row =3D 0; Row < Lbis->InitiatorProximityDomainsNumber; Row++) { + RowBaseIndex =3D Row * Lbis->TargetProximityDomainsNumber; + DEBUG ((DEBUG_INFO, "%02d ", Lbis->InitiatorProximityDomainList[Row])= ); + for (Col =3D 0; Col < Lbis->TargetProximityDomainsNumber; Col++) { + DEBUG ((DEBUG_INFO, "%08d ", Entry[RowBaseIndex + Col])); + } + DEBUG ((DEBUG_INFO, "\n")); + } +} + +/** + Get the Read/Write/Access bandwidth value of the memory type. + + @param [in] DataType Type of bandwidth value that is requi= red. (Read/Write/Access) + @param [in] Type Type of memory for which Bandwidth is= required. (DDR/DDRT) + + @retval Value of the bandwidth associated with memory type. + @retval 0xFF Input parameters are invalid. +**/ + +UINT16 +GetMemoryBandWidth ( + IN UINT8 DataType, + IN MemoryType Type, + IN UINT8 volMemMode + ) +{ + if (Type =3D=3D DDRT) { // MemoryType =3D=3D DDRT + switch (DataType) { + case EFI_ACPI_HMAT_ACCESS_BANDWIDTH : + return DDRT_ACCESS_BANDWIDTH; + case EFI_ACPI_HMAT_READ_BANDWIDTH : + if (volMemMode =3D=3D VOL_MEM_MODE_1LM) { + return DDRT_1LM_READ_BANDWIDTH; + } else { + return DDRT_2LM_READ_BANDWIDTH; + } + case EFI_ACPI_HMAT_WRITE_BANDWIDTH : + if (volMemMode =3D=3D VOL_MEM_MODE_1LM) { + return DDRT_1LM_WRITE_BANDWIDTH; + } else { + return DDRT_2LM_WRITE_BANDWIDTH; + } + default: + return 0xFF; + } + } else if (Type =3D=3D DDR2LMCACHE) { + switch (DataType) { + case EFI_ACPI_HMAT_ACCESS_BANDWIDTH : + return DDR2LMCACHE_ACCESS_BANDWIDTH; + case EFI_ACPI_HMAT_READ_BANDWIDTH : + return DDR2LMCACHE_READ_BANDWIDTH; + case EFI_ACPI_HMAT_WRITE_BANDWIDTH : + return DDR2LMCACHE_WRITE_BANDWIDTH; + default: + return 0xFF; + } + } else { + switch (DataType) { + case EFI_ACPI_HMAT_ACCESS_BANDWIDTH : + return DDR_ACCESS_BANDWIDTH; + case EFI_ACPI_HMAT_READ_BANDWIDTH : + return DDR_READ_BANDWIDTH; + case EFI_ACPI_HMAT_WRITE_BANDWIDTH : + return DDR_WRITE_BANDWIDTH; + default: + return 0xFF; + } + } +} + +/** + Get the Read/Write/Access bandwidth value of the memory type across sock= ets. + + @param [in] DataType Type of bandwidth value that is requi= red. (Read/Write/Access) + @param [in] Type Type of memory for which Bandwidth is= required. (DDR/DDRT) + + @retval Value of the bandwidth associated with memory type. + @retval 0xFF Input parameters are invalid. +**/ +UINT16 +GetXSocketMemoryBandWidth ( + IN UINT8 DataType, + IN MemoryType Type, + IN UINT8 volMemMode +) +{ + if (Type =3D=3D DDRT) { // MemoryType =3D=3D DDRT + switch (DataType) { + case EFI_ACPI_HMAT_ACCESS_BANDWIDTH: + return DDRT_ACCESS_BANDWIDTH; + case EFI_ACPI_HMAT_READ_BANDWIDTH: + if (volMemMode =3D=3D VOL_MEM_MODE_1LM) { + return XSOCKET_DDRT_1LM_READ_BANDWIDTH; + } else { + return XSOCKET_DDRT_2LM_READ_BANDWIDTH; + } + case EFI_ACPI_HMAT_WRITE_BANDWIDTH: + if (volMemMode =3D=3D VOL_MEM_MODE_1LM) { + return XSOCKET_DDRT_1LM_WRITE_BANDWIDTH; + } else { + return XSOCKET_DDRT_2LM_WRITE_BANDWIDTH; + } + default: + return 0xFF; + } + } else if (Type =3D=3D DDR2LMCACHE) { + switch (DataType) { + case EFI_ACPI_HMAT_ACCESS_BANDWIDTH: + return DDR2LMCACHE_ACCESS_BANDWIDTH; + case EFI_ACPI_HMAT_READ_BANDWIDTH: + return DDR2LMCACHE_READ_BANDWIDTH; + case EFI_ACPI_HMAT_WRITE_BANDWIDTH: + return DDR2LMCACHE_WRITE_BANDWIDTH; + default: + return 0xFF; + } + } else { + switch (DataType) { + case EFI_ACPI_HMAT_ACCESS_BANDWIDTH: + return XSOCKET_DDR_ACCESS_BANDWIDTH; + case EFI_ACPI_HMAT_READ_BANDWIDTH: + return XSOCKET_DDR_READ_BANDWIDTH; + case EFI_ACPI_HMAT_WRITE_BANDWIDTH: + return XSOCKET_DDR_WRITE_BANDWIDTH; + default: + return 0xFF; + } + } +} + +/** + Get the Read/Write/Access Latency value of the memory type. + + @param [in] DataType Type of latency value that is require= d (Read/Write/Access) + @param [in] Type Type of memory for which Latency is r= equired. (DDR/DDRT) + + @retval Value of the Latency associated with memory type. + @retval 0xFF Input parameters are invalid. +**/ +UINT16 +GetMemoryLatency ( + IN UINT8 DataType, + IN MemoryType Type, + IN UINT8 volMemMode + ) +{ + if (Type =3D=3D DDRT) { // MemoryType =3D=3D DDRT + switch (DataType) { + case EFI_ACPI_HMAT_ACCESS_LATENCY : + return DDRT_ACCESS_LATENCY; + + case EFI_ACPI_HMAT_READ_LATENCY : + if (volMemMode =3D=3D VOL_MEM_MODE_1LM) { + return DDRT_1LM_READ_LATENCY; + } else { + return DDRT_2LM_READ_LATENCY; + } + + case EFI_ACPI_HMAT_WRITE_LATENCY : + if (volMemMode =3D=3D VOL_MEM_MODE_1LM) { + return DDRT_1LM_WRITE_LATENCY; + } else { + return DDRT_2LM_WRITE_LATENCY; + } + + default: + return 0xFF; + } + } else if (Type =3D=3D DDR2LMCACHE){ + switch (DataType) { + case EFI_ACPI_HMAT_ACCESS_LATENCY : + return DDR2LMCACHE_ACCESS_LATENCY; + + case EFI_ACPI_HMAT_READ_LATENCY : + return DDR2LMCACHE_READ_LATENCY; + + case EFI_ACPI_HMAT_WRITE_LATENCY : + return DDR2LMCACHE_WRITE_LATENCY; + + default: + return 0xFF; + } + } else { + switch (DataType) { + case EFI_ACPI_HMAT_ACCESS_LATENCY : + return DDR_ACCESS_LATENCY; + + case EFI_ACPI_HMAT_READ_LATENCY : + return DDR_READ_LATENCY; + + case EFI_ACPI_HMAT_WRITE_LATENCY : + return DDR_WRITE_LATENCY; + + default: + return 0xFF; + } + } +} + +/** + Get the Read/Write/Access Latency value of the memory type between socke= ts. + + @param [in] DataType Type of latency value that is require= d (Read/Write/Access) + @param [in] Type Type of memory for which Latency is r= equired. (DDR/DDRT) + + @retval Value of the Latency associated with memory type. + @retval 0xFF Input parameters are invalid. +**/ +UINT16 +GetXSocketMemoryLatency ( + IN UINT8 DataType, + IN MemoryType Type, + IN UINT8 volMemMode + ) +{ + if (Type =3D=3D DDRT) { // MemoryType =3D=3D DDRT + switch (DataType) { + + case EFI_ACPI_HMAT_ACCESS_LATENCY : + return DDRT_ACCESS_LATENCY; + + case EFI_ACPI_HMAT_READ_LATENCY : + if (volMemMode =3D=3D VOL_MEM_MODE_1LM) { + return XSOCKET_DDRT_1LM_READ_LATENCY; + } else { + return XSOCKET_DDRT_2LM_READ_LATENCY; + } + + case EFI_ACPI_HMAT_WRITE_LATENCY : + if (volMemMode =3D=3D VOL_MEM_MODE_1LM) { + return XSOCKET_DDRT_1LM_WRITE_LATENCY; + } else { + return XSOCKET_DDRT_2LM_WRITE_LATENCY; + } + + default: + return 0xFF; + } + } else if (Type =3D=3D DDR2LMCACHE){ + switch (DataType) { + + case EFI_ACPI_HMAT_ACCESS_LATENCY : + return DDR2LMCACHE_ACCESS_LATENCY; + + case EFI_ACPI_HMAT_READ_LATENCY : + return DDR2LMCACHE_READ_LATENCY; + + case EFI_ACPI_HMAT_WRITE_LATENCY : + return DDR2LMCACHE_WRITE_LATENCY; + + default: + return 0xFF; + } + } else { + switch (DataType) { + + case EFI_ACPI_HMAT_ACCESS_LATENCY : + return XSOCKET_DDR_ACCESS_LATENCY; + + case EFI_ACPI_HMAT_READ_LATENCY : + return XSOCKET_DDR_READ_LATENCY; + + case EFI_ACPI_HMAT_WRITE_LATENCY : + return XSOCKET_DDR_WRITE_LATENCY; + + default: + return 0xFF; + } + } +} + +/** + Patch HMAT LATENCY_BANDWIDTH_INFO_STRUCTURE structure. + + @param [in] Lbis Points to HMAT LATENCY_BANDWIDTH_INFO= _STRUCTURE to be modified + @param [in, out] LibsSlackSize Points to cummulative LIBS slack size + @param [in] HmatData HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE = to be consumed + + @retval None +**/ +VOID +PatchBandWidthLbis ( + IN LATENCY_BANDWIDTH_INFO_STRUCTURE **LbisPtr, + IN OUT UINTN *LibsSlackSize, + IN HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *HmatData, + IN UINT8 DataType, + IN MemoryType Type, + IN UINT8 volMemMode + ) +{ + UINT32 Row =3D 0; + UINT32 Col =3D 0; + UINT32 RowSocketId =3D 0; + UINT32 ColSocketId =3D 0; + UINT32 RowBaseIndex =3D 0; + UINT32 StructSize =3D 0; + UINT32 InitiatorIndex =3D 0; + UINT32 TargetIndex =3D 0; + LATENCY_BANDWIDTH_INFO_STRUCTURE *Lbis =3D *LbisPtr; + UINT32 *InitiatorProximityDomainList =3D (UINT32*)Lbis; + UINT32 *TargetProximityDomainList =3D (UINT32*)Lbis; + UINT16 *RelativeDistanceEntry =3D (UINT16*)Lbis; + + Lbis->Type =3D SYSTEM_LOCALITY_LATENCY_BANDWIDTH_INFORMATION_STRUCTURE_T= YPE; + Lbis->DataType =3D DataType; + Lbis->InitiatorProximityDomainsNumber =3D HmatData->ProcessorDomainNumbe= r; + Lbis->TargetProximityDomainsNumber =3D HmatData->MemoryDomainNumber; + + switch (Type) { + + case DDR2LMCACHE: + Lbis->EntryBaseUnit =3D DDR2LMCACHE_BANDWIDTH_BASE_UNIT; + Lbis->Flags =3D EFI_ACPI_HMAT_MEMORY_HIERACHY_LAST_LEVEL_MEMORY; + break; + + default: + Lbis->EntryBaseUnit =3D MEMORY_BANDWIDTH_BASE_UNIT; + Lbis->Flags =3D EFI_ACPI_HMAT_MEMORY_HIERACHY_MEMORY; + } + + InitiatorProximityDomainList =3D (UINT32*)&(Lbis->InitiatorProximityDoma= inList[0]); + StructSize =3D (UINT32)((UINT8*)InitiatorProximityDomainList - (UINT8*)L= bis); + StructSize +=3D (Lbis->InitiatorProximityDomainsNumber * (sizeof (UINT32= ))); + TargetProximityDomainList =3D (UINT32*)((UINT8*)TargetProximityDomainLis= t + StructSize); + StructSize +=3D (Lbis->TargetProximityDomainsNumber * (sizeof (UINT32))); + RelativeDistanceEntry =3D (UINT16*)((UINT8*)RelativeDistanceEntry + Stru= ctSize); + StructSize +=3D (Lbis->InitiatorProximityDomainsNumber * Lbis->TargetPro= ximityDomainsNumber * (sizeof (UINT16))); + + Lbis->Length =3D StructSize; + + for (Row =3D 0; Row < Lbis->InitiatorProximityDomainsNumber; Row++) { + *(InitiatorProximityDomainList + Row) =3D Row; + } + for (Row =3D 0; Row < Lbis->TargetProximityDomainsNumber; Row++) { + *(TargetProximityDomainList + Row) =3D Row; + } + Row =3D 0; + for (InitiatorIndex =3D 0; InitiatorIndex < EFI_ACPI_HMAT_NUMBER_OF_PROC= ESSOR_DOMAINS; InitiatorIndex++) { + if (HmatData->ProcessorDomainList[InitiatorIndex] =3D=3D 1) { + RowSocketId =3D HmatData->ProcessorDomainSocketIdList[InitiatorIndex= ]; + RowBaseIndex =3D Row * Lbis->TargetProximityDomainsNumber; + Col =3D 0; + for (TargetIndex =3D 0; TargetIndex < EFI_ACPI_HMAT_NUMBER_OF_MEMORY= _DOMAINS; TargetIndex++) { + if (HmatData->MemoryDomainList[TargetIndex].Valid =3D=3D 1) { + ColSocketId =3D HmatData->MemoryDomainList[TargetIndex].Physical= SocketId; + if (Type =3D=3D DDR2LMCACHE) { + // + // DDR acting as cache for DDRT + //SocketsLinked + // + if (SocketsLinked (RowSocketId, ColSocketId)) { + RelativeDistanceEntry[RowBaseIndex + Col] =3D GetXSocketMemo= ryBandWidth (DataType, Type, volMemMode); + } else { + RelativeDistanceEntry[RowBaseIndex + Col] =3D GetMemoryBandW= idth (DataType, Type, volMemMode); + } + } else if (mSystemMemoryMap->volMemMode =3D=3D VOL_MEM_MODE_2LM)= { + // + // Add only details for DDRT as entire DDR is acting as Cache + // + if (SocketsLinked (RowSocketId, ColSocketId)) { + RelativeDistanceEntry[RowBaseIndex + Col] =3D GetXSocketMemo= ryBandWidth (DataType, DDRT, volMemMode); + } else { + RelativeDistanceEntry[RowBaseIndex + Col] =3D GetMemoryBandW= idth (DataType, DDRT, volMemMode); + } + } else { + // + // Neither cache nor 2LM, we need to add details for both DDR = and DDRT + // + if ((Col / (HmatData->MemoryDomainNumber- SkippedEntries)) =3D= =3D 0) { + // + // DDR entries + // + if (SocketsLinked (RowSocketId, ColSocketId)) { + RelativeDistanceEntry[RowBaseIndex + Col] =3D GetXSocketMe= moryBandWidth (DataType, DDR, volMemMode); + } else { + RelativeDistanceEntry[RowBaseIndex + Col] =3D GetMemoryBan= dWidth (DataType, DDR, volMemMode); + } + } else { + // + // DDRT entries + // + if (SocketsLinked (RowSocketId, ColSocketId)) { + RelativeDistanceEntry[RowBaseIndex + Col] =3D GetXSocketMe= moryBandWidth (DataType, DDRT, volMemMode); + } else { + RelativeDistanceEntry[RowBaseIndex + Col] =3D GetMemoryBan= dWidth (DataType, DDRT, volMemMode); + } + } + } + Col++; + } //if (HmatData->MemoryDomainList[TargetIndex].Valid =3D=3D 1) + } // for (TargetIndex) + Row++; + } // if (HmatData->ProcessorDomainList[InitiatorIndex] =3D=3D 1) + } //for (InitiatorIndex) + + *LibsSlackSize +=3D StructSize; + *LbisPtr =3D (LATENCY_BANDWIDTH_INFO_STRUCTURE *)((UINT8*)Lbis + StructS= ize); +} + +/** + Patch HMAT LATENCY_BANDWIDTH_INFO_STRUCTURE structure. + + @param [in] Lbis Points to HMAT LATENCY_BANDWIDTH_INFO_STRU= CTURE to be modified + @param [in, out] LibsSlackSize Points to cumulative LIBS slack size + @param [in] HmatData HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE to be= consumed + + @retval None +**/ +VOID +PatchMemoryLatencyLbis ( + IN LATENCY_BANDWIDTH_INFO_STRUCTURE **LbisPtr, + IN OUT UINTN *LibsSlackSize, + IN HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *HmatData, + IN UINT8 DataType, + IN MemoryType Type, + IN UINT8 volMemMode + ) +{ + UINT32 Row =3D 0; + UINT32 Col =3D 0; + UINT32 RowSocketId =3D 0; + UINT32 ColSocketId =3D 0; + UINT32 RowBaseIndex =3D 0; + UINT32 StructSize =3D 0; + UINT32 InitiatorIndex =3D 0; + UINT32 TargetIndex =3D 0; + LATENCY_BANDWIDTH_INFO_STRUCTURE *Lbis =3D *LbisPtr; + UINT32 *InitiatorProximityDomainList =3D (UINT32*)Lbis; + UINT32 *TargetProximityDomainList =3D (UINT32*)Lbis; + UINT16 *RelativeDistanceEntry =3D (UINT16*)Lbis; + + Lbis->Type =3D SYSTEM_LOCALITY_LATENCY_BANDWIDTH_INFORMATION_STRUCTURE_T= YPE; + Lbis->DataType =3D DataType; + Lbis->InitiatorProximityDomainsNumber =3D HmatData->ProcessorDomainNumbe= r; + Lbis->TargetProximityDomainsNumber =3D HmatData->MemoryDomainNumber; + + switch (Type) { + + case DDR2LMCACHE: + Lbis->EntryBaseUnit =3D DDR2LMCACHE_BANDWIDTH_BASE_UNIT; + Lbis->Flags =3D EFI_ACPI_HMAT_MEMORY_HIERACHY_LAST_LEVEL_MEMORY; + break; + + default: + Lbis->EntryBaseUnit =3D MEMORY_LATENCY_BASE_UNIT; + Lbis->Flags =3D EFI_ACPI_HMAT_MEMORY_HIERACHY_MEMORY; + } + + InitiatorProximityDomainList =3D (UINT32*)&(Lbis->InitiatorProximityDoma= inList[0]); + StructSize =3D (UINT32)((UINT8*)InitiatorProximityDomainList - (UINT8*)L= bis); + StructSize +=3D (Lbis->InitiatorProximityDomainsNumber * (sizeof (UINT32= ))); + TargetProximityDomainList =3D (UINT32*)((UINT8*)TargetProximityDomainLis= t + StructSize); + StructSize +=3D (Lbis->TargetProximityDomainsNumber * (sizeof (UINT32))); + RelativeDistanceEntry =3D (UINT16*)((UINT8*)RelativeDistanceEntry + Stru= ctSize); + StructSize +=3D (Lbis->InitiatorProximityDomainsNumber * Lbis->TargetPro= ximityDomainsNumber * (sizeof (UINT16))); + + Lbis->Length =3D StructSize; + + for (Row =3D 0; Row < Lbis->InitiatorProximityDomainsNumber; Row++) { + *(InitiatorProximityDomainList + Row) =3D Row; + } + for (Row =3D 0; Row < Lbis->TargetProximityDomainsNumber; Row++) { + *(TargetProximityDomainList + Row) =3D Row; + } + Row =3D 0; + for (InitiatorIndex =3D 0; InitiatorIndex < EFI_ACPI_HMAT_NUMBER_OF_PROC= ESSOR_DOMAINS; InitiatorIndex++) { + if (HmatData->ProcessorDomainList[InitiatorIndex] =3D=3D 1) { + RowSocketId =3D HmatData->ProcessorDomainSocketIdList[InitiatorIndex= ]; + RowBaseIndex =3D Row * Lbis->TargetProximityDomainsNumber; + Col =3D 0; + for (TargetIndex =3D 0; TargetIndex < EFI_ACPI_HMAT_NUMBER_OF_MEMORY= _DOMAINS; TargetIndex++) { + if (HmatData->MemoryDomainList[TargetIndex].Valid =3D=3D 1) { + ColSocketId =3D HmatData->MemoryDomainList[TargetIndex].Physical= SocketId; + if (Type =3D=3D DDR2LMCACHE) { + // + // DDR acting as cache for DDRT + // + if (SocketsLinked (RowSocketId, ColSocketId)) { + RelativeDistanceEntry[RowBaseIndex + Col] =3D GetXSocketMemo= ryLatency (DataType, Type, volMemMode); + } else { + RelativeDistanceEntry[RowBaseIndex + Col] =3D GetMemoryLaten= cy (DataType, Type, volMemMode); + } + } else if (mSystemMemoryMap->volMemMode =3D=3D VOL_MEM_MODE_2LM)= { + // + // Add only details for DDRT as entire DDR is acting as Cache + // + if (SocketsLinked (RowSocketId, ColSocketId)) { + RelativeDistanceEntry[RowBaseIndex + Col] =3D GetXSocketMemo= ryLatency (DataType, DDRT, volMemMode); + } else { + RelativeDistanceEntry[RowBaseIndex + Col] =3D GetMemoryLaten= cy (DataType, DDRT, volMemMode); + } + } else { + // + // Neither cache nor 2LM, we need to add details for both DDR = and DDRT + // + if ((Col / (HmatData->MemoryDomainNumber - SkippedEntries)) = =3D=3D 0) { + // + // DDR entries + // + if (SocketsLinked (RowSocketId, ColSocketId)) { + RelativeDistanceEntry[RowBaseIndex + Col] =3D GetXSocketMe= moryLatency (DataType, DDR, volMemMode); + } else { + RelativeDistanceEntry[RowBaseIndex + Col] =3D GetMemoryLat= ency (DataType, DDR, volMemMode); + } + } else { + // + // DDRT entries + // + if (SocketsLinked (RowSocketId, ColSocketId)) { + RelativeDistanceEntry[RowBaseIndex + Col] =3D GetXSocketMe= moryLatency (DataType, DDRT, volMemMode); + } else { + RelativeDistanceEntry[RowBaseIndex + Col] =3D GetMemoryLat= ency (DataType, DDRT, volMemMode); + } + } + } + Col++; + } //if (HmatData->MemoryDomainList[TargetIndex].Valid =3D=3D 1) + } // for (TargetIndex) + Row++; + } // if (HmatData->ProcessorDomainList[InitiatorIndex] =3D=3D 1) + } //for (InitiatorIndex) + + *LibsSlackSize +=3D StructSize; + *LbisPtr =3D (LATENCY_BANDWIDTH_INFO_STRUCTURE *)((UINT8*)Lbis + StructS= ize); +} + +/** + Patch HMAT LATENCY_BANDWIDTH_INFO_STRUCTURE structure. + + @param [in] Lbis Points to HMAT LATENCY_BANDWIDTH_INFO_STRU= CTURE to be modified + @param [in, out] SlackSize Points to cummulative slack size + @param [in] HmatData HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE to be= consumed + + @retval None +**/ +VOID +PatchHmatLbis ( + IN LATENCY_BANDWIDTH_INFO_STRUCTURE *Lbis, + IN OUT UINTN *SlackSize, + IN HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *HmatData + ) +{ + UINTN LibsStructSize=3D0; + UINT8 volMemMode; + LATENCY_BANDWIDTH_INFO_STRUCTURE *OrginalLbis =3D Lbis; + + volMemMode =3D mSystemMemoryMap->volMemMode; + + DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) Populating System Locality Latency an= d Bandwidth Information Structure\n")); + + PatchMemoryLatencyLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMAT_= READ_LATENCY, DDR, volMemMode); + PatchMemoryLatencyLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMAT_= WRITE_LATENCY, DDR, volMemMode); + PatchBandWidthLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMAT_READ= _BANDWIDTH, DDR, volMemMode); + PatchBandWidthLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMAT_WRIT= E_BANDWIDTH, DDR, volMemMode); + + if (mSystemMemoryMap->volMemMode !=3D VOL_MEM_MODE_1LM) { + PatchMemoryLatencyLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMA= T_READ_LATENCY, DDR2LMCACHE, volMemMode); + PatchMemoryLatencyLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMA= T_WRITE_LATENCY, DDR2LMCACHE, volMemMode); + PatchBandWidthLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMAT_RE= AD_BANDWIDTH, DDR2LMCACHE, volMemMode); + PatchBandWidthLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMAT_WR= ITE_BANDWIDTH, DDR2LMCACHE, volMemMode); + } + + RemoveSlack (SlackSize, OrginalLbis, LibsStructSize); + *SlackSize +=3D EFI_ACPI_HMAT_LBIS_COUNT * sizeof(Lbis[0]) - LibsStructS= ize; +} + +/** + Get Type 17 Handles for HBM devices used as cache. + + @param [in, out] SmbiosHandles Points to SmbiosHandles array to be m= odified + @param [in] NumaNode Value for NUMA Node whose memory is b= eing cached for the specific HBM devices + @retval None +**/ +VOID +GetHbmCacheHandles ( + IN UINT16 *SmbiosHandles, + IN UINT8 NumaNode + ) +{ + EFI_STATUS Status =3D EFI_SUCCESS; + SMBIOS_TABLE_TYPE17 *SmbiosType17Record; + EFI_SMBIOS_HANDLE SmbiosHandle =3D 0; + EFI_SMBIOS_PROTOCOL *mSmbios; + EFI_SMBIOS_TYPE SmbiosType =3D EFI_SMBIOS_TYPE_M= EMORY_DEVICE; + EFI_SMBIOS_TABLE_HEADER *SmbiosRecord; + UINT8 HbmHandleCount =3D 0; + + Status =3D gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)= &mSmbios); + if (!(EFI_ERROR (Status))) { + while ((!(EFI_ERROR (Status))) && (SmbiosHandle !=3D SMBIOS_HANDLE_PI_= RESERVED) ){ + Status =3D mSmbios->GetNext (mSmbios, &SmbiosHandle, &SmbiosType, &S= mbiosRecord, NULL); + SmbiosType17Record =3D (SMBIOS_TABLE_TYPE17 *) SmbiosRecord; + if ((SmbiosType17Record->TypeDetail.CacheDram =3D=3D 1) && (SmbiosT= ype17Record->DeviceSet =3D=3D NumaNode) ) { + SmbiosHandles[HbmHandleCount] =3D SmbiosType17Record->Hdr.Handle; + HbmHandleCount++; + } + } + } +} + +/** + Patch HMAT MEMORY_SIDE_CACHE_INFORMATION_STRUCTURE substructure. + + @param [in, out] Mscis Points to HMAT MEMORY_SIDE_CACHE_INFORMAT= ION_STRUCTURE to be modified + @param [in, out] SlackSize Points to cumulative slack size + @param [in] HmatData HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE to b= e consumed + + @retval None +**/ +VOID +PatchHmatMscis ( + IN OUT MEMORY_SIDE_CACHE_INFORMATION_STRUCTURE *Mscis, + IN OUT UINTN *SlackSize, + IN HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *HmatData + ) +{ + UINT32 Index; + UINT32 Count =3D 0; + UINT32 UnusedCount; + UINT8 SmbiosHandleIndex; + + DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) Populating Memory Side Cache Informat= ion Structure\n")); + + for (Index =3D 0; Index < EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS; Index+= +) { + if ((HmatData->MemoryDomainList[Index].Valid =3D=3D 0) || (HmatData->M= emoryDomainList[Index].Cacheable =3D=3D 0)) { + continue; + } + + // + // Fill in fields for Cached Memory Domains + // + Mscis[Count].MemoryProximityDomain =3D Index; + Mscis[Count].CacheAttributes.Bits.TotalCacheLevels =3D EFI_ACPI_HMAT_O= NE_LEVEL_CACHE; + Mscis[Count].CacheAttributes.Bits.CacheLevel =3D EFI_ACPI_HMAT_ONE_LEV= EL_CACHE; + Mscis[Count].CacheAttributes.Bits.CacheLineSize =3D DDR4_CACHE_LINE_SI= ZE; + Mscis[Count].CacheAttributes.Bits.CacheAssociativity =3D EFI_ACPI_HMAT= _CACHE_ASSOCIATIVITY_DIRECT_MAPPED; + Mscis[Count].CacheAttributes.Bits.WritePolicy =3D EFI_ACPI_HMAT_WRITE_= POLICY_WB; + Mscis[Count].MemorySideCacheSize =3D LShiftU64 (HmatData->MemoryDomain= List[Index].MemorySideCacheSize, MEM_ADDR_SHFT_VAL); + Mscis[Count].NumSmbiosHandles =3D HmatData->MemoryDomainList[Index].Nu= mSmbiosHandles; + for(SmbiosHandleIndex =3D 0 ; SmbiosHandleIndex < HmatData->MemoryDoma= inList[Index].NumSmbiosHandles; SmbiosHandleIndex++){ + Mscis[Count].SmbiosHandles[SmbiosHandleIndex] =3D HmatData->MemoryDo= mainList[Index].SmbiosHandles[SmbiosHandleIndex]; + } + + DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) MSCIS[%x] MemorySideCacheSize =3D 0= x%lx, ProximityDomain =3D %x\n", Count, Mscis[Count].MemorySideCacheSize, I= ndex)); + + Count++; + } + + // + // Move MSCIS entries up to replace removed MSARS entries + // + if (*SlackSize && Count) { + RemoveSlack (SlackSize, Mscis, Count * sizeof(Mscis[0])); + } + + // + // Update SlackSize for unused MSCIS entries + // + UnusedCount =3D EFI_ACPI_HMAT_MSCIS_COUNT - Count; + *SlackSize +=3D UnusedCount * sizeof(Mscis[0]); +} + +/** + Update the HMAT table. + + @param [in, out] HmatAcpiTable The table to be set. + + @retval EFI SUCCESS Procedure returned successfully. +**/ +EFI_STATUS +PatchHmatAcpiTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + UINTN SlackSize =3D 0; + HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *HmatData =3D NULL; + EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE *HmatAcpiTable; + + if (mSystemMemoryMap =3D=3D NULL) { + + ASSERT (FALSE); + return EFI_UNSUPPORTED; + } + + HmatAcpiTable =3D (EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE *)Table; + + HmatData =3D (HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *) InitializeHmatData= (); + if (HmatData =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "ACPI (HMAT) HMAT Data could not be initialized..= . skipping HMAT Patch\n")); + return EFI_OUT_OF_RESOURCES; + } + + // + // Patch the MSARS, SLLBIS, and MSCIS Structure from HMAT Table. + // + PatchHmatMsars (HmatAcpiTable, &SlackSize, HmatData); + PatchHmatLbis (HmatAcpiTable->Lbis, &SlackSize, HmatData); + PatchHmatMscis (HmatAcpiTable->MemSideCache, &SlackSize, HmatData); + + if (HmatData !=3D NULL) { + FreePool (HmatData); + } + + // + // Update HMAT table size + // + HmatAcpiTable->HmatHeader.Header.Length -=3D (UINT32)SlackSize; + + // + // Dump HMAT + // + DumpHmat (HmatAcpiTable); + + return EFI_SUCCESS; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLi= b/AcpiPlatformLibLocal.h b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiP= latformTableLib/AcpiPlatformLibLocal.h new file mode 100644 index 0000000000..4e0d9eaa8f --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiP= latformLibLocal.h @@ -0,0 +1,441 @@ +/** @file + + @copyright + Copyright 1999 - 2020 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _ACPI_PLATFORM__LIB_LOCAL_H_ +#define _ACPI_PLATFORM__LIB_LOCAL_H_ + +// +// Statements that include other header files +// +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // came from https://acpica.org/downloads/sourc= e_code.php acpica-win-20130214.zip/source/include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define OEM1_SSDT_TABLE_SIGNATURE SIGNATURE_32('O', 'E', 'M', '1') +#define OEM2_SSDT_TABLE_SIGNATURE SIGNATURE_32('O', 'E', 'M', '2') +#define OEM3_SSDT_TABLE_SIGNATURE SIGNATURE_32('O', 'E', 'M', '3') +#define OEM4_SSDT_TABLE_SIGNATURE SIGNATURE_32('O', 'E', 'M', '4') + +#define AML_NAME_OP 0x08 +#define AML_NAME_PREFIX_SIZE 0x06 +#define AML_NAME_DWORD_SIZE 0x0C + +#ifndef AML_EXTERNAL_OP +#define AML_EXTERNAL_OP 0x15 /* ACPI 6.0 */ +#endif + +#define GPSS_FVID_MAX_STATES 40 // Greater Than 16 p-state support + +// +// mCpuPCPSInfo usage +// +#define B_PCPS_DISABLE (1 << 17) // Bit 17 +#define B_PCPS_HT_ENABLE (1 << 16) // Bit 16 +#define PCIE_BUS_0 0x00 +#define PCIE_BUS_1 0x01 +#define PCIE_BUS_2 0x02 +#define PCIE_BUS_3 0x03 +#define PCIE_BUS_4 0x04 +#define PCIE_BUS_5 0x05 + +#define PCIE_PORT_ALL_FUNC 0x00 + +#define PCIE_PORT_0_DEV 0x00 + +#define PCIE_PORT_1A_DEV 0x00 +#define PCIE_PORT_1B_DEV 0x01 +#define PCIE_PORT_1C_DEV 0x02 +#define PCIE_PORT_1D_DEV 0x03 + +#define PCIE_PORT_2A_DEV 0x00 +#define PCIE_PORT_2B_DEV 0x01 +#define PCIE_PORT_2C_DEV 0x02 +#define PCIE_PORT_2D_DEV 0x03 + +#define PCIE_PORT_3A_DEV 0x00 +#define PCIE_PORT_3B_DEV 0x01 +#define PCIE_PORT_3C_DEV 0x02 +#define PCIE_PORT_3D_DEV 0x03 + +#define PCIE_PORT_4A_DEV 0x00 +#define PCIE_PORT_4B_DEV 0x01 +#define PCIE_PORT_4C_DEV 0x02 +#define PCIE_PORT_4D_DEV 0x03 + +#define PCIE_PORT_5_DEV 0x00 + +#define MAX_IO_APICS_10NM 1 + +// +// Define flag bits +// +#define POLARITY_ACTIVE_HIGH 0x01 +#define POLARITY_ACTIVE_LOW 0x03 +#define TRIGGERMODE_EDGE 0x04 +#define TRIGGERMODE_LEVEL 0x0C + +#pragma pack(1) +typedef struct { + UINT32 AcpiProcessorId; + UINT32 ApicId; + UINT32 Flags; + UINT32 SocketNum; +} CPU_ID_ORDER_MAP; + +typedef struct { + UINT8 AcpiProcessorId; + UINT8 ApicId; + UINT16 Flags; +} CPU_ID_MAP; + +typedef struct { + UINT8 StartByte; + UINT32 NameStr; + UINT8 Size; + UINT32 Value; +} ACPI_NAMEPACK_DWORD; + +typedef struct { + UINT8 StartByte; + UINT32 NameStr; + UINT8 OpCode; + UINT16 Size; // Hardcode to 16bit width because the= table we use is fixed size + UINT8 NumEntries; +} ACPI_NAME_COMMAND; + +typedef struct { + UINT8 PackageOp; + UINT8 PkgLeadByte; + UINT8 NumEntries; + UINT8 DwordPrefix0; + UINT32 CoreFreq; + UINT8 DwordPrefix1; + UINT32 Power; + UINT8 DwordPrefix2; + UINT32 TransLatency; + UINT8 DwordPrefix3; + UINT32 BMLatency; + UINT8 DwordPrefix4; + UINT32 Control; + UINT8 DwordPrefix5; + UINT32 Status; +} PSS_PACKAGE; + +typedef struct { + UINT8 NameOp; // 08h ;First opcode is a NameOp. + UINT32 PackageName; // PSDC/PSDE + UINT8 Length; + UINT8 DwordPrefix1; + UINT8 Revision; + UINT8 PackageOp; + UINT8 PackageLen; + UINT8 PackLen; + UINT16 WordValue1; + UINT16 WordValue2; + UINT8 BytePrefix2; + UINT32 Domain; + UINT8 BytePrefix3; + UINT8 CoordType; // 0xFC(SW_ALL), 0xFE(HW_ALL) + UINT8 BytePrefix4; + UINT32 NumProcessors; +} PSD_PACKAGE_LAYOUT; + +struct CpcRegPack { + UINT8 ResourceOp; // 11h + UINT8 Length; // 14h + UINT32 FFixedHW; + UINT32 RegisterBitsUsage; + UINT32 RegisterBitsShift; + UINT32 RegisterOffset; + UINT32 RegisterByteSize; +}; + +typedef struct { + UINT8 ExternalOp; + UINT8 RootChar; + UINT8 MultiNamePrefix; + UINT8 SegCount; + UINT32 NameStr[0]; +} EXTERNAL_OBJECT_DECL; + +#define ACPI_NAME_COMMAND_FROM_NAME_STR(a) BASE_CR (a, ACPI_NAME_COMMAND,= NameStr) +#define ACPI_NAME_COMMAND_FROM_NAMEPACK_STR(a) BASE_CR (a, ACPI_NAMEPACK_= DWORD, NameStr) +#define ACPI_EXTERNAL_OBJECT_DECL_FROM_NAME_STR(a) BASE_CR (a, EXTERNAL_OB= JECT_DECL, NameStr) + +// +// Private Driver Data +// +// +// Define Union of IO APIC & Local APIC structure; +// +typedef union { + EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_STRUCTURE AcpiLocalApic; + EFI_ACPI_6_2_IO_APIC_STRUCTURE AcpiIoApic; + EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_STRUCTURE AcpiLocalx2Apic; + struct { + UINT8 Type; + UINT8 Length; + } AcpiApicCommon; +} ACPI_APIC_STRUCTURE_PTR; + +#pragma pack() + +EFI_STATUS +PatchBdatAcpiTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ); + +/** + Build from scratch and install the MADT. + + @retval EFI_SUCCESS The MADT was installed successfully. + @retval EFI_OUT_OF_RESOURCES Could not allocate required structures. +**/ +EFI_STATUS +InstallMadtFromScratch ( + VOID + ); + +EFI_STATUS +InstallSratTable ( + VOID + ); + +EFI_STATUS +PatchFadtTable( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ); + +EFI_STATUS +PatchDsdtTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ); + +EFI_STATUS +PatchMcfgAcpiTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ); + +EFI_STATUS +PatchSLitTable( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ); + +EFI_STATUS +InstallSlitTable( + VOID + ); + +/** + Finds the Proximity Domain which the element in the Memory Map belongs t= o. + + @param [in] SocketId SocketId which the element belongs to. + @param [in] MemType MemType of the element. + @param [in] SncEnabled Bit to indicate if SNC is enabled in the se= tup options. + @param [in] ImcInterBitmap IMC interleave bitmap for this element. + @param [in] MemMode Current memory mode. 1LM, 2LM etc. + @param [in] LastDomainId Last Domain ID. + + @retval Proximity Domain. + +**/ +UINT32 +ProximityDomainOf ( + UINT8 SocketId, + UINT16 MemType, + UINT8 MaxEnabledImc, + UINT8 SncEnabled, + UINT8 SncNumOfCluster, + UINT8 ImcInterBitmap, + UINT8 MemMode, + UINT32 LastDomainId + ); + +EFI_STATUS +PatchSratTable ( + IN OUT STATIC_RESOURCE_AFFINITY_TABLE *Table + ); + +EFI_STATUS +PatchSsdtTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table, + IN OUT EFI_ACPI_TABLE_VERSION *Version + ); + +EFI_STATUS +PatchCpuPmSsdtTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ); + +EFI_STATUS +PatchOem1SsdtTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ); + +EFI_STATUS +PatchOem2SsdtTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ); + +EFI_STATUS +PatchOem3SsdtTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ); + +EFI_STATUS +PatchOem4SsdtTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ); + +EFI_STATUS +UpdateNfitTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ); + +EFI_STATUS +UpdatePcatTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ); + +/** + Detect the APICID map and initialize the module global pointer. +**/ +VOID +DetectApicIdMap ( + VOID + ); + +/** + Sort CPU Local APIC Information. + + This function gets the CPU local APIC information from the MP service + protocol into the local table structure, and sorts it based on APIC ID. + + @retval EFI_SUCCESS Local APIC information was successfully sorted. +**/ +EFI_STATUS +SortCpuLocalApicInTable ( + VOID + ); + +/** + Get the socket logical index. + + This function convert the socket physical index to logical index (0 base= d). + If the specified physical socket is not enabled, an invalid logical inde= x 0xff + will be returned. The socket physical index and logical index will be th= e same + if the indexes of enabled sockets are continuous. + + @param[in] SocketPhysicalId Socket physical index. + + @retval Socket logical index. +**/ +UINT8 +GetSocketLogicalId ( + IN UINT8 SocketPhysicalId + ); + +/** + Get the socket physical index. + + This function convert the socket logical index to physical index (0 base= d). + If the specified logical socket does not exist, an invalid physical inde= x 0xff + will be returned. The socket physical index and logical index will be th= e same + if the indexes of enabled sockets are continuous. + + @param[in] SocketLogicalId Socket logical index. + + @retval Socket physical index. +**/ +UINT8 +GetSocketPhysicalId ( + IN UINT8 SocketlogicId + ); + +/** + Verifies whether sockets are linked + + @param[in] SourceSocket Source Socket ID + @param[in] TargetSocket Targer Socket ID + + @retval TRUE link between source socket and target socket was found + FALSE otherwise + +**/ +BOOLEAN +SocketsLinked ( + IN UINT32 SourceSocket, + IN UINT32 TargetSocket + ); + +// +// AcpiPlatformTableLib private share +// +extern EFI_MP_SERVICES_PROTOCOL *mMpService; +extern BOOLEAN mCpuOrderSorted; +extern CPU_ID_ORDER_MAP mCpuApicIdOrderTable[]; +extern UINTN mNumberOfCPUs; +extern UINTN mNumberOfEnabledCPUs; +extern AML_OFFSET_TABLE_ENTRY *mAmlOffsetTablePointer; +extern CPU_CONFIG_CONTEXT_BUFFER *mCpuConfigLibConfigContextBuffer; + + +#endif diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLi= b/AcpiPlatformLibMcfg.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPl= atformTableLib/AcpiPlatformLibMcfg.c new file mode 100644 index 0000000000..dfe2425648 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiP= latformLibMcfg.c @@ -0,0 +1,134 @@ +/** @file + ACPI Platform Driver Hooks + + @copyright + Copyright 1996 - 2015 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// Statements that include other files +// +#include "AcpiPlatformLibLocal.h" + + +extern BIOS_ACPI_PARAM *mAcpiParameter; +extern EFI_IIO_UDS_PROTOCOL *mIioUds; +extern CPU_CSR_ACCESS_VAR *mCpuCsrAccessVarPtr; +extern SYSTEM_CONFIGURATION mSystemConfiguration; + +EFI_STATUS +PatchMcfgAcpiTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + UINT8 NodeId; + UINT8 NodeCount; + EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE *McfgTable; + + McfgTable =3D (EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE *= )Table; + + // + // mAcpiParameter memory buffer has been zero'ed out, so mAcpiParameter-= >PcieSegNum[] are 0's + // Patch \_SB.PSYS.SGEN with User Setup Option data + // + // + // dynamically allow multi-seg support + // + mAcpiParameter->PcieMultiSegSupport =3D 0; + for (NodeId =3D 0; NodeId < MAX_SOCKET; NodeId++) { + if ((UINT16) (mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[NodeId].Pcie= Segment) > 0) { + mAcpiParameter->PcieMultiSegSupport =3D 1; + break; + } + } + + // + // Update MCFG table entries (segment number, base addr and start/end bu= s numbers) + // + if (mAcpiParameter->PcieMultiSegSupport =3D=3D 0) { + + // + // Original code for single PCIe segment start + // + McfgTable->Segment[0].BaseAddress =3D mIioUds->IioUdsPtr->PlatformData= .PciExpressBase; + McfgTable->Segment[0].EndBusNumber =3D (UINT8)RShiftU64 (mIioUds->IioU= dsPtr->PlatformData.PciExpressSize, 20) - 1; + // + // Original code for single PCIe segment end + // + + // + // Single segment with segment number as 0 + // + McfgTable->Segment[0].PciSegmentGroupNumber =3D 0; + NodeCount =3D 1; + + } else { + // + // PCIe Multi-Segment handling - Assume each CPU socket as a segment, = and copy Segement info from IioUds HOB to MCFG table entries + // + + // + // Segment count =3D 0 + // + NodeCount =3D 0; + + for (NodeId =3D 0; NodeId < MAX_SOCKET; NodeId++) { + + // + // Skip a socket if it does not exist or does not contain valid bus = range data + // + if ( (UINT8)(mCpuCsrAccessVarPtr->SocketLastBus[NodeId]) =3D=3D + (UINT8)(mCpuCsrAccessVarPtr->SocketFirstBus[NodeId]) ) { + continue; + } + + // + // Copy PCIe Segement info from IioUds HOB to MCFG table entries + // + McfgTable->Segment[NodeCount].PciSegmentGroupNumber =3D (UINT16)(mIi= oUds->IioUdsPtr->PlatformData.CpuQpiInfo[NodeId].PcieSegment); + + McfgTable->Segment[NodeCount].BaseAddress =3D \ + LShiftU64 (mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[NodeId].Seg= MmcfgBase.hi, 32) + \ + (mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[NodeId].SegMmcfgBase.= lo); + + McfgTable->Segment[NodeCount].StartBusNumber =3D (UINT8)(mCpuCsrAcce= ssVarPtr->SocketFirstBus[NodeId]); + + McfgTable->Segment[NodeCount].EndBusNumber =3D (UINT8)(mCpuCsrAccess= VarPtr->SocketLastBus[NodeId]); + + // + // Update segment number returned by AML _SEG() . It resides in mA= cpiParameter region now. + // + mAcpiParameter->PcieSegNum[NodeId] =3D (UINT8)(mIioUds->IioUdsPtr->P= latformData.CpuQpiInfo[NodeId].PcieSegment); + + // + // Update count of valid segments + // + NodeCount++; + } + } + + // + // Set MCFG table "Length" field based on the number of PCIe segments en= umerated so far + // + McfgTable->Header.Header.Length =3D \ + sizeof (EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER= ) + \ + sizeof (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRE= SS_ALLOCATION_STRUCTURE) * NodeCount; + + // + // Debug dump of MCFG table + // + DEBUG ((DEBUG_ERROR, "ACPI MCFG table @ address 0x%x\n", Table )); + DEBUG ((DEBUG_ERROR, " Multi-Seg Support =3D %x\n", mAcpiParameter->Pci= eMultiSegSupport)); + DEBUG ((DEBUG_ERROR, " Number of Segments (sockets): %2d\n", NodeCount = )); + DEBUG ((DEBUG_ERROR, " Table Length =3D 0x%x\n\n", McfgTable->Header.He= ader.Length )); + for (NodeId =3D 0; NodeId < NodeCount; NodeId ++) { + DEBUG ((DEBUG_ERROR, " Segment[%2d].BaseAddress =3D %x\n", NodeId, = McfgTable->Segment[NodeId].BaseAddress)); + DEBUG ((DEBUG_ERROR, " Segment[%2d].PciSegmentGroupNumber =3D %x\n",= NodeId, McfgTable->Segment[NodeId].PciSegmentGroupNumber)); + DEBUG ((DEBUG_ERROR, " Segment[%2d].StartBusNumber =3D %x\n", NodeId= , McfgTable->Segment[NodeId].StartBusNumber)); + DEBUG ((DEBUG_ERROR, " Segment[%2d].EndBusNumber =3D %x\n\n", NodeId= , McfgTable->Segment[NodeId].EndBusNumber)); + } + + return EFI_SUCCESS; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLi= b/AcpiPlatformLibMigt.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPl= atformTableLib/AcpiPlatformLibMigt.c new file mode 100644 index 0000000000..603fe57cec --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiP= latformLibMigt.c @@ -0,0 +1,69 @@ +/** @file + ACPI Platform Driver Hooks + + @copyright + Copyright 1996 - 2018 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// Statements that include other files +// +#include "AcpiPlatformLibLocal.h" + +extern BIOS_ACPI_PARAM *mAcpiParameter; + +/** + Update the MIGT ACPI table + + @param *TableHeader - The table to be set + + @retval EFI_SUCCESS - Returns Success +**/ +EFI_STATUS +PatchMigtAcpiTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + EFI_STATUS Status; + UINT64 Address; + UINTN idx; + UINT8 checksum; + EFI_MIGT_ACPI_DESCRIPTION_TABLE *MigtAcpiTable; + + MigtAcpiTable =3D (EFI_MIGT_ACPI_DESCRIPTION_TABLE *)Table; + Address =3D 0xffffffff; + + Status =3D gBS->AllocatePages ( + AllocateMaxAddress, + EfiACPIMemoryNVS, + 1, //page + &Address + ); + + if (EFI_ERROR (Status)) { + return Status; + } + // + // update MIGT ACPI table + // + MigtAcpiTable->ActionRegion.Address =3D Address; + + // + // update checksum + // + MigtAcpiTable->Header.Checksum =3D 0; + checksum =3D 0; + for(idx =3D 0; idx < sizeof(EFI_MIGT_ACPI_DESCRIPTION_TABLE); idx++) { + checksum =3D checksum + (UINT8) (((UINT8 *)(MigtAcpiTable))[idx]); + } + MigtAcpiTable->Header.Checksum =3D (UINT8) (0 - checksum); + + // + // Update Migration Action Region GAS address + // + mAcpiParameter->MigrationActionRegionAddress =3D Address; + + return Status; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLi= b/AcpiPlatformLibMsct.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPl= atformTableLib/AcpiPlatformLibMsct.c new file mode 100644 index 0000000000..1755325d61 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiP= latformLibMsct.c @@ -0,0 +1,101 @@ +/** @file + ACPI Platform Driver Hooks + + @copyright + Copyright 1996 - 2020 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// Statements that include other files +// +#include "AcpiPlatformLibLocal.h" + +/** + Update the MSCT ACPI table + + @param *MsctAcpiTable - The table to be set + + @retval EFI_SUCCESS - Returns Success +**/ +EFI_STATUS +PatchMsctAcpiTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + UINTN idx; + UINT8 checksum; + UINT32 MaxPhysicalAddressBit; + EFI_CPUID_REGISTER CpuidLeafInfo; + EFI_ACPI_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE *MsctAcpiTable =3D NULL; + UINT32 MaxThreadCapacity; + UINT32 MaxSocketCount; + EFI_STATUS Status =3D EFI_SUCCESS; + DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &= DynamicSiLibraryProtocol2); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + MsctAcpiTable =3D (EFI_ACPI_MAXIMUM_SYSTEM_CHARACTERISTICS_TABLE *)Table; + + // + // If SNC is enabled set the Maximum number of Proximity domains accordi= ngly + // + MaxSocketCount =3D FixedPcdGet32 (PcdMaxCpuSocketCount); + + if (DynamicSiLibraryProtocol2->GetNumOfClusterPerSystem () !=3D 0) { + MsctAcpiTable->MaxNumProxDom =3D MaxSocketCount * DynamicSiLibraryProt= ocol2->GetNumOfClusterPerSystem () - 1; + } + + // + // Update Maximum Physical Address + // Get the number of address lines; Maximum Physical Address is 2^MaxPhy= sicalAddressBit - 1. + // If CPUID does not support reporting the max physical address, then us= e a max value of 36 as per SDM 3A, 4.1.4. + // + AsmCpuid (CPUID_EXTENDED_FUNCTION, &CpuidLeafInfo.RegEax, NULL, NULL, NU= LL); + MaxPhysicalAddressBit =3D 36; + if (CpuidLeafInfo.RegEax >=3D (UINT32) CPUID_VIR_PHY_ADDRESS_SIZE) { + AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &CpuidLeafInfo.RegEax, NULL, NUL= L, NULL); + MaxPhysicalAddressBit =3D (UINT8) CpuidLeafInfo.RegEax; + } + + MsctAcpiTable->MaxPhysicalAddress =3D (LShiftU64 (0x01, MaxPhysicalAddre= ssBit) - 1); + + MaxPhysicalAddressBit =3D DynamicSiLibraryProtocol2->GetMaxPhysicalAddrB= its (); + + MsctAcpiTable->MaxPhysicalAddress =3D (LShiftU64 (0x01, MaxPhysicalAddre= ssBit) - 1); + + // + // First Proximity Domain Information Structure reports characteristics = for all proximity domains, + // since the characteristics are the same for all proximity domains. + // + MsctAcpiTable->ProxDomInfoStructure[0].ProxDomRangeLow =3D 0; + MsctAcpiTable->ProxDomInfoStructure[0].ProxDomRangeHigh =3D MsctAcpiTabl= e->MaxNumProxDom; + + // + // Max Number of Threads that the processor can have MaxThreadCapacity + // + AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, 1, NULL, &MaxThreadCapacity, NULL, = NULL); + MsctAcpiTable->ProxDomInfoStructure[0].MaxProcessorCapacity =3D MaxThrea= dCapacity; + + // + // Max Memory capacity per proximity domain + // + MsctAcpiTable->ProxDomInfoStructure[0].MaxMemoryCapacity =3D MsctAcpiTab= le->MaxPhysicalAddress; + + // + // Update Checksum + // + MsctAcpiTable->Header.Checksum =3D 0; + checksum =3D 0; + for(idx =3D 0; idx < sizeof(EFI_ACPI_MAXIMUM_SYSTEM_CHARACTERISTICS_TABL= E); idx++) { + checksum =3D checksum + (UINT8) (((UINT8 *)(MsctAcpiTable))[idx]); + } + MsctAcpiTable->Header.Checksum =3D (UINT8) (0 - checksum); + + return EFI_SUCCESS; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLi= b/AcpiPlatformLibNfit.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPl= atformTableLib/AcpiPlatformLibNfit.c new file mode 100644 index 0000000000..cc65d575c3 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiP= latformLibNfit.c @@ -0,0 +1,45 @@ +/** @file + ACPI Platform Driver Hooks + + @copyright + Copyright 1996 - 2019 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// Statements that include other files +// +#include "AcpiPlatformLibLocal.h" + +/** + This function locates the CrystalRidge protocol and JedecNvdimm protocol + and calls the update ACPI tables functions defined there to update/build + the NVDIMM F/W Interface Table (NFIT). It builds the NFIT table which ge= ts + published in ACPI XSDT. + + @param[in,out] Table Pointer to NFIT which will be build in + CR Protocol and will be publised in ACPI XSDT. + + @retval EFI_SUCCESS Table successfully updated. + @retval EFI_UNSUPPORTED Table not updated. +**/ +EFI_STATUS +UpdateNfitTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + EFI_NFIT_TABLE_UPDATE_PROTOCOL *NfitTableUpdateProtocol =3D NULL; + EFI_STATUS Status; + + Status =3D gBS->LocateProtocol (&gEfiNfitTableUpdateProtocolGuid, NULL, = &NfitTableUpdateProtocol); + + if (!EFI_ERROR (Status)) { + Status =3D NfitTableUpdateProtocol->UpdateAcpiTable ((UINT64*) Table); + } else { + DEBUG ((DEBUG_ERROR, "Cannot find NfitTableUpdateProtocol\n")); + } + DEBUG ((DEBUG_INFO, "NFIT Update Status: 0x%x\n", Status)); + + return Status; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLi= b/AcpiPlatformLibPcat.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPl= atformTableLib/AcpiPlatformLibPcat.c new file mode 100644 index 0000000000..515e8ffd1d --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiP= latformLibPcat.c @@ -0,0 +1,42 @@ +/** @file + ACPI Platform Driver Hooks + + @copyright + Copyright 1996 - 2016 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// Statements that include other files +// +#include "AcpiPlatformLibLocal.h" + +/** + This function locates the CrystalRidge Protocol and calls + into one of its interface function (UpdateAcpiPcatTable) to + update/build the PCAT (Platform Capability Attribute Table). + And this table gets published in ACPI XSDT. + + @param *Table - Pointer to PCAT table which will be + build in CR Protocol and will be publised in ACPI + XSDT. + @retval Status - Return Status +**/ +EFI_STATUS +UpdatePcatTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + EFI_STATUS Status; + DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &= DynamicSiLibraryProtocol2); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D DynamicSiLibraryProtocol2->UpdatePcatTable (Table); + return EFI_SUCCESS; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLi= b/AcpiPlatformLibPmtt.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPl= atformTableLib/AcpiPlatformLibPmtt.c new file mode 100644 index 0000000000..dd9807c899 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiP= latformLibPmtt.c @@ -0,0 +1,267 @@ +/** @file + ACPI Platform Driver Hooks + + @copyright + Copyright 2016 - 2020 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "AcpiPlatformLibLocal.h" +#include + +extern struct SystemMemoryMapHob *mSystemMemoryMap; + +/*************************************************************************= ***** + * Definitions. + *************************************************************************= *****/ +//#define PMTTDEBUG_ENABLED 1 +#if PMTTDEBUG_ENABLED +#define PMTTDEBUG(Expr) _DEBUG(Expr) +#else +#define PMTTDEBUG(Expr) +#endif +#ifndef NELEMENTS +#define NELEMENTS(Array) (sizeof(Array)/sizeof((Array)[0])) +#endif + + +// +// PMTT GUID variables +// +const EFI_GUID gEfiPmttTypeDieGuid =3D PMTT_TYPE_DIE_GUID; +const EFI_GUID gEfiPmttTypeChannelGuid =3D PMTT_TYPE_CHANNEL_GUID; +const EFI_GUID gEfiPmttTypeSlotGuid =3D PMTT_TYPE_SLOT_GUID; + +/*************************************************************************= ***** + * Functions. + *************************************************************************= *****/ + +EFI_STATUS +PatchPlatformMemoryTopologyTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + UINT8 Socket; + UINT8 Die; + UINT8 Imc; + UINT8 Channel; + UINT8 ChannelIndex; + UINT8 Dimm; + SMBIOS_DIMM_INFO DimmInfo; + SMBIOS_MEM_INFO_PROTOCOL *SmbiosInfoProtocol; + EFI_STATUS Status; + ACPI_PLATFORM_MEMORY_TOPOLOGY_TABLE *PmttTable =3D (ACPI_PLATFORM_MEMOR= Y_TOPOLOGY_TABLE*)Table; + UINT8 MaxImc; + UINT8 MaxChPerImc; + UINT8 DieCnt; + + DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &= DynamicSiLibraryProtocol2); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + MaxImc =3D DynamicSiLibraryProtocol2->GetMaxImc (); + MaxChPerImc =3D DynamicSiLibraryProtocol2->GetNumChannelPerMc (); + + ASSERT (PmttTable->Header.Signature =3D=3D ACPI_PMTT_TABLE_SIGNATURE); + + Status =3D gBS->LocateProtocol (&gSmbiosMemInfoProtocolGuid, NULL, (VOID= **)&SmbiosInfoProtocol); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "[ACPI] (PMTT) Cannot locate SmbiosMemInfoProtoco= l! (%r)\n", Status)); + ASSERT_EFI_ERROR (Status); + SmbiosInfoProtocol =3D NULL; + } + + for (Socket =3D 0; Socket < MAX_SOCKET; Socket++) { + + PmttTable->Socket[Socket].Type =3D ACPI_TOP_LEVEL_SOCKET; + PmttTable->Socket[Socket].SckIdent =3D Socket; + PmttTable->Socket[Socket].Length =3D sizeof(PmttTable->Socket[Socke= t]) - sizeof(ACPI_PMTT_DIE_DEVICE); + PmttTable->Socket[Socket].Flag =3D 0; + PmttTable->Socket[Socket].NumOfMemoryDevices =3D 0; + + if (mSystemMemoryMap->Socket[Socket].SocketEnabled) { + PmttTable->Socket[Socket].Flag |=3D (PMTT_TOP_LEVEL_AGGREGATOR_DEVIC= E | PMTT_PHYSICAL_ELEMENT_OF_TOPOLOGY); + PmttTable->NumOfMemoryDevices++; + } else { + continue; + } + + DieCnt =3D DynamicSiLibraryProtocol2->GetAcpiDieCount (Socket); + for (Die =3D 0; Die < DieCnt; Die++) { + + PmttTable->Socket[Socket].Die[Die].Type =3D ACPI_TOP_LEVEL_VENDOR_SP= ECIFIC_DEVICE; + PmttTable->Socket[Socket].Die[Die].Length =3D sizeof(PmttTable->Sock= et[Socket].Die[Die]) - MAX_IMC * sizeof(ACPI_PMTT_IMC_DEVICE); + PmttTable->Socket[Socket].Die[Die].Flag =3D 0; + PmttTable->Socket[Socket].Die[Die].Flag |=3D PMTT_PHYSICAL_ELEMENT_O= F_TOPOLOGY; + PmttTable->Socket[Socket].Die[Die].NumOfMemoryDevices =3D 0; + PmttTable->Socket[Socket].Die[Die].DieId =3D Die; + CopyGuid (&PmttTable->Socket[Socket].Die[Die].TypeUuid, &gEfiPmttTyp= eDieGuid); + + PmttTable->Socket[Socket].NumOfMemoryDevices++; + + for (Imc =3D 0; Imc < MaxImc; Imc++) { + + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Type =3D ACPI_TOP_LEVE= L_IMC; + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Length =3D sizeof(Pmtt= Table->Socket[Socket].Die[Die].Imc[Imc]) - MAX_MC_CH * sizeof(ACPI_PMTT_CHA= NNEL_DEVICE); + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Flag =3D 0; + PmttTable->Socket[Socket].Die[Die].Imc[Imc].NumOfMemoryDevices =3D= 0; + PmttTable->Socket[Socket].Die[Die].Imc[Imc].ImcId =3D Imc; + + if (mSystemMemoryMap->Socket[Socket].imcEnabled[Imc]) { + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Flag |=3D PMTT_PHYSI= CAL_ELEMENT_OF_TOPOLOGY; + PmttTable->Socket[Socket].Die[Die].NumOfMemoryDevices++; + } else { + continue; + } + + for (Channel =3D 0; Channel < MaxChPerImc; Channel++) { + + ChannelIndex =3D MEM_IMCCH_TO_SKTCH(Imc, Channel); + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Typ= e =3D ACPI_TOP_LEVEL_VENDOR_SPECIFIC_DEVICE; + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Len= gth =3D sizeof(PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel]= ) - MAX_DIMM * sizeof(ACPI_PMTT_SLOT_DEVICE); + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Fla= g =3D 0; + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Num= OfMemoryDevices =3D 0; + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Cha= nnelId =3D Channel; + CopyGuid (&(PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[= Channel].TypeUuid), &gEfiPmttTypeChannelGuid); + + if (mSystemMemoryMap->Socket[Socket].ChannelInfo[ChannelIndex].E= nabled) { + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].F= lag |=3D PMTT_PHYSICAL_ELEMENT_OF_TOPOLOGY; + PmttTable->Socket[Socket].Die[Die].Imc[Imc].NumOfMemoryDevices= ++; + } else { + continue; + } + + for (Dimm =3D 0; Dimm < MAX_DIMM; Dimm++) { + // + // Looping through the each DIMM on the IMC. + // + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].S= lot[Dimm].Type =3D ACPI_TOP_LEVEL_VENDOR_SPECIFIC_DEVICE; + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].S= lot[Dimm].Length =3D sizeof(PmttTable->Socket[Socket].Die[Die].Imc[Imc].Cha= nnel[Channel].Slot[Dimm]) - sizeof(ACPI_PMTT_DIMM_DEVICE); + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].S= lot[Dimm].Flag |=3D PMTT_PHYSICAL_ELEMENT_OF_TOPOLOGY; + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].S= lot[Dimm].NumOfMemoryDevices =3D 0; + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].S= lot[Dimm].SlotId =3D Dimm; + CopyGuid (&PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel= [Channel].Slot[Dimm].TypeUuid, &gEfiPmttTypeSlotGuid); + + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].S= lot[Dimm].Dimm.Type =3D PHYSICAL_COMPONENT_IDENTIFIER_TYPE_DIMM; + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].S= lot[Dimm].Dimm.Length =3D sizeof(PmttTable->Socket[Socket].Die[Die].Imc[Imc= ].Channel[Channel].Slot[Dimm].Dimm); + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].S= lot[Dimm].Dimm.NumOfMemoryDevices =3D 0; + + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].S= lot[Dimm].Dimm.Flag =3D 0; + + if (!mSystemMemoryMap->Socket[Socket].ChannelInfo[ChannelIndex= ].DimmInfo[Dimm].Present) { + continue; + } + + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].S= lot[Dimm].Dimm.Flag |=3D PMTT_PHYSICAL_ELEMENT_OF_TOPOLOGY; + + if (mSystemMemoryMap->Socket[Socket].ChannelInfo[ChannelIndex]= .DimmInfo[Dimm].DcpmmPresent) { + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel]= .Slot[Dimm].Dimm.Flag |=3D PMTT_AEP_DIMM; + } + // + // Get SMBIOS handle for the DIMM. If handle not found use FFF= FFFFFh. + // + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].S= lot[Dimm].Dimm.SmbiosHandle =3D (UINT32)-1; + if (SmbiosInfoProtocol !=3D NULL) { + + DimmInfo.Socket =3D Socket; + DimmInfo.Imc =3D Imc; + DimmInfo.Channel =3D Channel; + DimmInfo.Dimm =3D Dimm; + Status =3D SmbiosInfoProtocol->SmbiosGetDimmByLocation (Smbi= osInfoProtocol, &DimmInfo); + if (!EFI_ERROR (Status)) { + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channe= l].Slot[Dimm].Dimm.SmbiosHandle =3D DimmInfo.Type17Handle; + } + } + + if (!mSystemMemoryMap->Socket[Socket].ChannelInfo[ChannelIndex= ].DimmInfo[Dimm].Enabled) { + continue; + } + + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].S= lot[Dimm].NumOfMemoryDevices++; + PmttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].N= umOfMemoryDevices++; + } // for (Dimm...) + } // for (Channel...) + } // for (Imc...) + } // for (Die...) + } // for (Skt...) + // + // Dump the strucutre for debug purpose + // + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) Signature: 0x%08X\n", PmttT= able->Header.Signature)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) Length: %d\n", PmttTable= ->Header.Length)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) Revision: %d\n", PmttTable= ->Header.Revision)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) Checksum: %d\n", PmttTabl= e->Header.Checksum)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) OemId: '%c%c%c%c%c%c'\n= ", + PmttTable->Header.OemId[0], PmttTable->Header.OemId[1], Pmtt= Table->Header.OemId[2], + PmttTable->Header.OemId[3], PmttTable->Header.OemId[4], Pmtt= Table->Header.OemId[5])); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) OemTableId: 0x%08X\n", PmttT= able->Header.OemTableId)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) OemRevision: %d\n", PmttTable= ->Header.OemRevision)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) CreatorId: 0x%08X\n", PmttT= able->Header.CreatorId)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) CreatorRevision: %d\n", PmttTable= ->Header.OemRevision)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) NumOfMemoryDevices: %d\n", PmttTa= ble->NumOfMemoryDevices)); + + PMTTDEBUG ((DEBUG_INFO, "\n")); + for (Socket =3D 0; Socket < NELEMENTS (PmttTable->Socket); Socket++) { + + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d] Type: 0x%02X\n", So= cket, PmttTable->Socket[Socket].Type)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d] Length: %d\n", Socket= , PmttTable->Socket[Socket].Length)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d] Flags: 0x%04X\n", So= cket, PmttTable->Socket[Socket].Flag)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d] SocketId: %d\n", Socket= , PmttTable->Socket[Socket].SckIdent)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d] NumOfMemoryDevices: %d\= n", Socket, PmttTable->Socket[Socket].NumOfMemoryDevices)); + + PMTTDEBUG ((DEBUG_INFO, "\n")); + for (Die =3D 0; Die < NELEMENTS(PmttTable->Socket[Socket].Die); Die++)= { + + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d] Type: 0x%02X\= n", Socket, Die, PmttTable->Socket[Socket].Die[Die].Type)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d] Length: %d\n", = Socket, Die, PmttTable->Socket[Socket].Die[Die].Length)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d] Flags: 0x%04X\= n", Socket, Die, PmttTable->Socket[Socket].Die[Die].Flag)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d] DieId: %d\n", = Socket, Die, PmttTable->Socket[Socket].Die[Die].DieId)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d] TypeUuid: %g\n", = Socket, Die, PmttTable->Socket[Socket].Die[Die].TypeUuid)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d] NumOfMemoryDevices: = %d\n", Socket, Die, PmttTable->Socket[Socket].Die[Die].NumOfMemoryDev= ices)); + + PMTTDEBUG ((DEBUG_INFO, "\n")); + for (Imc =3D 0; Imc < NELEMENTS(PmttTable->Socket[Socket].Die[Die].I= mc); Imc++) { + + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d] Type: = 0x%02X\n", Socket, Die, Imc, PmttTable->Socket[Socket].Die[Die].I= mc[Imc].Type)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d] Length: = %d\n", Socket, Die, Imc, PmttTable->Socket[Socket].Die[Die].Imc[I= mc].Length)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d] Flags: = 0x%04X\n", Socket, Die, Imc, PmttTable->Socket[Socket].Die[Die].I= mc[Imc].Flag)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d] ImcId: = %d\n", Socket, Die, Imc, PmttTable->Socket[Socket].Die[Die].Imc[I= mc].ImcId)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d] NumOfMemoryDev= ices: %d\n", Socket, Die, Imc, PmttTable->Socket[Socket].Die[Die].Imc[I= mc].NumOfMemoryDevices)); + + PMTTDEBUG ((DEBUG_INFO, "\n")); + for (Channel =3D 0; Channel < NELEMENTS(PmttTable->Socket[Socket].= Die[Die].Imc[Imc].Channel); Channel++) { + + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d] Type: = 0x%02X\n", Socket, Die, Imc, Channel, PmttTable->Socket[Soc= ket].Die[Die].Imc[Imc].Channel[Channel].Type)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d] Length: = %d\n", Socket, Die, Imc, Channel, PmttTable->Socket[Socket]= .Die[Die].Imc[Imc].Channel[Channel].Length)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d] Flags: = 0x%04X\n", Socket, Die, Imc, Channel, PmttTable->Socket[Soc= ket].Die[Die].Imc[Imc].Channel[Channel].Flag)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d] ChannelI= d: %d\n", Socket, Die, Imc, Channel, PmttTable->Socket[Socket]= .Die[Die].Imc[Imc].Channel[Channel].ChannelId)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d] TypeUuid= : %g\n", Socket, Die, Imc, Channel, PmttTable->Socket[Socket]= .Die[Die].Imc[Imc].Channel[Channel].TypeUuid)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d] NumOfMem= oryDevices: %d\n", Socket, Die, Imc, Channel, PmttTable->Socket[Socket]= .Die[Die].Imc[Imc].Channel[Channel].NumOfMemoryDevices)); + + PMTTDEBUG ((DEBUG_INFO, "\n")); + for (Dimm =3D 0; Dimm < NELEMENTS(PmttTable->Socket[Socket].Die[= Die].Imc[Imc].Channel[Channel].Slot); Dimm++) { + + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d][%d] Ty= pe: 0x%02X\n", Socket, Die, Imc, Channel, Dimm, PmttTable= ->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Type)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d][%d] Le= ngth: %d\n", Socket, Die, Imc, Channel, Dimm, PmttTable->So= cket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Length)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d][%d] Fl= ags: 0x%04X\n", Socket, Die, Imc, Channel, Dimm, PmttTable= ->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Flag)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d][%d] Sl= otId: %d\n", Socket, Die, Imc, Channel, Dimm, PmttTable->So= cket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].SlotId)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d][%d] Ty= peUuid: %g\n", Socket, Die, Imc, Channel, Dimm, PmttTable->So= cket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].TypeUuid)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d][%d] Nu= mOfMemoryDevices: %d\n", Socket, Die, Imc, Channel, Dimm, PmttTable->So= cket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].NumOfMemoryDevic= es)); + + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d][%d][%d= ] Type: 0x%02X\n", Socket, Die, Imc, Channel, Dimm, Dimm, Pm= ttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Dimm.= Type)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d][%d][%d= ] Length: %d\n", Socket, Die, Imc, Channel, Dimm, Dimm, PmttTa= ble->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Dimm.Leng= th)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d][%d][%d= ] Flags: 0x%04X\n", Socket, Die, Imc, Channel, Dimm, Dimm, Pm= ttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Dimm.= Flag)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d][%d][%d= ] SmbiosHandle: 0x%08X\n", Socket, Die, Imc, Channel, Dimm, Dimm, Pm= ttTable->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Dimm.= SmbiosHandle)); + PMTTDEBUG ((DEBUG_INFO, "[ACPI] (PMTT) [%d][%d][%d][%d][%d][%d= ] NumOfMemoryDevices: %d\n", Socket, Die, Imc, Channel, Dimm, Dimm, PmttTa= ble->Socket[Socket].Die[Die].Imc[Imc].Channel[Channel].Slot[Dimm].Dimm.NumO= fMemoryDevices)); + } // for (Dimm...) + } // for (Channel...) + } // for (Imc...) + } // for (Die...) + } // for (Skt...) + return EFI_SUCCESS; +} // PatchPlatformMemoryTopologyTable () diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLi= b/AcpiPlatformLibSlit.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPl= atformTableLib/AcpiPlatformLibSlit.c new file mode 100644 index 0000000000..a8ac046aea --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiP= latformLibSlit.c @@ -0,0 +1,1153 @@ +/** @file + ACPI Platform Driver Hooks + + @copyright + Copyright 1996 - 2020 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// Statements that include other files +// +#include "AcpiPlatformLibLocal.h" + +extern SYSTEM_MEMORY_MAP_HOB *mSystemMemoryMap; +extern EFI_IIO_UDS_PROTOCOL *mIioUds; +extern EFI_ACPI_TABLE_PROTOCOL *mAcpiTable; +extern CPU_CSR_ACCESS_VAR *mCpuCsrAccessVarPtr; + +EFI_ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE_PMEM_INFO mSlitPmemInfo[EFI_ACP= I_SLIT_PMEM_INFO_CNT]; + + +/** + Displays System Locality Distance Information Table (SLIT) + + @param None + + @retval None +**/ +VOID +DisplayEntries ( + IN ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *SlitPtr + ) +{ + UINT16 EntryIdx =3D 0; + UINT16 MaxTableEntries; + UINT8 NodeCount; + + if (SlitPtr =3D=3D NULL) { + + ASSERT (SlitPtr !=3D NULL); + return; + } + NodeCount =3D (UINT8)SlitPtr->Header.NumberOfSystemLocalities; + MaxTableEntries =3D NodeCount * NodeCount; + + DEBUG ((DEBUG_INFO, "SLIT: Dump table (size %d):\n", NodeCount)); + + while (EntryIdx < MaxTableEntries) { + + DEBUG ((DEBUG_INFO, "%02X ", SlitPtr->NumSlit[EntryIdx].Entry)); + if ((EntryIdx % NodeCount) =3D=3D (NodeCount - 1)) { + DEBUG ((DEBUG_INFO, "\n")); + } + EntryIdx++; + } +} + + +/** + Stores correlation between AEP PMEM NUMA node and socket + + @param[in] Pmem AEP PMEM NUMA node number + @param[in] Socket Socket number + + @retval None + +**/ +VOID +SavePmemInfo ( + IN UINT8 Pmem, + IN UINT8 Socket, + MEM_TYPE Type + ) +{ + if (Pmem < EFI_ACPI_SLIT_PMEM_INFO_CNT) { + + DEBUG ((DEBUG_INFO, "SLIT: Found PMem %d at socket %d (mem type 0x%X)\= n", Pmem, Socket, Type)); + mSlitPmemInfo[Pmem].Pmem =3D Pmem; + mSlitPmemInfo[Pmem].Socket =3D Socket; + mSlitPmemInfo[Pmem].Valid =3D TRUE; + return; + } + + DEBUG ((DEBUG_ERROR, "SLIT: Error - Number of PMem nodes (%d) exceed PMe= m info data table size (%d)\n", + Pmem, EFI_ACPI_SLIT_PMEM_INFO_CNT)); + ASSERT (FALSE); +} + +/** + Retrieves socket correlated with given AEP PMEM NUMA node + + @param[in] Pmem AEP PMEM Numa node + + @retval Socket correlated with given AEP PMEM NUMA node + +**/ +UINT8 +GetSocketForPmem ( + IN UINT8 Pmem + ) +{ + UINT8 PmemInfoEntry; + + for (PmemInfoEntry =3D 0; PmemInfoEntry < EFI_ACPI_SLIT_PMEM_INFO_CNT; P= memInfoEntry++) { + if (mSlitPmemInfo[PmemInfoEntry].Valid && mSlitPmemInfo[PmemInfoEntry]= .Pmem =3D=3D Pmem) { + return mSlitPmemInfo[PmemInfoEntry].Socket; + } + } + + DEBUG ((DEBUG_ERROR, "SLIT: Error - PMem node (%d) is not associated wit= h any socket\n", Pmem)); + ASSERT (FALSE); + return PMEM_INVALID_SOCKET; +} + +/** + This function gets the physical node index for given FPGA NUMA node. + If the given FPGA NUMA node doesn't exist, an invalid physical node + index 0xff will be returned. + + @param[in] FpgaNumaNodeId FPGA NUMA node index (0 based). + + @retval Physical node index of given FPGA NUMA node (0 based). + +**/ +UINT8 +GetPhyNodeIdForFpga ( + IN UINT8 FpgaNumaNodeId + ) +{ + UINT32 FpgaPresentBitMap; + UINT8 PhyNodeId; + + PhyNodeId =3D 0; + FpgaPresentBitMap =3D mCpuCsrAccessVarPtr->FpgaPresentBitMap; + + while ((FpgaNumaNodeId !=3D (UINT8) -1) && (FpgaPresentBitMap !=3D 0)) { + if ((FpgaPresentBitMap & BIT0) !=3D 0) { + FpgaNumaNodeId--; + } + FpgaPresentBitMap >>=3D 1; + PhyNodeId++; + } + + if ((FpgaPresentBitMap =3D=3D 0) && (FpgaNumaNodeId !=3D (UINT8) -1)) { + return (UINT8) -1; + } + + return PhyNodeId - 1; +} + +/** + Retrieves number of FPGA Presents + + @retval Number of FPGA Presents in the system + +**/ +UINT8 +GetFpgaCount ( + VOID) +{ + UINT8 FpgaCount =3D 0; + UINT32 FpgaPresentBitMap =3D mCpuCsrAccessVarPtr->FpgaPresentBitMap; + + while (FpgaPresentBitMap) { + if (FpgaPresentBitMap & BIT0) { + FpgaCount++; + } + FpgaPresentBitMap >>=3D 1; + } + return FpgaCount; +} + +/** + Retrieves number of AEP PMEM NUMA nodes + + @retval Number of AEP PMEM NUMA nodes + +**/ +UINT8 +GetPmemNodeCount ( + VOID + ) +{ + UINT8 Socket; + UINT8 SadRule; + UINT8 PmemNodeCount =3D 0; + + EFI_STATUS Status =3D EFI_SUCCESS; + DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &= DynamicSiLibraryProtocol2); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return 0; + } + + for (Socket =3D 0; Socket < MAX_SOCKET; Socket++) { + if ((mCpuCsrAccessVarPtr->socketPresentBitMap & (BIT0 << Socket)) =3D= =3D 0) { + continue; + } + for (SadRule =3D 0; SadRule < MAX_SAD_RULES; SadRule++) { + // + // Only local SADs of PMEM type should be taken into consideration. + // Skip any memory region marked reserved. + // + if (mSystemMemoryMap->Socket[Socket].SAD[SadRule].local && + DynamicSiLibraryProtocol2->IsMemTypeAppDirect (mSystemMemoryMap-= >Socket[Socket].SAD[SadRule].type) && + !DynamicSiLibraryProtocol2->IsMemTypeReserved (mSystemMemoryMap-= >Socket[Socket].SAD[SadRule].type)) { + + SavePmemInfo (PmemNodeCount++, Socket, mSystemMemoryMap->Socket[So= cket].SAD[SadRule].type); + } + } + } + + return PmemNodeCount; +} + +/** + Retrieves number of clusters in the system if system is in SNC mode. If = system is not + in SNC mode, the return 1. + + @return Number of clusters in the system in SNC mode or 1 if system is n= ot in SNC mode. + +**/ +UINT8 +GetNumClusters ( + VOID + ) +{ + UINT8 NumClusters; + + NumClusters =3D mIioUds->IioUdsPtr->SystemStatus.OutNumOfCluster; + if ((NumClusters =3D=3D 0) || (mIioUds->IioUdsPtr->SystemStatus.OutSncEn= =3D=3D 0)) { + NumClusters =3D 1; // For non-SNC mode, we should also return 1. + } + if (mSystemMemoryMap->VirtualNumaEnable) { + NumClusters =3D NumClusters * mSystemMemoryMap->VirtualNumOfCluster; + } + + return NumClusters; +} + +/** + Retrieves number of enabled CPUs in the system + + @param None + + @retval Number of enabled CPUs in the system + +**/ +UINT8 +GetNumCpus ( + VOID + ) +{ + return mIioUds->IioUdsPtr->SystemStatus.numCpus; +} + +/** + Calculates total number of nodes + + @param[in] NumCpus Number of CPUs + @param[in] NumClusters Number of clusters + @param[in] PmemNodeCount Number of AEP PMEM NUMA nodes + + @retval Total number of nodes + +**/ +UINT8 +GetNodeCount ( + IN UINT8 NumCpus, + IN UINT8 NumClusters, + IN UINT8 PmemNodeCount, + IN UINT8 FpgaCount + ) +{ + UINT8 NodeCount; + + if (mSystemMemoryMap->volMemMode =3D=3D VOL_MEM_MODE_MIX_1LM2LM) { + NodeCount =3D ((NumCpus * NumClusters * EFI_ACPI_SLIT_DOMAINS_NODES_MA= X_CNT) + PmemNodeCount + FpgaCount); + } else { + NodeCount =3D ((NumCpus * NumClusters) + PmemNodeCount + FpgaCount); + } + if ((NodeCount * NodeCount) < EFI_ACPI_SYSTEM_LOCALITIES_ENTRY_COUNT) { + return NodeCount; + } + + DEBUG ((DEBUG_ERROR, "SLIT: Error - Nodes distances info data size (%d) = exceed SLIT distances info table size (%d)\n", + (NodeCount * NodeCount), EFI_ACPI_SYSTEM_LOCALITIES_ENTRY_COUNT)); + ASSERT (FALSE); + return 0; +} + +/** + Verifies whether sockets are linked + + @param[in] SourceSocket Source Socket ID + @param[in] TargetSocket Targer Socket ID + + @retval TRUE link between source socket and target socket was found + FALSE otherwise + +**/ +BOOLEAN +SocketsLinked ( + IN UINT32 SourceSocket, + IN UINT32 TargetSocket + ) +{ + UINT8 PeerSocket; + UINT8 LinkValid; + UINT8 PeerSocId; + + EFI_STATUS Status =3D EFI_SUCCESS; + DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &= DynamicSiLibraryProtocol2); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return FALSE; + } + + // + // Validate sockets ids + // + if ((SourceSocket < MAX_SOCKET) && (TargetSocket < MAX_SOCKET)) { + // + // Do not process when source socket is the same as target socket + // + if (SourceSocket !=3D TargetSocket) { + for (PeerSocket =3D 0; PeerSocket < (DynamicSiLibraryProtocol2->GetK= tiPortCnt()); PeerSocket++) { + LinkValid =3D mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[SourceSo= cket].PeerInfo[PeerSocket].Valid; + PeerSocId =3D mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[SourceSo= cket].PeerInfo[PeerSocket].PeerSocId; + if (LinkValid && (PeerSocId =3D=3D TargetSocket)) { + // + // Link found + // + return TRUE; + } + } + } + // + // Link not found + // + return FALSE; + } + + DEBUG ((DEBUG_ERROR, "SLIT: Error when checking if sockets are linked (s= ource socket id %d, target socket id %d)\n", SourceSocket, TargetSocket)); + return FALSE; +} + +/** + Initializes SLIT Table entries + + @param[in,out] Table Pointer to SLIT ACPI tables + + @retval EFI_SUCCESS operation completed successfully + +**/ +EFI_STATUS +InitEntries ( + IN OUT ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *SlitPtr + ) +{ + if (SlitPtr =3D=3D NULL) { + ASSERT (SlitPtr !=3D NULL); + return EFI_INVALID_PARAMETER; + } + SetMem (&SlitPtr->NumSlit[0].Entry, EFI_ACPI_SYSTEM_LOCALITIES_ENTRY_COU= NT, 0xFF); + + return EFI_SUCCESS; +} + +/** + Processes socket nodes + + @param[in,out] Table Pointer to SLIT ACPI tables + @param[in] NumCpus Number of CPUs + @param[in] NumClusters Number of clusters + @param[in] PmemNodeCount Number of AEP PMEM NUMA nodes + @param[in] FpgaCount Number of FPGA NUMA nodes + @param[in] NodeCount Number of all nodes + + @retval EFI_SUCCESS operation completed successfully + +**/ +EFI_STATUS +ProcessSockets ( + IN OUT EFI_ACPI_COMMON_HEADER *Table, + IN UINT8 NumCpus, + IN UINT8 NumClusters, + IN UINT8 PmemNodeCount, + IN UINT8 FpgaCount, + IN UINT8 NodeCount + ) +{ + ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *SlitAcpiTable; + UINT16 EntryIdx; + UINT8 SourceNode; + UINT8 SourceSocket; + UINT8 SourceCluster; + UINT8 TargetSocket; + UINT8 TargetCluster; + UINT8 VirtualNumaFactor; + + if (NULL =3D=3D Table) { + DEBUG ((DEBUG_ERROR, "SLIT: Error in SLIT update with data about nodes= on same socket\n")); + return EFI_INVALID_PARAMETER; + } + VirtualNumaFactor =3D 1; + if (mSystemMemoryMap->VirtualNumaEnable) { + VirtualNumaFactor =3D mSystemMemoryMap->VirtualNumOfCluster; + } + + DEBUG ((DEBUG_INFO, "SLIT: Update with data about nodes on same socket\n= ")); + + SlitAcpiTable =3D (ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *)Table; + + for (SourceNode =3D 0; SourceNode < (NodeCount - PmemNodeCount - FpgaCou= nt) ; SourceNode++) { + SourceSocket =3D SourceNode / NumClusters; + SourceCluster =3D SourceNode % NumClusters; + for (TargetSocket =3D 0; TargetSocket < NumCpus; TargetSocket++) { + for (TargetCluster =3D 0; TargetCluster < NumClusters; TargetCluster= ++) { + if (SourceSocket =3D=3D TargetSocket) { + EntryIdx =3D (SourceNode * (NodeCount)) + (TargetSocket * NumClu= sters) + TargetCluster; + // + // Source and target are nodes on same socket + // + if ((SourceCluster / VirtualNumaFactor) =3D=3D (TargetCluster / = VirtualNumaFactor)) { + // + // a) Same socket same physical cluster + // + SlitAcpiTable->NumSlit[EntryIdx].Entry =3D ZERO_HOP; + } else { + // + // b) Same socket different cluster + // + SlitAcpiTable->NumSlit[EntryIdx].Entry =3D ZERO_ONE; + } + } + } + } + } + + return EFI_SUCCESS; +} + +/** + Processes socket nodes + + @param[in,out] Table Pointer to SLIT ACPI tables + @param[in] NumCpus Number of CPUs + @param[in] NumClusters Number of clusters + @param[in] PmemNodeCount Number of AEP PMEM NUMA nodes + @param[in] FpgaCount Number of FPGA NUMA nodes + @param[in] NodeCount Number of all nodes + + @retval EFI_SUCCESS operation completed successfully + +**/ +EFI_STATUS +ProcessMixedModeSockets ( + IN OUT EFI_ACPI_COMMON_HEADER *Table, + IN UINT8 NumCpus, + IN UINT8 NumClusters, + IN UINT8 PmemNodeCount, + IN UINT8 FpgaCount, + IN UINT8 NodeCount + ) +{ + ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *SlitAcpiTable; + UINT16 EntryIdx1LM; + UINT16 EntryIdx2LM; + UINT8 SourceNode; + UINT8 SourceSocket; + UINT8 SourceCluster; + UINT8 TargetSocket; + UINT8 TargetCluster; + BOOLEAN Is2LM; + + if (NULL =3D=3D Table) { + DEBUG ((DEBUG_ERROR, "SLIT: Error in SLIT update with data about nodes= on same socket for Mixed Mode\n")); + return EFI_INVALID_PARAMETER; + } + + DEBUG ((DEBUG_INFO, "SLIT: Update with data about nodes on same socket f= or Mixed Mode\n")); + + SlitAcpiTable =3D (ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *)Table; + + for (SourceNode =3D 0; SourceNode < (NodeCount - PmemNodeCount - FpgaCou= nt) ; SourceNode++) { + Is2LM =3D (SourceNode >=3D NumCpus * NumClusters) ? TRUE : FALSE; + SourceSocket =3D (SourceNode - NumCpus * NumClusters * (Is2LM ? 1 : 0)= ) / NumClusters; + SourceCluster =3D (SourceNode - NumCpus * NumClusters * (Is2LM ? 1 : 0= )) % NumClusters; + + TargetSocket =3D SourceSocket; + for (TargetCluster =3D 0; TargetCluster < NumClusters; TargetCluster++= ) { + EntryIdx1LM =3D (UINT16)((SourceNode * NodeCount) + (TargetSocket * = NumClusters) + TargetCluster); + EntryIdx2LM =3D EntryIdx1LM + NumCpus * NumClusters; + + if ((SourceCluster =3D=3D TargetCluster) && (Is2LM =3D=3D FALSE)) { + // + // CPU -> 1LM at the same socket, the same cluster + // + SlitAcpiTable->NumSlit[EntryIdx1LM].Entry =3D ZERO_HOP; + // + // CPU -> 2LM at the same socket, the same cluster + // + SlitAcpiTable->NumSlit[EntryIdx2LM].Entry =3D ZERO_ONE; + } else if ((SourceCluster =3D=3D TargetCluster) && (Is2LM =3D=3D TRU= E)) { + // + // CPU -> 2LM at the same socket, the same cluster + // + SlitAcpiTable->NumSlit[EntryIdx1LM].Entry =3D ZERO_ONE; + // + // not effective + // + SlitAcpiTable->NumSlit[EntryIdx2LM].Entry =3D ZERO_HOP; + } else if ((SourceCluster !=3D TargetCluster) && (Is2LM =3D=3D FALSE= )) { + // + // CPU -> 1LM at the same socket, different cluster + // + SlitAcpiTable->NumSlit[EntryIdx1LM].Entry =3D ZERO_ONE; + // + // CPU -> 2LM at the same socket, different cluster + // + SlitAcpiTable->NumSlit[EntryIdx2LM].Entry =3D ZERO_TWO; + } else { + // + // branch condition: ((SourceCluster !=3D TargetCluster) && (Is2LM= =3D=3D TRUE)) + // CPU -> 2LM at the same socket, different cluster + // + SlitAcpiTable->NumSlit[EntryIdx1LM].Entry =3D ZERO_TWO; + // + // not effective + // + SlitAcpiTable->NumSlit[EntryIdx2LM].Entry =3D ZERO_TWO; + } + } + } + + return EFI_SUCCESS; +} + +/** + Processes connections between sockets to retrieve valid distances + + @param[in,out] Table Pointer to SLIT ACPI tables + @param[in] NumCpus Number of CPUs + @param[in] NumClusters Number of clusters + @param[in] PmemNodeCount Number of AEP PMEM NUMA nodes + @param[in] FpgaCount Number of FPGA NUMA nodes + @param[in] NodeCount Number of all nodes + + @retval EFI_SUCCESS operation completed successfully + +**/ +EFI_STATUS +ProcessSocketsLinks ( + IN OUT EFI_ACPI_COMMON_HEADER *Table, + IN UINT8 NumCpus, + IN UINT8 NumClusters, + IN UINT8 PmemNodeCount, + IN UINT8 FpgaCount, + IN UINT8 NodeCount + ) +{ + ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *SlitAcpiTable; + UINT8 SourceNode; + UINT8 SourceSocket; + UINT8 SourceCluster; + UINT8 TargetSocket; + + if (NULL =3D=3D Table) { + DEBUG ((DEBUG_ERROR, "SLIT: Error in processing links between sockets\= n")); + return EFI_INVALID_PARAMETER; + } + + DEBUG ((DEBUG_INFO, "SLIT: Update table with links between sockets\n")); + + SlitAcpiTable =3D (ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *)Table; + + for (SourceNode =3D 0; SourceNode < (NodeCount - PmemNodeCount - FpgaCou= nt); SourceNode++) { + SourceSocket =3D SourceNode / NumClusters; + SourceCluster =3D SourceNode % NumClusters; + for (TargetSocket =3D 0; TargetSocket < NumCpus; TargetSocket++) { + if (SocketsLinked (GetSocketPhysicalId (SourceSocket), GetSocketPhys= icalId (TargetSocket))) { + SetMem (&SlitAcpiTable->NumSlit[(SourceNode * NodeCount) + (Target= Socket * NumClusters)].Entry, + NumClusters, ONE_HOP); + } + } + } + + return EFI_SUCCESS; +} + +/** + Processes connections between sockets to retrieve valid distances + + @param[in,out] Table Pointer to SLIT ACPI tables + @param[in] NumCpus Number of CPUs + @param[in] NumClusters Number of clusters + @param[in] PmemNodeCount Number of AEP PMEM NUMA nodes + @param[in] FpgaCount Number of FPGA NUMA nodes + @param[in] NodeCount Number of all nodes + + @retval EFI_SUCCESS operation completed successfully + +**/ +EFI_STATUS +ProcessMixedModeSocketsLinks ( + IN OUT EFI_ACPI_COMMON_HEADER *Table, + IN UINT8 NumCpus, + IN UINT8 NumClusters, + IN UINT8 PmemNodeCount, + IN UINT8 FpgaCount, + IN UINT8 NodeCount + ) +{ + ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *SlitAcpiTable; + UINT16 EntryIdx1LM; + UINT16 EntryIdx2LM; + UINT8 SourceNode; + UINT8 SourceSocket; + UINT8 SourceCluster; + UINT8 TargetSocket; + UINT8 TargetCluster; + BOOLEAN Is2LM; + + if (NULL =3D=3D Table) { + DEBUG ((DEBUG_ERROR, "SLIT: Error in processing links between sockets = in Mixed Mode\n")); + return EFI_INVALID_PARAMETER; + } + + DEBUG ((DEBUG_INFO, "SLIT: Update table with links between sockets in Mi= xed Mode\n")); + + SlitAcpiTable =3D (ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *)Table; + + for (SourceNode =3D 0; SourceNode < (NodeCount - PmemNodeCount - FpgaCou= nt); SourceNode++) { + Is2LM =3D (SourceNode >=3D NumCpus * NumClusters) ? TRUE : FALSE; + SourceSocket =3D (SourceNode - NumCpus * NumClusters * (Is2LM ? 1 : 0)= ) / NumClusters; + SourceCluster =3D (SourceNode - NumCpus * NumClusters * (Is2LM ? 1 : 0= )) % NumClusters; + + for (TargetSocket =3D 0; TargetSocket < NumCpus; TargetSocket++) { + if (SocketsLinked (GetSocketPhysicalId (SourceSocket), GetSocketPhys= icalId (TargetSocket))) { + // + // If both sockets are linked by KTI and not the same socket. + // + for (TargetCluster =3D 0; TargetCluster < NumClusters; TargetClust= er++) { + EntryIdx1LM =3D (UINT16)((SourceNode * NodeCount) + (TargetSocke= t * NumClusters) + TargetCluster); + EntryIdx2LM =3D EntryIdx1LM + NumCpus * NumClusters; + + if (Is2LM =3D=3D FALSE) { + // + // CPU -> 1LM at different socket + // + SlitAcpiTable->NumSlit[EntryIdx1LM].Entry =3D ONE_HOP; + // + // CPU -> 2LM at different socket + // + SlitAcpiTable->NumSlit[EntryIdx2LM].Entry =3D ONE_ONE; + } else { + // + // branch condition: (Is2LM =3D=3D TRUE) + // CPU -> 2LM at different socket + // + SlitAcpiTable->NumSlit[EntryIdx1LM].Entry =3D ONE_ONE; + // + // not effective + // + SlitAcpiTable->NumSlit[EntryIdx2LM].Entry =3D ONE_TWO; + } + } + } + } + } + + return EFI_SUCCESS; +} + +/** + Processes all AEP PMEM NUMA nodes + + @param[in,out] Table Pointer to SLIT ACPI tables + @param[in] NumCpus Number of CPUs + @param[in] NumClusters Number of clusters + @param[in] PmemNodeCount Number of AEP PMEM NUMA nodes + @param[in] FpgaCount Number of FPGA NUMA nodes + @param[in] NodeCount Number of all nodes + + @retval EFI_SUCCESS operation completed successfully + +**/ +EFI_STATUS +ProcessPmems ( + IN OUT EFI_ACPI_COMMON_HEADER *Table, + IN UINT8 NumCpus, + IN UINT8 NumClusters, + IN UINT8 PmemNodeCount, + IN UINT8 FpgaCount, + IN UINT8 NodeCount + ) +{ + ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *SlitAcpiTable; + UINT16 EntryIdx; + UINT8 SourceNode; + UINT8 TargetNode; + UINT8 SourceSocket; + UINT8 TargetCluster; + UINT8 TargetSocket; + UINT8 SourcePmem; + UINT8 TargetPmem; + UINT8 SourcePmemSocket; + UINT8 TargetPmemSocket; + UINT8 TotalVolMemNodes; + + if (NULL =3D=3D Table) { + DEBUG ((DEBUG_ERROR, "SLIT: Error in processing PMems\n")); + return EFI_INVALID_PARAMETER; + } + + if (mSystemMemoryMap->volMemMode =3D=3D VOL_MEM_MODE_MIX_1LM2LM) { + TotalVolMemNodes =3D NumCpus * NumClusters * EFI_ACPI_SLIT_DOMAINS_NOD= ES_MAX_CNT; + } else { + TotalVolMemNodes =3D NumCpus * NumClusters; + } + + DEBUG ((DEBUG_INFO, "SLIT: Include PMem NUMA nodes\n")); + + if (PmemNodeCount > 0) { + + SlitAcpiTable =3D (ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *)Table; + + // + // 1) AEP PMEM nodes to AEP PMEM nodes distances + // + for (SourceNode =3D (NodeCount - PmemNodeCount - FpgaCount); SourceNod= e < (NodeCount - FpgaCount); SourceNode++) { + SourcePmem =3D SourceNode - TotalVolMemNodes; + for (TargetPmem =3D 0; TargetPmem < PmemNodeCount; TargetPmem++) { + TargetNode =3D TargetPmem + TotalVolMemNodes; + EntryIdx =3D (SourceNode * NodeCount) + TargetNode; + if (SourcePmem =3D=3D TargetPmem) { + SlitAcpiTable->NumSlit[EntryIdx].Entry =3D PMEM_ZERO_HOP; + } else { + // + // Retrieve sockets associated with PMEMs + // + SourcePmemSocket =3D GetSocketForPmem (SourcePmem); + TargetPmemSocket =3D GetSocketForPmem (TargetPmem); + + if (SourcePmemSocket =3D=3D TargetPmemSocket) { + // + // PMEMs are on the same socket + // + SlitAcpiTable->NumSlit[EntryIdx].Entry =3D PMEM_ONE_ONE; + } else { + // + // Assign 2 hop and process with PeerInfo checking + // + SlitAcpiTable->NumSlit[EntryIdx].Entry =3D PMEM_TWO_HOP; + + // + // Examine PeerInfo to look for link between AEP PMEM source s= ocket and AEP PMEM target socket + // + if (SocketsLinked (SourcePmemSocket, TargetPmemSocket)) { + // + // Link found assign 1 hop + // + SlitAcpiTable->NumSlit[EntryIdx].Entry =3D PMEM_ONE_HOP; + } + } + } + } + } + + // + // 2) Sockets to AEP PMEM nodes distances + // + for (SourceNode =3D 0; SourceNode < (NodeCount - PmemNodeCount - FpgaC= ount); SourceNode++) { + SourceSocket =3D GetSocketPhysicalId (SourceNode / NumClusters); + for (TargetPmem =3D 0; TargetPmem < PmemNodeCount; TargetPmem++) { + TargetPmemSocket =3D GetSocketForPmem (TargetPmem); + TargetNode =3D TargetPmem + TotalVolMemNodes; + EntryIdx =3D (SourceNode * NodeCount) + TargetNode; + if (SourceSocket =3D=3D TargetPmemSocket) { + SlitAcpiTable->NumSlit[EntryIdx].Entry =3D PMEM_ONE_ONE; + } else { + // + // Assign 2 hop and process with PeerInfo checking + // + SlitAcpiTable->NumSlit[EntryIdx].Entry =3D PMEM_TWO_HOP; + + // + // Examine PeerInfo to look for link between source socket and A= EP PMEM socket + // + if (SocketsLinked (SourceSocket, TargetPmemSocket)) { + // + // Link found assign 1 hop + // + SlitAcpiTable->NumSlit[EntryIdx].Entry =3D PMEM_ONE_HOP; + } + } + } + } + + // + // 3) AEP PMEM nodes to sockets distances + // + for (SourceNode =3D (NodeCount - PmemNodeCount - FpgaCount); SourceNod= e < (NodeCount - FpgaCount); SourceNode++) { + SourcePmem =3D SourceNode - TotalVolMemNodes; + SourcePmemSocket =3D GetSocketForPmem (SourcePmem); + for (TargetSocket =3D 0; TargetSocket < NumCpus; TargetSocket++) { + for (TargetCluster =3D 0; TargetCluster < NumClusters; TargetClust= er++) { + EntryIdx =3D (SourceNode * NodeCount) + (TargetSocket * NumClust= ers) + TargetCluster; + if(SourcePmemSocket =3D=3D GetSocketPhysicalId (TargetSocket)) { + SlitAcpiTable->NumSlit[EntryIdx].Entry =3D PMEM_ONE_ONE; + } else { + // + // Assign 2 hop and process with PeerInfo checking + // + SlitAcpiTable->NumSlit[EntryIdx].Entry =3D PMEM_TWO_HOP; + + // + // Examine PeerInfo to look for link between source socket and= AEP PMEM socket + // + if (SocketsLinked (SourcePmemSocket, GetSocketPhysicalId (Targ= etSocket))) { + // + // Link found assign 1 hop + // + SlitAcpiTable->NumSlit[EntryIdx].Entry =3D PMEM_ONE_HOP; + } + } + } + } + } + } else { + DEBUG ((DEBUG_INFO, "SLIT: PMem NUMA nodes not present\n")); + } + + return EFI_SUCCESS; +} + +/** + This function processes all FPGA NUMA nodes. + + @param[in,out] Table Pointer to SLIT ACPI tables. + @param[in] NumClusters Number of clusters. + @param[in] PmemNodeCount Number of AEP PMEM NUMA nodes. + @param[in] FpgaCount Number of FPGA NUMA nodes. + @param[in] NodeCount Number of all nodes. + + @retval EFI_SUCCESS This function is executed successfully. + @retval EFI_INVALID_PARAMETER Some of input parameters are invalid. +**/ +EFI_STATUS +ProcessFpgaNodes ( + IN OUT EFI_ACPI_COMMON_HEADER *Table, + IN UINT8 NumClusters, + IN UINT8 PmemNodeCount, + IN UINT8 FpgaCount, + IN UINT8 NodeCount + ) +{ + ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *SlitAcpiTable; + UINT8 SourceNode; + UINT8 TargetNode; + UINT8 SourceSocket; + UINT8 TargetSocket; + + if (Table =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "SLIT: Error in processing FPGA nodes\n")); + return EFI_INVALID_PARAMETER; + } + + if (FpgaCount =3D=3D 0) { + return EFI_SUCCESS; + } + + SlitAcpiTable =3D (ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *)Table; + + for (SourceNode =3D (NodeCount - FpgaCount); SourceNode < NodeCount; Sou= rceNode++) { + SourceSocket =3D GetPhyNodeIdForFpga (SourceNode - (NodeCount - FpgaCo= unt)); + + for (TargetNode =3D 0; TargetNode < NodeCount; TargetNode++) { + if (TargetNode < (NodeCount- PmemNodeCount - FpgaCount)) { + TargetSocket =3D GetSocketPhysicalId (TargetNode / NumClusters); = // Normal nodes + } else if (TargetNode < (NodeCount - FpgaCount)) { + TargetSocket =3D GetSocketForPmem (TargetNode - (NodeCount - PmemN= odeCount - FpgaCount)); // PMEM nodes + } else { + TargetSocket =3D GetPhyNodeIdForFpga (TargetNode - (NodeCount - Fp= gaCount)); // FPGA nodes + } + + if (SourceSocket =3D=3D TargetSocket) { + SlitAcpiTable->NumSlit[SourceNode * NodeCount + TargetNode].Entry = =3D ZERO_HOP; + } else if (SocketsLinked (SourceSocket, TargetSocket)) { + SlitAcpiTable->NumSlit[SourceNode * NodeCount + TargetNode].Entry = =3D ONE_HOP; + SlitAcpiTable->NumSlit[TargetNode * NodeCount + SourceNode].Entry = =3D ONE_HOP; + } else { + SlitAcpiTable->NumSlit[SourceNode * NodeCount + TargetNode].Entry = =3D TWO_HOP; + SlitAcpiTable->NumSlit[TargetNode * NodeCount + SourceNode].Entry = =3D TWO_HOP; + } + } + } + + return EFI_SUCCESS; +} + +/** + Processes all remaining valid SLIT nodes + + @param[in,out] Table pointer to SLIT ACPI tables + + @retval EFI_SUCCESS operation completed successfully + +**/ +EFI_STATUS +ProcessRemainingNodes ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *SlitAcpiTable; + UINT16 EntryIdx =3D 0; + UINT16 MaxTableEntries; + UINT8 NodeCount; + + if (NULL =3D=3D Table) { + DEBUG ((DEBUG_ERROR, "SLIT: Error while processing remaining valid nod= es\n")); + return EFI_INVALID_PARAMETER; + } + + DEBUG ((DEBUG_INFO, "SLIT: Fill in the rest of the SLIT table\n")); + + SlitAcpiTable =3D (ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *)Table; + + NodeCount =3D (UINT8)SlitAcpiTable->Header.NumberOfSystemLocalities; + MaxTableEntries =3D NodeCount * NodeCount; + + while (EntryIdx < MaxTableEntries) { + if (SlitAcpiTable->NumSlit[EntryIdx].Entry =3D=3D 0xFF) { + // + // This entry has not been filled yet, assign 2 hop to this table en= try + // + SlitAcpiTable->NumSlit[EntryIdx].Entry =3D TWO_HOP; + } + + if ((EntryIdx % NodeCount) =3D=3D 0) { + DEBUG ((DEBUG_INFO, "[%2d - %2d] ", EntryIdx/NodeCount, EntryIdx%Nod= eCount)); + } + EntryIdx++; + } + + return EFI_SUCCESS; +} + +/** + Processes unused SLIT nodes + + @param[in,out] Table pointer to SLIT ACPI tables + + @retval EFI_SUCCESS operation completed successfully + +**/ +EFI_STATUS +ProcessUnusedNodes ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *SlitAcpiTable; + UINT16 MaxTableEntries; + UINT8 NodeCount; + + if (NULL =3D=3D Table) { + DEBUG ((DEBUG_ERROR, "SLIT: Error while processing unused nodes\n")); + return EFI_INVALID_PARAMETER; + + } + + DEBUG ((DEBUG_INFO, "SLIT: Zero out the unused nodes\n")); + + SlitAcpiTable =3D (ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *)Table; + + NodeCount =3D (UINT8)SlitAcpiTable->Header.NumberOfSystemLocalities; + MaxTableEntries =3D NodeCount * NodeCount; + + SetMem (&SlitAcpiTable->NumSlit[MaxTableEntries], + (UINTN)&SlitAcpiTable->NumSlit[EFI_ACPI_SYSTEM_LOCALITIES_ENTRY_C= OUNT] - (UINTN)&SlitAcpiTable->NumSlit[MaxTableEntries], 0); + + return EFI_SUCCESS; +} + +/** + Updates System Locality Distance Information Table (SLIT) + + @param[in,out] Table pointer to SLIT ACPI tables + + @retval EFI_SUCCESS operation completed successfully + @retval EFI_ABORTED operation not completed due to processing error + +**/ +EFI_STATUS +PatchSLitTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *SlitAcpiTable; + EFI_STATUS Status; + UINT8 NodeCount; + UINT8 NumCpus; + UINT8 NumClusters; + UINT8 PmemNodeCount; + UINT8 FpgaCount; + + NumCpus =3D GetNumCpus (); + NumClusters =3D GetNumClusters (); + PmemNodeCount =3D GetPmemNodeCount (); + FpgaCount =3D GetFpgaCount(); + NodeCount =3D GetNodeCount (NumCpus, NumClusters, PmemNodeCount, FpgaCou= nt); + + DEBUG ((DEBUG_INFO, "SLIT: NumCpus %d, NumClusters %d, PmemNodeCount %d = -> NodeCount %d FpgaCount %d\n", + NumCpus, NumClusters, PmemNodeCount, NodeCoun= t,FpgaCount)); + + SlitAcpiTable =3D (ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *)Table; + SlitAcpiTable->Header.NumberOfSystemLocalities =3D NodeCount; + + // + // 1) Initialize all entries to 0xFF + // + Status =3D InitEntries (SlitAcpiTable); + + // + // 2) Update SLIT table with data about nodes on same socket + // + if (!EFI_ERROR(Status)) { + if (mSystemMemoryMap->volMemMode =3D=3D VOL_MEM_MODE_MIX_1LM2LM) { + Status =3D ProcessMixedModeSockets (Table, NumCpus, NumClusters, Pme= mNodeCount, FpgaCount, NodeCount); + } else { + Status =3D ProcessSockets (Table, NumCpus, NumClusters, PmemNodeCoun= t, FpgaCount, NodeCount); + } + } + + // + // 3) Update table with links between sockets by examining PeerInfo stru= cture + // + if (!EFI_ERROR (Status)) { + if (mSystemMemoryMap->volMemMode =3D=3D VOL_MEM_MODE_MIX_1LM2LM) { + Status =3D ProcessMixedModeSocketsLinks (Table, NumCpus, NumClusters= , PmemNodeCount, FpgaCount, NodeCount); + } else { + Status =3D ProcessSocketsLinks (Table, NumCpus, NumClusters, PmemNod= eCount, FpgaCount, NodeCount); + } + } + + // + // 4) Update table with PMEMs + // + if (!EFI_ERROR (Status)) { + Status =3D ProcessPmems (Table, NumCpus, NumClusters, PmemNodeCount, F= pgaCount, NodeCount); + } + + // + // 5 Update table with FPGA + // + if (!EFI_ERROR (Status)) { + Status =3D ProcessFpgaNodes (Table, NumClusters, PmemNodeCount, FpgaCo= unt, NodeCount); + } + + // + // 6) Fill in the rest of the Slit table, 2 hops between any remaining v= alid nodes + // + if (!EFI_ERROR (Status)) { + Status =3D ProcessRemainingNodes (Table); + } + + // + // 7) Zero out the unused nodes + // + if (!EFI_ERROR (Status)) { + Status =3D ProcessUnusedNodes (Table); + } + + // + // 8) Print the entire SLIT table + // + if (!EFI_ERROR (Status)) { + DisplayEntries (SlitAcpiTable); + } + + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** + Allocate memory and fill SLIT information to this buffer, then + install this table to ACPI table. + + @retval EFI_SUCCESS Install table success. + @retval EFI_OUT_OF_RESOURCES Out of memory. + +**/ +EFI_STATUS +InstallSlitTable ( + VOID + ) +{ + ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *Table; + UINTN TableSize; + UINT8 NumClusters; + UINTN TableHandle =3D 0; + EFI_STATUS Status; + + NumClusters =3D GetNumClusters (); + + TableSize =3D sizeof (EFI_ACPI_6_2_SYSTEM_LOCALITY_DISTANCE_INFORMATION_= TABLE_HEADER) + + sizeof (ACPI_SYSTEM_LOCALITIES_STRUCTURE) * EFI_ACPI_SYSTEM_= LOCALITIES_ENTRY_COUNT; + + Table =3D (ACPI_SYSTEM_LOCALITY_INFORMATION_TABLE *) AllocateZeroPool (T= ableSize); + if (Table =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Table->Header.Header.Signature =3D EFI_ACPI_6_2_SYSTEM_LOCALITY_INFORMAT= ION_TABLE_SIGNATURE; + Table->Header.Header.Length =3D (UINT32) TableSize; + Table->Header.Header.Revision =3D EFI_ACPI_6_2_SYSTEM_LOCALITY_DISTANCE_= INFORMATION_TABLE_REVISION; + Table->Header.Header.OemRevision =3D EFI_ACPI_OEM_SLIT_REVISION; + CopyMem (Table->Header.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), si= zeof (Table->Header.Header.OemId)); + Table->Header.Header.OemTableId =3D PcdGet64 (PcdAcpiDefaultOemTableId); + Table->Header.Header.CreatorId =3D PcdGet32 (PcdAcpiDefaultCreatorId); + Table->Header.Header.CreatorRevision =3D PcdGet32 (PcdAcpiDefaultCreator= Revision); + + // + // All node init with 0 before pass to patcher + // + PatchSLitTable ((EFI_ACPI_COMMON_HEADER *)&Table->Header.Header); + + // + // Publish SLIT Structure to ACPI + // + + Status =3D mAcpiTable->InstallAcpiTable ( + mAcpiTable, + Table, + Table->Header.Header.Length, + &TableHandle + ); + + // + // Free memory + // + if (Table !=3D NULL) { + FreePool (Table); + } + + return Status; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLi= b/AcpiPlatformLibSrat.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPl= atformTableLib/AcpiPlatformLibSrat.c new file mode 100644 index 0000000000..c19c942274 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiP= latformLibSrat.c @@ -0,0 +1,952 @@ +/** @file + ACPI Platform Driver Hooks + + @copyright + Copyright 1996 - 2020 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// Statements that include other files +// +#include "AcpiPlatformLibLocal.h" +#include +#include +#include +#include + +extern BOOLEAN mX2ApicEnabled; +extern struct SystemMemoryMapHob *mSystemMemoryMap; +extern EFI_IIO_UDS_PROTOCOL *mIioUds; +extern SOCKET_MEMORY_CONFIGURATION mSocketMemoryConfiguration; +extern UINT32 mNumOfBitShift; +extern UINT32 mApicIdMap[MAX_SOCKET][MAX_CORE * MAX_= THREAD]; +extern UINTN mNumberOfCPUs; +extern CPU_ID_ORDER_MAP mCpuApicIdOrderTable[]; +extern EFI_ACPI_TABLE_PROTOCOL *mAcpiTable; +extern CPU_CSR_ACCESS_VAR *mCpuCsrAccessVarPtr; + +UINT32 mPackageChaTotal[MAX_SOCKET]; + +CPU_LOGICAL_THREAD_ID_TABLE mCpuThreadIdMsrTable[MAX_CPU_NUM]; + +static ACPI_PLATFORM_PROTOCOL mAcpiPlatformProtocol; + +struct _ACPI_PLATFORM_UTILS_MEM_AFF_DATA { + EFI_ACPI_6_2_MEMORY_AFFINITY_STRUCTURE AcpiMemAffData[MEMORY_AFFINITY_ST= RUCTURE_COUNT]; + BOOLEAN AcpiMemAffDataValid; +} mAcpiPlatformMemAffData; + + +VOID +CollectThreadIdMsrData ( + IN UINT8 SncEnabled, + IN UINT8 SncNumOfCluster + ); + +UINT32 +GetProximityDomainForSNC ( + UINT32 ApicId + ); + + +/** + This function counts the number of bits set in a 32-bit unsigned integer. + + @param[in] Value The 32-bit unsigned integer to count. + + @retval The number of set bits. +**/ +UINT8 +BitCount32 ( + IN UINT32 Value + ) +{ + UINT8 Count; + + Count =3D 0; + while (Value !=3D 0) { + Value &=3D Value - 1; + Count++; + } + + return Count; +} + +/** + Get the socket logical index. + + This function convert the socket physical index to logical index (0 base= d). + If the specified physical socket is not enabled, an invalid logical inde= x 0xff + will be returned. The socket physical index and logical index will be th= e same + if the indexes of enabled sockets are continuous. + + @param[in] SocketPhysicalId Socket physical index. + + @retval Socket logical index. +**/ +UINT8 +GetSocketLogicalId ( + IN UINT8 SocketPhysicalId + ) +{ + UINT32 SocketBitMap; + + if ((mCpuCsrAccessVarPtr->socketPresentBitMap & (BIT0 << SocketPhysicalI= d)) =3D=3D 0) { + return (UINT8) -1; + } + + SocketBitMap =3D mCpuCsrAccessVarPtr->socketPresentBitMap & ((BIT0 << So= cketPhysicalId) - 1); + return BitCount32 (SocketBitMap); +} + +/** + Get the socket physical index. + + This function convert the socket logical index to physical index (0 base= d). + If the specified logical socket does not exist, an invalid physical inde= x 0xff + will be returned. The socket physical index and logical index will be th= e same + if the indexes of enabled sockets are continuous. + + @param[in] SocketLogicalId Socket logical index. + + @retval Socket physical index. +**/ +UINT8 +GetSocketPhysicalId ( + IN UINT8 SocketlogicId + ) +{ + UINT32 SocketBitMap; + + SocketBitMap =3D mCpuCsrAccessVarPtr->socketPresentBitMap; + + while (SocketlogicId !=3D 0) { + SocketBitMap &=3D SocketBitMap - 1; + SocketlogicId--; + } + + if (SocketBitMap =3D=3D 0) { + return (UINT8) -1; + } + + return BitCount32 (SocketBitMap ^ (SocketBitMap - 1)) - 1; +} + +/** + + Update the SRAT APIC IDs. + + @param *SRAAcpiTable - The table to be set + + @retval EFI_SUCCESS - Returns Success + +**/ +EFI_STATUS +PatchSratAllApicIds( + IN OUT STATIC_RESOURCE_AFFINITY_TABLE *SRAAcpiTable + ) +{ + UINT16 ThreadIndex; // Support more than 256 thre= ads (8S case) + UINT8 *ApicTablePtr; + UINT8 socket; + UINT8 Index; + + ThreadIndex =3D 0; + for (socket =3D 0; socket < MAX_SOCKET; socket++) { + ApicTablePtr =3D (UINT8*)mApicIdMap[socket]; + // + // Even IDs must be list first + // + for (Index =3D 0; Index < MAX_CORE * MAX_THREAD; Index +=3D 2) { + SRAAcpiTable->Apic[ThreadIndex].ApicId =3D (UINT8)ApicTablePtr[Index= ] + (socket << mNumOfBitShift); + SRAAcpiTable->Apic[ThreadIndex].ProximityDomain7To0 =3D socket; //as= ProxDomain are all 0, or we can come up some algorithm if there is any dep= endency + if ((UINT8)ApicTablePtr[Index] !=3D 0xff) { + SRAAcpiTable->Apic[ThreadIndex].Flags =3D EFI_ACPI_6_2_PROCESSOR_L= OCAL_APIC_SAPIC_ENABLED; + } + ThreadIndex++; + } //end of for coreThreadIndex + } //end for socket + + for (socket =3D 0; socket < MAX_SOCKET; socket++) { + // + // for odd APICID and must be after all even APICIDs + // + ApicTablePtr =3D (UINT8*)mApicIdMap[socket]; + for (Index =3D 1; Index < MAX_CORE * MAX_THREAD; Index +=3D 2) { + SRAAcpiTable->Apic[ThreadIndex].ApicId =3D (UINT8)ApicTablePtr[Index= ] + (socket << mNumOfBitShift); + SRAAcpiTable->Apic[ThreadIndex].ProximityDomain7To0 =3D socket; //as= ProxDomain are all 0, or we can come up some algorithm if there is any dep= endency + if ((UINT8)ApicTablePtr[Index] !=3D 0xff) { + SRAAcpiTable->Apic[ThreadIndex].Flags =3D EFI_ACPI_6_2_PROCESSOR_L= OCAL_APIC_SAPIC_ENABLED; + } + ThreadIndex++; + } + } //end of for coreThreadIndex + ASSERT (ThreadIndex =3D=3D MAX_CPU_NUM); + return EFI_SUCCESS; +} + +UINT32 +ProximityDomainOf ( + UINT8 SocketId, + UINT16 MemType, + UINT8 MaxEnabledImc, + UINT8 SncEnabled, + UINT8 SncNumOfCluster, + UINT8 ImcInterBitmap, + UINT8 MemMode, + UINT32 LastDomainId + ) +{ + UINT32 DomainId =3D (UINT16)~0; + INTN FirstImc; + UINT8 ImcPerCluster; + UINT8 NumSockets =3D mIioUds->IioUdsPtr->SystemStatus.numCpus; + UINT8 SocketLogicalId; + + EFI_STATUS Status =3D EFI_SUCCESS; + DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &= DynamicSiLibraryProtocol2); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + } + + if (SncEnabled =3D=3D 0) { + SncNumOfCluster =3D 1; + } + + if (!DynamicSiLibraryProtocol2->IsMemTypeVolatile (MemType)) { + // + // Persistent memory nodes and FPGA nodes are just pending behinds vol= atile memories + // + DomainId =3D LastDomainId + 1; + } else { + SocketLogicalId =3D GetSocketLogicalId (SocketId); + // + // Process volatile memory nodes + // + if (SncEnabled =3D=3D 0) { + DomainId =3D SocketLogicalId; + } else { + // + // Find the cluster ID using ImcInterBitmap + // + ImcPerCluster =3D MAX_IMC / SncNumOfCluster; + FirstImc =3D LowBitSet32 (ImcInterBitmap); + if (FirstImc =3D=3D -1) { + FirstImc =3D 0; + } + if (MaxEnabledImc <=3D SncNumOfCluster) { + DomainId =3D (SocketLogicalId * SncNumOfCluster) + (UINT32) (First= Imc / ImcPerCluster); + } else { + DomainId =3D (SocketLogicalId * SncNumOfCluster) + ((UINT32) First= Imc) / ImcPerCluster; + } + } + if (MemMode =3D=3D VOL_MEM_MODE_MIX_1LM2LM) { + // + // 2LM nodes follow the completion of iteration of all 1LM nodes + // + DomainId +=3D (UINT32)((DynamicSiLibraryProtocol2->IsMemType2lm (Mem= Type) ? 1 : 0) * NumSockets * SncNumOfCluster); + } + } + + DEBUG ((DEBUG_INFO, "SocketId =3D %d, SncEnabled =3D %d, SncNumOfCluster= =3D %d, ImcInterBitmap =3D 0x%x, ", + SocketId, SncEnabled, SncNumOfCluster, ImcInterBitmap)); + + DEBUG ((DEBUG_INFO, "MemType =3D %d, MemMode =3D %d, Physical DomainId = =3D %d\n", + MemType, MemMode, DomainId)); + + return DomainId; +} + +VOID +PatchMemorySratEntries ( + IN OUT STATIC_RESOURCE_AFFINITY_TABLE *SratTable, + UINT8 SncEnabled, + UINT8 SncNumOfCluster, + UINT8 *LastIndexUsed + ) +{ + UINT8 LegacyNodeId; + UINT8 NodeId; + UINT8 Index; + UINT8 TableIndex =3D 0; + UINT8 Socket; + UINT32 LastDomainId =3D 0; + UINT64 MemoryAddress; + UINT64 MemorySize; + UINT8 Pass; + UINT8 PrevIndex; + BOOLEAN SkipEntry; + UINT8 MaxEnabledImc =3D 0; + UINTN ImcIndex; + UINT8 MemSocketBitmap =3D 0; + UINT8 NoMemSocketBitmap; + UINT32 ProximityDomain; + UINT8 PhysicalClusters; + UINT8 VirtualClusters; + + EFI_STATUS Status =3D EFI_SUCCESS; + DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &= DynamicSiLibraryProtocol2); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return; + } + + LegacyNodeId =3D 0xFF; + DEBUG ((DEBUG_INFO, "\nSRAT: Updating SRAT memory information!\n")); + DEBUG ((DEBUG_INFO, "Idx Base Length Proximity F= lags\n")); + + if (mSystemMemoryMap->VirtualNumaEnable) { + PhysicalClusters =3D SncNumOfCluster / mSystemMemoryMap->VirtualNumOfC= luster; + VirtualClusters =3D mSystemMemoryMap->VirtualNumOfCluster; + } else { + PhysicalClusters =3D SncNumOfCluster; + VirtualClusters =3D 1; + } + + // + // Looping the System Memory Map elements twice + // Fist loop creates domains for all volatile regions based on socket + // The second loop creates domains for all persistent memory ranges + // + for (Pass =3D 1; Pass < 3; Pass++ ) { + TableIndex =3D 0; + for (Index =3D 0; Index < mSystemMemoryMap->numberEntries; Index++ ) { + SkipEntry =3D FALSE; + NodeId =3D mSystemMemoryMap->Element[Index].NodeId; + ASSERT (NodeId < MC_MAX_NODE); + + if (TableIndex >=3D MEMORY_AFFINITY_STRUCTURE_COUNT) { + ASSERT (0); + break; + } + + // + // Skip any memory region marked reserved + // + if (DynamicSiLibraryProtocol2->IsMemTypeReserved (mSystemMemoryMap->= Element[Index].Type)) { + continue; + } + + // + // As the HOB has base addr in 64 MB chunks + // + MemoryAddress =3D ((UINT64)mSystemMemoryMap->Element[Index].BaseAddr= ess << MEM_ADDR_SHFT_VAL); + + // + // Skip duplicate entries if applicable + // + if (TableIndex) { + for (PrevIndex =3D 0; PrevIndex < TableIndex; PrevIndex++) { + if (MemoryAddress =3D=3D ((UINT64)SratTable->Memory[PrevIndex].A= ddressBaseHigh << 32) + SratTable->Memory[PrevIndex].AddressBaseLow) { + SkipEntry =3D TRUE; + break; + } + } + } + if (SkipEntry) { + continue; + } + + // + // Update bitmap for sockets with memory populated + // + if (DynamicSiLibraryProtocol2->IsMemTypeVolatile (mSystemMemoryMap->= Element[Index].Type)) { + MemSocketBitmap |=3D BIT0 << mSystemMemoryMap->Element[Index].Sock= etId; + } + + SratTable->Memory[TableIndex].AddressBaseLow =3D (UINT32)(MemoryAddr= ess & 0xFFFFFFFF); + SratTable->Memory[TableIndex].AddressBaseHigh =3D (UINT32)((UINTN)M= emoryAddress >> 32); + + // + // As the HOB has Length in 64 MB chunks + // + MemorySize =3D ((UINT64)mSystemMemoryMap->Element[Index].ElementSiz= e << MEM_ADDR_SHFT_VAL); + SratTable->Memory[TableIndex].LengthLow =3D (UINT32)(MemorySize & 0x= FFFFFFFF); + SratTable->Memory[TableIndex].LengthHigh =3D (UINT32)((UINTN)MemoryS= ize >> 32); + + if ((Pass =3D=3D 2) || DynamicSiLibraryProtocol2->IsMemTypeVolatile = (mSystemMemoryMap->Element[Index].Type)) { + + // + // Get max enabled IMC for this socket + // + for (ImcIndex =3D 0, MaxEnabledImc =3D 0; ImcIndex < MAX_IMC; ImcI= ndex++) { + if (mSystemMemoryMap->Socket[mSystemMemoryMap->Element[Index].So= cketId].imcEnabled[ImcIndex] !=3D 0) { + MaxEnabledImc ++; + } + } + + ProximityDomain =3D ProximityDomainOf ( + mSystemMemoryMap->Element[Index].SocketId, + mSystemMemoryMap->Element[Index].Type, + MaxEnabledImc, + SncEnabled, + PhysicalClusters, + mSystemMemoryMap->Element[Index].ImcInterBitmap, + mSystemMemoryMap->volMemMode, + LastDomainId + ); + SratTable->Memory[TableIndex].ProximityDomain =3D (ProximityDomain= * VirtualClusters) + (Index % VirtualClusters); + if (LastDomainId < SratTable->Memory[TableIndex].ProximityDomain) { + LastDomainId =3D SratTable->Memory[TableIndex].ProximityDomain; + } + if ((MemoryAddress =3D=3D 0) && (MemorySize > 0)) { + LegacyNodeId =3D NodeId; + } + + // + // Enable the Memory structure + // + if ((LegacyNodeId =3D=3D NodeId) || (!mSocketMemoryConfiguration.S= ratMemoryHotPlug) ) { + SratTable->Memory[TableIndex].Flags =3D EFI_ACPI_6_2_MEMORY_ENAB= LED; + } else { + SratTable->Memory[TableIndex].Flags =3D EFI_ACPI_6_2_MEMORY_ENAB= LED | EFI_ACPI_6_2_MEMORY_HOT_PLUGGABLE; + } + if (!DynamicSiLibraryProtocol2->IsMemTypeVolatile (mSystemMemoryMa= p->Element[Index].Type) && + !DynamicSiLibraryProtocol2->IsMemTypeFpga (mSystemMemoryMap->E= lement[Index].Type)) { + SratTable->Memory[TableIndex].Flags |=3D EFI_ACPI_6_2_MEMORY_NON= VOLATILE; + } + + if (Pass =3D=3D 2) { + DEBUG ((DEBUG_INFO, "%3d %08x%08x, %08x%08x %2x %x\n", + TableIndex, + SratTable->Memory[TableIndex].AddressBaseHigh, + SratTable->Memory[TableIndex].AddressBaseLow, + SratTable->Memory[TableIndex].LengthHigh, + SratTable->Memory[TableIndex].LengthLow, + SratTable->Memory[TableIndex].ProximityDomain, + SratTable->Memory[TableIndex].Flags)); + } + } + TableIndex++; + } + // + // Update LastDomainId for enabled sockets with no memory + // + NoMemSocketBitmap =3D mCpuCsrAccessVarPtr->socketPresentBitMap & ~MemS= ocketBitmap; + if (Pass =3D=3D 1) { + for (Socket =3D 0; Socket < MAX_SOCKET; Socket++) { + if ((BIT0 << Socket) & NoMemSocketBitmap) { + LastDomainId +=3D SncNumOfCluster; + } + } + } + } + + *LastIndexUsed =3D TableIndex; +} + +EFI_STATUS +PatchSratTable ( + IN OUT STATIC_RESOURCE_AFFINITY_TABLE *SratTable + ) +{ + UINT8 Index; + UINT8 NewIndex; + UINT16 ThreadIndex; // Support more= than 256 threads (8S case) + UINT8 NodeId; + UINTN HighTopMemory; + UINTN HotPlugBase; + UINTN HotPlugLen; + UINT8 SncEnabled; + UINT8 SncNumOfCluster; + + SncEnabled =3D mIioUds->IioUdsPtr->SystemStatus.OutSncEn; + SncNumOfCluster =3D mIioUds->IioUdsPtr->SystemStatus.OutNumOfCluster; + + if (mSystemMemoryMap !=3D NULL) { + if (mSystemMemoryMap->VirtualNumaEnable) { + if (SncEnabled) { + SncNumOfCluster =3D SncNumOfCluster * mSystemMemoryMap->VirtualNumOf= Cluster; + } else { + // + // If Virtual NUMA enabled without SNC, use the number of Virtual N= UMA clusters. + // Do not multiply by "OutNumOfCluster" if the system is in a UMA B= ased Clustering mode (e.g. Hemisphere). + // + SncNumOfCluster =3D mSystemMemoryMap->VirtualNumOfCluster; + SncEnabled =3D 1; + } + } + } + + if (SncNumOfCluster =3D=3D 0) { + SncNumOfCluster =3D 1; + } + + CollectThreadIdMsrData (SncEnabled, SncNumOfCluster); + + if (mSocketMemoryConfiguration.SratCpuHotPlug) { + PatchSratAllApicIds (SratTable); + } else { + DEBUG (( DEBUG_INFO, "-------- SRAT TABLE ---------- %x\n", PROCESSOR= _LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE_COUNT)); + + for (ThreadIndex =3D 0; ThreadIndex < PROCESSOR_LOCAL_APIC_SAPIC_AFFIN= ITY_STRUCTURE_COUNT; ThreadIndex++) { + if (ThreadIndex < mNumberOfCPUs) { + + // + // Use mCpuThreadIdMsrTable.ApicId by sorting SRAT sequentially to= fix proximity domain grouping of threads in OSes + // + if (mX2ApicEnabled) { + SratTable->x2Apic[ThreadIndex].ProximityDomain =3D GetProximityD= omainForSNC (mCpuThreadIdMsrTable[ThreadIndex].ApicId); + SratTable->x2Apic[ThreadIndex].X2ApicId =3D mCpuThreadIdMsrTable= [ThreadIndex].ApicId; + SratTable->x2Apic[ThreadIndex].Flags =3D EFI_ACPI_6_2_PROCESSOR_= LOCAL_APIC_SAPIC_ENABLED; + } else { + // + // If SNC is enabled and 2 clusters, there is 1 extra Proximity = Domain per socket + // SNC cannot exist unless all HA's have memory + // + SratTable->Apic[ThreadIndex].ProximityDomain7To0 =3D (UINT8)GetP= roximityDomainForSNC (mCpuThreadIdMsrTable[ThreadIndex].ApicId); + SratTable->Apic[ThreadIndex].ApicId =3D (UINT8)mCpuThreadIdMsrTa= ble[ThreadIndex].ApicId; + SratTable->Apic[ThreadIndex].Flags =3D EFI_ACPI_6_2_PROCESSOR_LO= CAL_APIC_SAPIC_ENABLED; + } + } else { + if (mX2ApicEnabled) { + SratTable->x2Apic[ThreadIndex].X2ApicId =3D (UINT32)-1; + } else { + SratTable->Apic[ThreadIndex].ApicId =3D 0xFF; + } + } + if (mX2ApicEnabled) { + DEBUG (( DEBUG_INFO, "\nSRAT: CpuThreadIndex\t%x, ApicId\t%x, F= lags\t%x!\n", + ThreadIndex, SratTable->x2Apic[ThreadIndex].X2ApicId, Srat= Table->x2Apic[ThreadIndex].Flags)); + } else { + DEBUG (( DEBUG_INFO, "\nSRAT: CpuThreadIndex\t%x, ApicId\t%x, F= lags\t%x, ProximityDomain\t%x!\n", + ThreadIndex, SratTable->Apic[ThreadIndex].ApicId, SratTabl= e->Apic[ThreadIndex].Flags, + SratTable->Apic[ThreadIndex].ProximityDomain7To0)); + } + } + } + + if (mSystemMemoryMap !=3D NULL) { + + PatchMemorySratEntries (SratTable, SncEnabled, SncNumOfCluster, &Index= ); + + HotPlugBase =3D 0x100; + if (mSocketMemoryConfiguration.MemoryHotPlugBase =3D=3D 0) { // Auto + // + // Read the actual TOHM and set it as the hot memory base + // + HighTopMemory =3D (UINT64)mIioUds->IioUdsPtr->SystemStatus.tohmLimi= t << 26; + HotPlugBase =3D (HighTopMemory >> 32); + if ((UINT32)HighTopMemory > 0) { + HotPlugBase++; + } + } else if (mSocketMemoryConfiguration.MemoryHotPlugBase) { // Number + HotPlugBase =3D mSocketMemoryConfiguration.MemoryHotPlugBase * 0x80; + } + HotPlugLen =3D (mSocketMemoryConfiguration.MemoryHotPlugLen + 1) * 0x1= 0; + + if (mSocketMemoryConfiguration.SratMemoryHotPlug) { + DEBUG (( DEBUG_INFO, "SRAT: Updating SRAT hotplug memory information= !\n" )); + for (NodeId =3D 0; NodeId < MC_MAX_NODE; NodeId++) { + NewIndex =3D Index + NodeId; + if (NewIndex >=3D MEMORY_AFFINITY_STRUCTURE_COUNT) { + ASSERT (0); + break; + } + // + // As the HOB has base addr in 1 GB chunks + // + SratTable->Memory[NewIndex].ProximityDomain =3D (NodeId >> 1); + SratTable->Memory[NewIndex].AddressBaseLow =3D 0; + SratTable->Memory[NewIndex].AddressBaseHigh =3D (UINT32)(HotPlugBa= se + NodeId * HotPlugLen); + SratTable->Memory[NewIndex].LengthLow =3D 0; + SratTable->Memory[NewIndex].LengthHigh =3D (UINT32)HotPlugLen; + SratTable->Memory[NewIndex].Flags =3D EFI_ACPI_6_2_MEMORY_ENABLED = | EFI_ACPI_6_2_MEMORY_HOT_PLUGGABLE; + + DEBUG ((DEBUG_INFO, "%3d %08x%08x %08x%08x %x %x\n", NewIndex, + SratTable->Memory[Index].AddressBaseHigh, + SratTable->Memory[Index].AddressBaseLow, + SratTable->Memory[Index].LengthHigh, + SratTable->Memory[Index].LengthLow, + SratTable->Memory[Index].ProximityDomain, + SratTable->Memory[NewIndex].Flags)); + } + } + // + // Copy SRAT memory affinity data to ACPI platform protocol + // + DEBUG ((DEBUG_INFO, "ACPI Platform Protocol - Memory Affinity Data upd= ated\n")); + ZeroMem (&mAcpiPlatformMemAffData, sizeof (mAcpiPlatformMemAffData)); + CopyMem (&mAcpiPlatformMemAffData.AcpiMemAffData[0], &SratTable->Memor= y[0], sizeof (mAcpiPlatformMemAffData.AcpiMemAffData)); + mAcpiPlatformMemAffData.AcpiMemAffDataValid =3D TRUE; + } + return EFI_SUCCESS; +} + + +/** + Routine Description: + Collect ThreadIdMsr Value for all the AP's and sorts it by the ThreadI= dMsr Value. + The Sorted Table, for every socket the first half of the threads will = be Mapped to 1st HA + The second half f threads in every socket will mapped to 2nd HA. + + Arguments: + NONE + + Returns: + NONE +**/ +VOID +CollectThreadIdMsrData ( + IN UINT8 SncEnabled, + IN UINT8 SncNumOfCluster + ) +{ + UINT32 SocketIndex; + UINT32 ThreadIndex; + UINTN NumOfChaPerCluster; + BOOLEAN CollocatedChaIdPresent; + UINT32 NumberOfThreads; + UINT8 SocketLogicalId; + + NumOfChaPerCluster =3D 0; + CollocatedChaIdPresent =3D FALSE; + AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, 0, NULL, &NumberOfThreads, NULL, NU= LL); + + // + // Get total number of CHAs per socket + // + for(SocketIndex =3D 0; SocketIndex < MAX_SOCKET; SocketIndex++) { + mPackageChaTotal[SocketIndex] =3D mIioUds->IioUdsPtr->PlatformData.Cpu= QpiInfo[SocketIndex].TotCha; + } + + // + // Determine whether collocated CHA ID is encoded in upper 32 bits of MS= R 0x53 LOGICAL_THREAD_ID + // + if (SncEnabled) { + for(ThreadIndex =3D 0; ThreadIndex < (MAX_CORE * MAX_THREAD); ThreadIn= dex++) { + if (mCpuThreadIdMsrTable[ThreadIndex].CollocatedChaId !=3D 0) { + if (mCpuThreadIdMsrTable[ThreadIndex].CollocatedChaId !=3D 0xFF) { + CollocatedChaIdPresent =3D TRUE; + } + break; + } + } + if (!CollocatedChaIdPresent) { + DEBUG ((DEBUG_WARN, "ERROR: Collocated CHA ID is not found! Correct = SNC Proximity Domain programming not guaranteed.\n")); + } + } + + // + // Set SNC Proximity Domain variables for each thread + // + for(ThreadIndex =3D 0; ThreadIndex < MAX_CPU_NUM; ThreadIndex++) { + if (mCpuThreadIdMsrTable[ThreadIndex].ThreadIdValue =3D=3D 0xff) { + continue; + } + + // + // We divide cores in group by number of clusters. + // CHA number is used instead of active threads to account for when co= res or + // threads are disabled. + // + SocketIndex =3D mCpuConfigLibConfigContextBuffer->CollectedDataBuffer[= ThreadIndex].ProcessorLocation.Package; + SocketLogicalId =3D GetSocketLogicalId ((UINT8) SocketIndex); + if (!SncEnabled) { + mCpuThreadIdMsrTable[ThreadIndex].SNCProximityDomain =3D SocketLogic= alId; + } else { + NumOfChaPerCluster =3D mPackageChaTotal[SocketIndex]/SncNumOfCluster; + if (CollocatedChaIdPresent) { + mCpuThreadIdMsrTable[ThreadIndex].SNCProximityDomain =3D (UINT32)(= (SocketLogicalId * SncNumOfCluster) + (mCpuThreadIdMsrTable[ThreadIndex].Co= llocatedChaId / (NumOfChaPerCluster))); + } else { + mCpuThreadIdMsrTable[ThreadIndex].SNCProximityDomain =3D (UINT32)(= (SocketLogicalId * SncNumOfCluster) + (mCpuThreadIdMsrTable[ThreadIndex].Th= readIdValue / (NumOfChaPerCluster*NumberOfThreads))); + } + DEBUG ((DEBUG_INFO, "ThreadIndex=3D%x, SncNumOfCluster=3D%x, NumOfCh= aPerCluster=3D%x, SNCProximityDomain=3D%x\n", ThreadIndex, SncNumOfCluster,= NumOfChaPerCluster, mCpuThreadIdMsrTable[ThreadIndex].SNCProximityDomain)); + DEBUG ((DEBUG_INFO, "ThreadIdValue=3D%x\n", mCpuThreadIdMsrTable[Thr= eadIndex].ThreadIdValue)); + } + } +} + +/** + Return the Domain Flag value of the specific APICID + Proximity Domain Flag + 0 Denotes upper half of the sorted thread needs to be mapped to 1st HA. + 1 Denotes lower half and mapped to 2nd HA + + @retval Proximity Domain Value for the thread within a Socket. +**/ +UINT32 +GetProximityDomainForSNC ( + IN UINT32 ApicId + ) +{ + UINT32 ThreadIndex =3D 0; + static UINT32 SncIndex =3D 0; + + // + // The ApicIds are in order. Saving the index will reduce loop iterations + // + for (ThreadIndex =3D SncIndex; ThreadIndex < MAX_CPU_NUM; ThreadIndex++)= { + if (mCpuThreadIdMsrTable[ThreadIndex].ApicId =3D=3D ApicId){ + SncIndex =3D ThreadIndex + 1; + return mCpuThreadIdMsrTable[ThreadIndex].SNCProximityDomain; + } else if (mCpuThreadIdMsrTable[ThreadIndex].ApicId =3D=3D (UINT32) -1= ) { + // + // We have reached the end of the populated threads + // + break; + } + } + + // + // Start again from the beginning if we made it to the end of the array + // + for (ThreadIndex =3D 0; ThreadIndex < MAX_CPU_NUM; ThreadIndex++) { + if (mCpuThreadIdMsrTable[ThreadIndex].ApicId =3D=3D ApicId){ + SncIndex =3D ThreadIndex + 1; + return mCpuThreadIdMsrTable[ThreadIndex].SNCProximityDomain; + } + } + + DEBUG ((DEBUG_ERROR, "APICID not found in CpuThreadIdMsrValueTable\n")); + ASSERT (FALSE); + ThreadIndex--; + return mCpuThreadIdMsrTable[ThreadIndex].SNCProximityDomain; +} + +/** + Function retrieves selected data of ACPI SRAT Memory Affinity Structures + (please note that data will not be available until SRAT table installati= on) + + @param[out] *MemAffData ACPI Memory Affinity Data + @param[out] *MemAffDataLength ACPI Memory Affinity Data Length + + @retval EFI_SUCCESS ACPI Memory Affinity Data retrieved succ= essfully + @retval EFI_NOT_FOUND ACPI Memory Affinity Data not found (SRA= T ACPI table was not published) + @retval EFI_INVALID_PARAMETER One or more of input arguments is NULL +**/ +EFI_STATUS +GetAcpiMemoryAffinityData ( + OUT ACPI_MEMORY_AFFINITY_DATA **MemAffData, + OUT UINTN *MemAffDataLength + ) +{ + if (MemAffData =3D=3D NULL || MemAffDataLength =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + if (!mAcpiPlatformMemAffData.AcpiMemAffDataValid) { + return EFI_NOT_FOUND; + } + + *MemAffData =3D mAcpiPlatformMemAffData.AcpiMemAffData; + *MemAffDataLength =3D (UINT8)MEMORY_AFFINITY_STRUCTURE_COUNT; + + return EFI_SUCCESS; +} + +/** + Function initialize and install ACPI Platform Protocol + + @param None + + @retval EFI_SUCCESS Operation completed successfully +**/ +EFI_STATUS +InstallAcpiPlatformProtocol ( + VOID + ) +{ + EFI_HANDLE Handle =3D NULL; + + ZeroMem (&mAcpiPlatformProtocol, sizeof(mAcpiPlatformProtocol)); + mAcpiPlatformProtocol.GetAcpiMemoryAffinityData =3D GetAcpiMemoryAffinit= yData; + + return gBS->InstallProtocolInterface (&Handle, &gAcpiPlatformProtocolGui= d, EFI_NATIVE_INTERFACE, &mAcpiPlatformProtocol); +} + +VOID +PrintSratTable ( + IN EFI_ACPI_DESCRIPTION_HEADER *Header + ) +{ + EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *Table; + EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE *SubType; + UINTN TotalLength; + UINT8 *TempPtr; + EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE *ApicType; + EFI_ACPI_6_2_MEMORY_AFFINITY_STRUCTURE *MemType; + EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTURE *x2ApicType; + UINTN TempLength; + + Table =3D (EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *) Header; + if (Table->Header.Signature !=3D EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_T= ABLE_SIGNATURE) { + DEBUG ((DEBUG_ERROR, "[SRAT] Not SRAT table, skip!\n")); + return; + } + + TotalLength =3D Table->Header.Length; + + DEBUG ((DEBUG_INFO, "----------------------------[SRAT Table] ----------= ----------\n")); + DEBUG ((DEBUG_INFO, "----Header-----\n")); + DEBUG ((DEBUG_INFO, "Length : %d\n", Table->Header.Length)); + DEBUG ((DEBUG_INFO, "Revision : %d\n", Table->Header.Revision)); + DEBUG ((DEBUG_INFO, "Checksum : %2X\n", Table->Header.Checksum)); + DEBUG ((DEBUG_INFO, "OemTableId : %X\n", Table->Header.OemTableId)= ); + DEBUG ((DEBUG_INFO, "OemRevision : %d\n", Table->Header.OemRevision= )); + DEBUG ((DEBUG_INFO, "CreatorId : %X\n", Table->Header.CreatorId)); + DEBUG ((DEBUG_INFO, "CreatorRevision : %X\n", Table->Header.CreatorRevi= sion)); + DEBUG ((DEBUG_INFO, "\n")); + + TempPtr =3D (UINT8 *)Table; + TempPtr +=3D sizeof(EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER); + TempLength =3D ((EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCT= URE *) TempPtr)->Length; + while (TempPtr < ((UINT8 *)Table + TotalLength)){ + SubType =3D (EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTUR= E *) TempPtr; + if (SubType->Type =3D=3D EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFIN= ITY) { + ApicType =3D SubType; + DEBUG ((DEBUG_INFO, "APIC Type : %d\n", ApicType->Type)); + DEBUG ((DEBUG_INFO, "Length : %d\n", ApicType->Length= )); + DEBUG ((DEBUG_INFO, "ProximityDomain7To0 : %d\n", ApicType->Proxim= ityDomain7To0)); + DEBUG ((DEBUG_INFO, "ApicId : %X\n", ApicType->ApicId= )); + DEBUG ((DEBUG_INFO, "Flags : %X\n", ApicType->Flags)= ); + DEBUG ((DEBUG_INFO, "LocalSapicEid : %d\n", ApicType->LocalS= apicEid)); + DEBUG ((DEBUG_INFO, "ProximityDomain31To8 : %d\n", (*(UINT32 *)Apic= Type->ProximityDomain31To8) & 0xFFFFFF)); + DEBUG ((DEBUG_INFO, "ClockDomain : %d\n", ApicType->ClockD= omain)); + + } else if (SubType->Type =3D=3D EFI_ACPI_6_2_MEMORY_AFFINITY) { + MemType =3D (EFI_ACPI_6_2_MEMORY_AFFINITY_STRUCTURE *)SubType; + DEBUG ((DEBUG_INFO, "Mem Type : %d\n", MemType->Type)); + DEBUG ((DEBUG_INFO, "Length : %d\n", MemType->Length)); + DEBUG ((DEBUG_INFO, "ProximityDomain : %d\n", MemType->ProximityDom= ain)); + DEBUG ((DEBUG_INFO, "AddressBaseLow : %X\n", MemType->AddressBaseL= ow)); + DEBUG ((DEBUG_INFO, "AddressBaseHigh : %X\n", MemType->AddressBaseH= igh)); + DEBUG ((DEBUG_INFO, "LengthLow : %X\n", MemType->LengthLow)); + DEBUG ((DEBUG_INFO, "LengthHigh : %X\n", MemType->LengthHigh)); + DEBUG ((DEBUG_INFO, "Flags : %X\n", MemType->Flags)); + + } else if (SubType->Type =3D=3D EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_AF= FINITY) { + x2ApicType =3D (EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTU= RE *) SubType; + DEBUG ((DEBUG_INFO, "x2APIC Type : %d\n", x2ApicType->Type)); + DEBUG ((DEBUG_INFO, "Length : %d\n", x2ApicType->Length)); + DEBUG ((DEBUG_INFO, "ProximityDomain : %d\n", x2ApicType->Proximity= Domain)); + DEBUG ((DEBUG_INFO, "X2ApicId : %X\n", x2ApicType->X2ApicId)= ); + DEBUG ((DEBUG_INFO, "Flags : %X\n", x2ApicType->Flags)); + DEBUG ((DEBUG_INFO, "ClockDomain : %d\n", x2ApicType->ClockDoma= in)); + + } else { + DEBUG ((DEBUG_INFO, "Unknown Type : %d\n", SubType->Type)); + DEBUG ((DEBUG_INFO, "Length : %d\n", SubType->Length)); + } + if (SubType->Length < 10) { + DEBUG ((DEBUG_ERROR, "Error in Length %d, try previous length.\n", S= ubType->Length)); + TempPtr +=3D TempLength; + } else { + TempPtr +=3D SubType->Length; + TempLength =3D SubType->Length; + } + DEBUG ((DEBUG_INFO, "\n")); + } +} + +/** + Build from scratch and install the SRAT. + + @retval EFI_SUCCESS The SRAT was installed successfully. + @retval EFI_OUT_OF_RESOURCES Could not allocate required structures. +**/ +EFI_STATUS +InstallSratTable ( + VOID + ) +{ + EFI_STATUS Status; + UINTN Index; + UINTN TableHandle; + UINTN TableSize; + STATIC_RESOURCE_AFFINITY_TABLE *SratTable; + + Status =3D EFI_SUCCESS; + TableHandle =3D 0; + + if (mSocketMemoryConfiguration.Srat =3D=3D 0) { + return EFI_SUCCESS; + } + + if (mSystemMemoryMap =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + SratTable =3D (STATIC_RESOURCE_AFFINITY_TABLE *) AllocateZeroPool (sizeo= f(STATIC_RESOURCE_AFFINITY_TABLE)); + if (SratTable =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "InstallSratTable: allocate SRAT table failed \n"= )); + return EFI_OUT_OF_RESOURCES; + } + + TableSize =3D sizeof (EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER= ) + + sizeof (EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STR= UCTURE) * PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE_COUNT + + sizeof (EFI_ACPI_6_2_MEMORY_AFFINITY_STRUCTURE) * MEMORY_AFF= INITY_STRUCTURE_COUNT + + sizeof (EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRUCTU= RE) * X2APIC_AFFINITY_STRUCTURE_COUNT ; + + SratTable->SratHeader =3D (EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_H= EADER *) AllocateZeroPool (TableSize); + if (SratTable->SratHeader =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "InstallSratTable: Create SratHeader has failed \= n")); + return EFI_OUT_OF_RESOURCES; + } + + SratTable->Apic =3D (EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_ST= RUCTURE *) (UINTN)((UINTN)SratTable->SratHeader + + (UINTN)sizeof(EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_= TABLE_HEADER)); + + SratTable->Memory =3D (EFI_ACPI_6_2_MEMORY_AFFINITY_STRUCTURE *) (UINTN)= ((UINTN)SratTable->Apic + + (UINTN)sizeof(EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPI= C_AFFINITY_STRUCTURE) * PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE_COUNT= ); + + SratTable->x2Apic =3D (EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_AFFINITY_STRU= CTURE *) (UINTN)((UINTN)SratTable->Memory + + (UINTN)sizeof(EFI_ACPI_6_2_MEMORY_AFFINITY_STRUCTURE= )* MEMORY_AFFINITY_STRUCTURE_COUNT); + + + SratTable->SratHeader->Header.Signature =3D EFI_ACPI_6_2_SYSTEM_RESOURCE= _AFFINITY_TABLE_SIGNATURE; + SratTable->SratHeader->Header.Length =3D (UINT32) TableSize; + SratTable->SratHeader->Header.Revision =3D EFI_ACPI_6_2_SYSTEM_RESOURCE_= AFFINITY_TABLE_REVISION; + CopyMem (SratTable->SratHeader->Header.OemId, PcdGetPtr (PcdAcpiDefaultO= emId), sizeof (SratTable->SratHeader->Header.OemId)); + SratTable->SratHeader->Header.OemTableId =3D PcdGet64 (PcdAcpiDefaultOem= TableId); + SratTable->SratHeader->Header.OemRevision =3D EFI_ACPI_OEM_SRAT_REVISION; + SratTable->SratHeader->Header.CreatorId =3D PcdGet32 (PcdAcpiDefaultCrea= torId); + SratTable->SratHeader->Header.CreatorRevision =3D PcdGet32 (PcdAcpiDefau= ltCreatorRevision); + + SratTable->SratHeader->Reserved1 =3D EFI_ACPI_SRAT_RESERVED_FOR_BACKWARD= _COMPATIBILITY; + SratTable->SratHeader->Reserved2 =3D EFI_ACPI_RESERVED_QWORD; + + for (Index =3D 0; Index < PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE_= COUNT; Index++) { + SratTable->Apic[Index].Type =3D EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPI= C_AFFINITY; + SratTable->Apic[Index].Length =3D sizeof(EFI_ACPI_6_2_PROCESSOR_LOCAL_= APIC_SAPIC_AFFINITY_STRUCTURE); + SratTable->Apic[Index].ApicId =3D 0xFF; + } + + for (Index =3D 0; Index < MEMORY_AFFINITY_STRUCTURE_COUNT; Index++) { + SratTable->Memory[Index].Type =3D EFI_ACPI_6_2_MEMORY_AFFINITY; + SratTable->Memory[Index].Length =3D sizeof(EFI_ACPI_6_2_MEMORY_AFFINIT= Y_STRUCTURE); + } + + for (Index =3D 0; Index < X2APIC_AFFINITY_STRUCTURE_COUNT; Index++) { + SratTable->x2Apic[Index].Type =3D EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_= AFFINITY; + SratTable->x2Apic[Index].Length =3D sizeof(EFI_ACPI_6_2_PROCESSOR_LOCA= L_X2APIC_AFFINITY_STRUCTURE); + SratTable->x2Apic[Index].X2ApicId =3D 0xFFFFFFFF; + } + + PatchSratTable (SratTable); + PrintSratTable (&SratTable->SratHeader->Header); + + // + // Publish SRAT Structure to ACPI + // + Status =3D mAcpiTable->InstallAcpiTable ( + mAcpiTable, + SratTable->SratHeader, + SratTable->SratHeader->Header.Length, + &TableHandle + ); + + + FreePool (SratTable->SratHeader); + FreePool (SratTable); + + InstallAcpiPlatformProtocol (); + + return Status; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLi= b/AcpiPlatformLibSsdt.c b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPl= atformTableLib/AcpiPlatformLibSsdt.c new file mode 100644 index 0000000000..cb8b2b24be --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/AcpiP= latformLibSsdt.c @@ -0,0 +1,1004 @@ +/** @file + ACPI Platform Driver Hooks + + @copyright + Copyright 1996 - 2020 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// Statements that include other files +// +#include "AcpiPlatformLibLocal.h" +#include + +extern BIOS_ACPI_PARAM *mAcpiParameter; +extern EFI_IIO_UDS_PROTOCOL *mIioUds; + +extern SOCKET_MEMORY_CONFIGURATION mSocketMemoryConfiguration; +extern SOCKET_POWERMANAGEMENT_CONFIGURATION mSocketPowermanagementConfigur= ation; + +extern BOOLEAN mCpuOrderSorted; +extern UINT32 mApicIdMap[MAX_SOCKET][MAX_CORE * MAX_THREAD]; +extern UINT32 mNumOfBitShift; + +extern UINT32 mEnabledProcessor[MAX_SOCKET]; + +extern EFI_CPU_CSR_ACCESS_PROTOCOL *mCpuCsrAccess; +UINT32 mCpuPCPSInfo[MAX_SOCKET]; +UINT32 mNcpuValue[MAX_SOCKET]; + +extern CPU_ID_ORDER_MAP mCpuApicIdOrderTable[]; +extern UINT8 mPStateEnable; + +#ifndef MSR_MISC_ENABLES +#define MSR_MISC_ENABLES 0x01A0 +#endif + +/** + This function detects PCPS Info + + mCpuPCPSInfo usage: + Bit[15:0]: Enabled processors in current socket + Bit[16]: Hyperthreading enable + Bit[17]: PCPS disable in system + + @param None + + @retval VOID + +**/ +VOID +DetectPcpsInfo ( + VOID + ) +{ + UINT8 Socket; + UINT32 CpuPCPSInfo =3D 0; + UINT32 SmtDisable =3D 0; + UINT32 Csr; + + EFI_STATUS Status =3D EFI_SUCCESS; + DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &= DynamicSiLibraryProtocol2); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return; + } + + for (Socket =3D 0; Socket < MAX_SOCKET; Socket++) { + if (mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].Valid) { + SmtDisable =3D DynamicSiLibraryProtocol2->PcuGetDesiredCoreSmtDis (S= ocket); + + Csr =3D mCpuCsrAccess->ReadCpuCsr (Socket, 0, 0x04320084); + + if (!SmtDisable && !(Csr & (1 << 12))) { + mCpuPCPSInfo[Socket] |=3D B_PCPS_HT_ENABLE; + } + CpuPCPSInfo =3D mCpuPCPSInfo[Socket]; + + // + // Update NCPU + // + mNcpuValue[Socket] =3D mCpuPCPSInfo[Socket] & 0xFF; + + if (((CpuPCPSInfo & B_PCPS_DISABLE) =3D=3D 0)) { + if (CpuPCPSInfo & B_PCPS_HT_ENABLE) { + mNcpuValue[Socket] =3D 2; + } else { + mNcpuValue[Socket] =3D 1; + } + } + } + } + + for (Socket =3D 0; Socket < MAX_SOCKET; Socket++) { + if (mCpuPCPSInfo[Socket] =3D=3D 0) { + mCpuPCPSInfo[Socket] =3D CpuPCPSInfo; + mNcpuValue[Socket] =3D mNcpuValue[0]; + } + } +} + +/** + Find APICID in mCpuApicIdOrderTable + + @param SocketIndex - In: Acpi thread number + @param ThreadIndex - In: Acpi thread number + + @retval APICID - If not found, return 0xFFFFFFFF +**/ +UINT32 +LocateApicIdInfo ( + IN UINT32 SocketIndex, + IN UINT32 ThreadIndex + ) +{ + if (mApicIdMap[SocketIndex][ThreadIndex] =3D=3D (UINT32) -1) { + return (UINT32) -1; + } + + return (mApicIdMap[SocketIndex][ThreadIndex] + (SocketIndex << mNumOfBit= Shift)); +} + +/** + Gather the EIST information + + @param ThreadId - In: Acpi thread number + @param CpuMiscData - In/Out: Pointer to thread's CPU_MISC_DTAT struct + + @retval EFI_SUCCESS - EIST info retrieved +**/ +EFI_STATUS +LocateCpuEistInfo ( + IN UINT32 CpuIndex, + OUT CPU_MISC_DATA **CpuMiscData + ) +{ + UINTN Index; + UINT32 Socket; + UINT32 ApicId; + const UINT32 *ApicMapPtr; + + Socket =3D CpuIndex / (MAX_CORE * MAX_THREAD); + Index =3D CpuIndex % (MAX_CORE * MAX_THREAD); + ApicMapPtr =3D mApicIdMap[Socket]; + + ApicId =3D mAcpiParameter->ProcessorApicIdBase[Socket] + ApicMapPtr[Inde= x]; + + for (Index =3D 0; Index < mCpuConfigLibConfigContextBuffer->NumberOfProc= essors; ++Index) { + if (mCpuConfigLibConfigContextBuffer->CollectedDataBuffer[Index].CpuMi= scData.ApicID =3D=3D ApicId) { + *CpuMiscData =3D &mCpuConfigLibConfigContextBuffer->CollectedDataBuf= fer[Index].CpuMiscData; + break; + } + } + + if (*CpuMiscData =3D=3D NULL) { //use SBSP's data + *CpuMiscData =3D &mCpuConfigLibConfigContextBuffer->CollectedDataBuffe= r[0].CpuMiscData; + } + + return EFI_SUCCESS; +} + +/** + Determine turbo mode status + + @param None + + @retval TRUE if turbo enabled, FALSE if disabled +**/ +BOOLEAN +IsTurboModeEnabled ( + VOID + ) +{ + EFI_CPUID_REGISTER CpuidRegisters; + BOOLEAN Status; + UINT64 MiscEnable; + + Status =3D FALSE; + AsmCpuid (CPUID_THERMAL_POWER_MANAGEMENT, &CpuidRegisters.RegEax, &Cpuid= Registers.RegEbx, &CpuidRegisters.RegEcx, &CpuidRegisters.RegEdx); + if (((CPUID_THERMAL_POWER_MANAGEMENT_EAX*)&CpuidRegisters.RegEax)->Bits.= TurboBoostTechnology !=3D 0) { + // + // Turbo mode is supported on this processor (Available) + // + + MiscEnable =3D AsmReadMsr64 (MSR_MISC_ENABLES); + if ((RShiftU64 (MiscEnable, 38) & 1) =3D=3D 0) { // Bit 38 is TurboMod= eDisable + // + // Turbo mode is supported on this processor (Available) + // + Status =3D TRUE; + } + } + + return Status; +} + +/** + Finds the actual beginning of a CPU SSDT table, skips the If(Zero) { Ext= ernal() ... } opcode + auto-generated by the iASL 6.1 compiler + + From iASL/6.1/changes.txt + "Completed full support for the ACPI 6.0 External() AML opcode. The + compiler emits an external AML opcode for each ASL External statement. + This opcode is used by the disassembler to assist with the disassembly of + external control methods by specifying the required number of arguments + for the method. AML interpreters do not use this opcode. To ensure that + interpreters do not even see the opcode, a block of one or more external + opcodes is surrounded by an "If(0)" construct. As this feature becomes + commonly deployed in BIOS code, the ability of disassemblers to correctly + disassemble AML code will be greatly improved." + + The AML code contains external (_SB_SCKxCyyy) opcodes within a If(Zero) = statement; + we have to ignore this opcodes and start patching from the actual table = begin marker, i.e., "TBST" + + @param[in] BeginPtr a pointer to the begin of a SSDT table + @param[in] EndPtr a pointer to the end of a SSDT table + + @retval beginning of the part of SSDT table past external _SB_ opc= odes +**/ +static inline +UINT8 * +SkipExternalSbOpcodes( + IN UINT8 *BeginPtr, + IN UINT8 *EndPtr, + IN UINT32 ExternSbExpected + ) +{ + UINT8 *CurPtr =3D BeginPtr; + UINT32 ExternSbFound =3D 0; + + ASSERT (BeginPtr < EndPtr); + + DEBUG ((DEBUG_VERBOSE, "SkipExternalSbOpcodes start\n")); + + for (CurPtr =3D BeginPtr; CurPtr < EndPtr; ++CurPtr) { + UINT32 Signature =3D *(UINT32 *) CurPtr; + + if (SIGNATURE_32 ('_', 'S', 'B', '_') =3D=3D Signature) { + CONST EXTERNAL_OBJECT_DECL *ExternDecl =3D ACPI_EXTERNAL_OBJECT_DECL= _FROM_NAME_STR (CurPtr); + + ASSERT (BeginPtr < (UINT8 *)ExternDecl); + + if ((AML_EXTERNAL_OP =3D=3D ExternDecl->ExternalOp ) && + (AML_ROOT_CHAR =3D=3D ExternDecl->RootChar) && + (AML_MULTI_NAME_PREFIX =3D=3D ExternDecl->MultiNamePrefix) && + (0x3 <=3D ExternDecl->SegCount)) { + ++ExternSbFound; + } else { + break; + } + } + } + + DEBUG ((DEBUG_ERROR, "ExternSbExpected: %d, ExternSbFound: %d\n")); + + ASSERT ((ExternSbFound % ExternSbExpected) =3D=3D 0); + + DEBUG ((DEBUG_VERBOSE, "SkipExternalSbOpcodes end\n")); + + return CurPtr; +} + +/** + Update the CPU PM SSDT table + + @param[in,out] TableHeader The table to be set + + @retval EFI_SUCCESS Returns Success + @retval EFI_UNSUPPORTED Table is not supported +**/ +EFI_STATUS +PatchCpuPmSsdtTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + UINT8 *CurrPtr; + UINT8 *EndPtr; + UINT8 *SsdtPointer; + UINT32 Signature; + UINT32 CpuFixes; + UINT32 CpuSkt; + UINT32 CpuIndex; + UINT32 ThreadIndex; + UINT32 AdjustSize; + ACPI_NAMEPACK_DWORD *NamePtr; + UINT32 DomnValue; + ACPI_NAME_COMMAND *PsdPackage; + PSD_PACKAGE_LAYOUT *PsdPackageItemPtr; + CPU_MISC_DATA *CpuMiscData; + + DEBUG ((DEBUG_INFO, "Patching SSDT PatchCpuPmSsdtTable\n")); + + // + // Loop through the ASL looking for values that we must fix up. + // + DomnValue =3D 0; + CpuFixes =3D 0; + CpuSkt =3D 0; + CpuIndex =3D 0; + ThreadIndex =3D 0; + CurrPtr =3D (UINT8 *) Table; + EndPtr =3D (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); + CpuMiscData =3D NULL; + + DetectPcpsInfo (); + + // + // CurrPtr =3D beginning of table to search + // + CurrPtr =3D SkipExternalSbOpcodes (CurrPtr, EndPtr, (UINT32) MAX_CPU_NUM= ); + + // + // Subtract 11 from EndPtr - this is the size of the largest data item w= e will search for + // so that we do not try to read past the end of the table + // + EndPtr -=3D 11; + + for (SsdtPointer =3D CurrPtr; SsdtPointer <=3D EndPtr; ++SsdtPointer) { + Signature =3D *(UINT32 *) SsdtPointer; + CpuIndex =3D 0; + AdjustSize =3D 0; + + switch (Signature) { + + // + // The AML code contains strings in the form of _SB_SCKxCyyy where x i= s the socket number + // and yyy is the thread number in hexadecimal, this first case parses= that string and saves + // the socket number into CpuSkt and the thread number into CpuIndex. + // + case SIGNATURE_32 ('_', 'S', 'B', '_'): + // + // SKTX + // + CpuSkt =3D *(SsdtPointer + 7); + if ((CpuSkt < '0') || ((CpuSkt - '0') > MAX_SOCKET)) { + CpuSkt =3D '0'; + } + CpuSkt -=3D '0'; + + if ((*(SsdtPointer + 8) !=3D 'C')) { + continue; + } + + if ((*(SsdtPointer + 11) > '0') && (*(SsdtPointer + 11) <=3D '9')) { + CpuIndex =3D (*(SsdtPointer + 11) -'0'); + } else if ((*(SsdtPointer + 11) >=3D 'A') && (*(SsdtPointer + 11) <= =3D 'F')) { + CpuIndex =3D (*(SsdtPointer + 11) -'A' + 10); + } + + if ((*(SsdtPointer + 10) > '0') && ( *(SsdtPointer + 10) <=3D '9')) { + AdjustSize =3D (*(SsdtPointer + 10) -'0') * 0x10; + } else if ((*(SsdtPointer + 10) >=3D 'A') && (*(SsdtPointer + 10) <= =3D 'F')) { + AdjustSize =3D (*(SsdtPointer + 10) -'A' + 10) * 0x10; + } + + CpuIndex +=3D AdjustSize; + AdjustSize =3D 0; + + if ((*(SsdtPointer + 9) > '0') && (*(SsdtPointer + 9) <=3D '9')) { + AdjustSize =3D (*(SsdtPointer + 9) -'0') * 0x100; + } else if ((*(SsdtPointer + 9) >=3D 'A') && (*(SsdtPointer + 9) <=3D= 'F')) { + AdjustSize =3D (*(SsdtPointer + 9) -'A' + 10) * 0x100; + } + + CpuIndex +=3D AdjustSize; + ThreadIndex =3D CpuIndex; + + // + // PCPS - Update DOMN + // + DomnValue =3D (UINT8) CpuSkt; + + if ((mCpuPCPSInfo[CpuSkt] & B_PCPS_DISABLE) =3D=3D 0) { + DomnValue =3D LocateApicIdInfo (CpuSkt, ThreadIndex); + + if (mNcpuValue[CpuSkt] =3D=3D 2) { + DomnValue =3D (DomnValue >> 1); + } + } + + DEBUG (( + DEBUG_INFO, + ":ACPI: PatchCpuPmSsdtTable(): CpuSkt: %d ThreadIndex: %d, NcpuVal= ue: %d, DomnValue: %d\n", + CpuSkt, + ThreadIndex, + mNcpuValue[CpuSkt], + DomnValue + )); + ++CpuFixes; + CpuMiscData =3D NULL; + LocateCpuEistInfo (0, &CpuMiscData); // use CPU0 for update NPSS an= d SPSS + break; + + case SIGNATURE_32 ('D', 'O', 'M', 'N'): + NamePtr =3D ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (SsdtPointer); + if (NamePtr->StartByte !=3D AML_NAME_OP) { + continue; + } + + if (NamePtr->Size !=3D AML_NAME_DWORD_SIZE) { + continue; + } + + NamePtr->Value =3D DomnValue; + break; + + case SIGNATURE_32 ('N', 'C', 'P', 'U'): + NamePtr =3D ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (SsdtPointer); + if (NamePtr->StartByte !=3D AML_NAME_OP) { + continue; + } + + if (NamePtr->Size !=3D AML_NAME_DWORD_SIZE) { + continue; + } + + NamePtr->Value =3D (UINT32) mNcpuValue[CpuSkt]; + break; + + case SIGNATURE_32 ('P', 'S', 'D', 'C'): + case SIGNATURE_32 ('P', 'S', 'D', 'E'): + PsdPackage =3D ACPI_NAME_COMMAND_FROM_NAME_STR (SsdtPointer); + if (PsdPackage->StartByte !=3D AML_NAME_OP) { + continue; + } + + PsdPackageItemPtr =3D (PSD_PACKAGE_LAYOUT *) ((UINT8 *) PsdPac= kage); + DEBUG (( + DEBUG_VERBOSE, + "PatchCpuPmSsdtTable(): PsdPackageItemPtr table: %x is detected...= \n", + PsdPackage->NameStr + )); + DEBUG (( + DEBUG_VERBOSE, + " Initial Values: Domain =3D %x, CoordType =3D %x, NumP= rocessors =3D %x\n", + PsdPackageItemPtr->Domain, + PsdPackageItemPtr->CoordType, + PsdPackageItemPtr->NumProcessors + )); + + PsdPackageItemPtr->Domain =3D DomnValue; + PsdPackageItemPtr->NumProcessors =3D (UINT32) mNcpuValue[CpuSkt]; + DEBUG (( + DEBUG_VERBOSE, + " PsdPackage =3D %x, PsdPackageItemPtr =3D %x, SsdtPointer = =3D %x\n", + (UINT8 *)PsdPackage, + (UINT8 *)PsdPackageItemPtr, + (UINT8 *)SsdtPointer + )); + DEBUG (( + DEBUG_VERBOSE, + " Updated PSD Domain =3D %x, CoordType =3D %x, NumProcessor= s =3D %x\n", + PsdPackageItemPtr->Domain, + PsdPackageItemPtr->CoordType, + PsdPackageItemPtr->NumProcessors + )); + break; + + default: + break; + } // switch + } // for + + // + // N fixes together currently + // + ASSERT (CpuFixes =3D=3D (UINT32) MAX_CPU_NUM); + + return EFI_SUCCESS; +} + +/** + + Update the OEM1 P-State SSDT table (EIST) + + @param *TableHeader - The table to be set + + @retval EFI_SUCCESS - Returns Success + +**/ +EFI_STATUS +PatchOem1SsdtTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + EFI_STATUS Status; + UINT8 *CurrPtr; + UINT8 *EndPtr; + UINT8 *SsdtPointer; + UINT32 Signature; + UINT32 CpuFixes; + UINT32 NpssFixes; + UINT32 GpssFixes; + UINT32 CpuSkt; + UINT32 CpuIndex; + UINT32 ThreadIndex; + UINT32 PackageSize; + UINT32 NewPackageSize; + UINT32 AdjustSize; + UINTN TableIndex; + ACPI_NAME_COMMAND *PssTable; + PSS_PACKAGE *PssTableItemPtr; + CPU_MISC_DATA *CpuMiscData; + FVID_ENTRY *PssState; + + DEBUG ((DEBUG_INFO, "Patching SSDT PatchOem1SsdtTable\n")); + + // + // Loop through the ASL looking for values that we must fix up. + // + NpssFixes =3D 0; + GpssFixes =3D 0; + CpuFixes =3D 0; + CpuSkt =3D 0; + CpuIndex =3D 0; + ThreadIndex =3D 0; + CurrPtr =3D (UINT8 *) Table; + EndPtr =3D (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); + CpuMiscData =3D NULL; + + Status =3D LocateCpuEistInfo (0, &CpuMiscData); // get BSP's data + if( (EFI_ERROR (Status)) || (CpuMiscData =3D=3D NULL ) ){ + DEBUG ((DEBUG_WARN, " PatchGv3SsdtTable - EIST info for BSP index not = found \n")); + return Status; + } + + mPStateEnable =3D 1; + + // + // CurrPtr =3D beginning of table to search + // + CurrPtr =3D SkipExternalSbOpcodes (CurrPtr, EndPtr, (UINT32) MAX_CPU_NUM= ); + + // + // Subtract 11 from EndPtr - this is the size of the larget data item we= will search for + // so that we do not try to read past the end of the table + // + EndPtr -=3D 11; + + for (SsdtPointer =3D CurrPtr; SsdtPointer <=3D EndPtr; ++SsdtPointer) { + Signature =3D *(UINT32 *) SsdtPointer; + CpuIndex =3D 0; + AdjustSize =3D 0; + + switch (Signature) { + case SIGNATURE_32 ('_', 'S', 'B', '_'): + // + // SKTX + // + CpuSkt =3D *(SsdtPointer + 7); + if ((CpuSkt < '0') || ((CpuSkt - '0') > MAX_SOCKET)) { + CpuSkt =3D '0'; + } + + CpuSkt -=3D '0'; + + if ((*(SsdtPointer + 11) > '0') && (*(SsdtPointer + 11) <=3D '9'))= { + CpuIndex =3D (*(SsdtPointer + 11) -'0'); + } else if ((*(SsdtPointer + 11) >=3D 'A') && (*(SsdtPointer + 11) = <=3D 'F')) { + CpuIndex =3D (*(SsdtPointer + 11) -'A' + 10); + } + + if ((*(SsdtPointer + 10) > '0') && ( *(SsdtPointer + 10) <=3D '9')= ) { + AdjustSize =3D (*(SsdtPointer + 10) -'0') * 0x10; + } else if ((*(SsdtPointer + 10) >=3D 'A') && (*(SsdtPointer + 10) = <=3D 'F')) { + AdjustSize =3D (*(SsdtPointer + 10) -'A' + 10) * 0x10; + } + + CpuIndex +=3D AdjustSize; + AdjustSize =3D 0; + + if ((*(SsdtPointer + 9) > '0') && (*(SsdtPointer + 9) <=3D '9')) { + AdjustSize =3D (*(SsdtPointer + 9) -'0') * 0x100; + } else if ((*(SsdtPointer + 9) >=3D 'A') && (*(SsdtPointer + 9) <= =3D 'F')) { + AdjustSize =3D (*(SsdtPointer + 9) -'A' + 10) * 0x100; + } + + CpuIndex +=3D AdjustSize; + ThreadIndex =3D CpuIndex; + + ++CpuFixes; + CpuMiscData =3D NULL; + LocateCpuEistInfo (0, &CpuMiscData); // use CPU0 for update NPSS = and SPSS + break; + + case SIGNATURE_32 ('N', 'P', 'S', 'S'): + case SIGNATURE_32 ('S', 'P', 'S', 'S'): + + PssTable =3D ACPI_NAME_COMMAND_FROM_NAME_STR (SsdtPointer); + if (PssTable->StartByte !=3D AML_NAME_OP) { + continue; + } + + ASSERT (CpuMiscData !=3D NULL); + PssState =3D CpuMiscData->FvidTable; + + AdjustSize =3D PssTable->NumEntries * sizeof (PSS_PACKAGE); + AdjustSize -=3D (UINT32)(CpuMiscData->NumberOfPStates * sizeof (PS= S_PACKAGE)); + PackageSize =3D (PssTable->Size & 0xF) + ((PssTable->Size & 0x= FF00) >> 4); + NewPackageSize =3D PackageSize - AdjustSize; + PssTable->Size =3D (UINT16) ((NewPackageSize & 0xF) + ((NewPackag= eSize & 0x0FF0) << 4)); + + // + // Set most significant two bits of byte zero to 01, meaning two b= ytes used + // + PssTable->Size |=3D 0x40; + + // + // Set unused table to Noop Code + // + SetMem ( + (UINT8 *) PssTable + NewPackageSize + AML_NAME_PREFIX_SIZE, + AdjustSize, + AML_NOOP_OP + ); + PssTable->NumEntries =3D (UINT8) CpuMiscData->NumberOfPStates; + PssTableItemPtr =3D (PSS_PACKAGE *) ((UINT8 *) PssTable + si= zeof (ACPI_NAME_COMMAND)); + + // + // Update the size + // + + if (CpuMiscData->NumberOfPStates =3D=3D 1) { + mPStateEnable =3D 0; + } + + for (TableIndex =3D 0; TableIndex < CpuMiscData->NumberOfPStates; = ++TableIndex) { + PssTableItemPtr->CoreFreq =3D (UINT32) (CpuMiscData->IntendedFsb= Frequency * PssState[TableIndex].Ratio); + if (mSocketPowermanagementConfiguration.TurboMode && (TableIndex= =3D=3D 0) && IsTurboModeEnabled ()) { + PssTableItemPtr->CoreFreq =3D (UINT32)((CpuMiscData->IntendedF= sbFrequency * PssState[TableIndex + 1].Ratio) + 1); + } + + + PssTableItemPtr->Power =3D (UINT32)(PssState[TableIndex].Pow= er); // when calulate Tdp already make it mW; + if (PssTable->NameStr =3D=3D SIGNATURE_32 ('N', 'P', 'S', 'S')) { + PssTableItemPtr->TransLatency =3D (UINT32)(PssState[TableIndex= ].TransitionLatency); + PssTableItemPtr->Control =3D (UINT32)(PssState[TableIndex].= Ratio << 8); + PssTableItemPtr->Status =3D (UINT32)(PssState[TableIndex].= Ratio << 8); + } else { + // + // This method should be supported by SMM PPM Handler + // + // Status is simply the state number. + // Use the state number w/ OS command value so that the + // legacy interface may be used. Latency for SMM is 100 + BM = latency. + PssTableItemPtr->Status =3D (UINT32)TableIndex; + PssTableItemPtr->TransLatency =3D (UINT32)(100 + PssState[Tabl= eIndex].TransitionLatency); + PssTableItemPtr->Control =3D (UINT32)(SW_SMI_OS_REQUEST | (Ta= bleIndex << 8)); + } + + PssTableItemPtr->BMLatency =3D (UINT32)(PssState[TableIndex].= BusMasterLatency); + + ++PssTableItemPtr; + } + + if (PssTable->NameStr =3D=3D SIGNATURE_32 ('N', 'P', 'S', 'S')) { + ++NpssFixes; + } + + SsdtPointer =3D (UINT8 *) PssTable + PackageSize; + break; + + case SIGNATURE_32 ('G', 'P', 'S', 'S'): + + PssTable =3D ACPI_NAME_COMMAND_FROM_NAME_STR (SsdtPointer); + if (PssTable->StartByte !=3D AML_NAME_OP) { + continue; + } + + ASSERT (CpuMiscData !=3D NULL); + PssState =3D CpuMiscData->GreaterFvidTable; + + ASSERT (CpuMiscData->GreaterNumberOfPStates <=3D GPSS_FVID_MAX_STA= TES); + if (CpuMiscData->GreaterNumberOfPStates > GPSS_FVID_MAX_STATES) { + continue; + } + + AdjustSize =3D PssTable->NumEntries * sizeof (PSS_PACKAGE); + AdjustSize -=3D (UINT32)(CpuMiscData->GreaterNumberOfPStates * siz= eof (PSS_PACKAGE)); + PackageSize =3D (PssTable->Size & 0xF) + ((PssTable->Size & 0x= FF00) >> 4); + NewPackageSize =3D PackageSize - AdjustSize; + PssTable->Size =3D (UINT16) ((NewPackageSize & 0xF) + ((NewPackag= eSize & 0x0FF0) << 4)); + + // + // Set most significant two bits of byte zero to 01, meaning two b= ytes used + // + PssTable->Size |=3D 0x40; + + // + // Set unused table to Noop Code + // + SetMem ( + (UINT8 *) PssTable + NewPackageSize + AML_NAME_PREFIX_SIZE, + AdjustSize, + AML_NOOP_OP + ); + PssTable->NumEntries =3D (UINT8) CpuMiscData->GreaterNumberOfPSta= tes; + PssTableItemPtr =3D (PSS_PACKAGE *) ((UINT8 *) PssTable + si= zeof (ACPI_NAME_COMMAND)); + + // + // Update the size + // + for (TableIndex =3D 0; TableIndex < CpuMiscData->GreaterNumberOfPS= tates; ++TableIndex) { + PssTableItemPtr->CoreFreq =3D (UINT32) (CpuMiscData->IntendedFsb= Frequency * PssState[TableIndex].Ratio); + if (mSocketPowermanagementConfiguration.TurboMode && (TableIndex= =3D=3D 0) && IsTurboModeEnabled()) { + PssTableItemPtr->CoreFreq =3D (UINT32)((CpuMiscData->IntendedF= sbFrequency * PssState[TableIndex + 1].Ratio) + 1); + } + + // + // If Turbo mode is supported, add one to the Max Non-Turbo freq= uency + // + PssTableItemPtr->Power =3D (UINT32)(PssState[TableIndex].Power);= // when calulate Tdp already make it mW; + if (PssTable->NameStr =3D=3D SIGNATURE_32 ('G', 'P', 'S', 'S')) { + PssTableItemPtr->TransLatency =3D (UINT32)(PssState[TableIndex= ].TransitionLatency); + PssTableItemPtr->Control =3D (UINT32)(PssState[TableIndex].Ra= tio << 8); + PssTableItemPtr->Status =3D (UINT32)(PssState[TableIndex].Ra= tio << 8); + } else { + // + // This method should be supported by SMM PPM Handler + // + // Status is simply the state number. + // Use the state number w/ OS command value so that the + // legacy interface may be used. Latency for SMM is 100 + BM = latency. + // + PssTableItemPtr->Status =3D (UINT32)TableIndex; + PssTableItemPtr->TransLatency =3D (UINT32)(100 + PssState[Tabl= eIndex].TransitionLatency); + PssTableItemPtr->Control =3D (UINT32)(SW_SMI_OS_REQUEST | (Ta= bleIndex << 8)); + } + + PssTableItemPtr->BMLatency =3D (UINT32)(PssState[TableIndex].= BusMasterLatency); + + ++PssTableItemPtr; + } + + if (PssTable->NameStr =3D=3D SIGNATURE_32 ('G', 'P', 'S', 'S')) { + ++GpssFixes; + } + + SsdtPointer =3D (UINT8 *) PssTable + PackageSize; + break; + + default: + break; + } // switch + } // for + + // + // N fixes together currently + // + ASSERT (CpuFixes =3D=3D (UINT32) MAX_CPU_NUM); + + if (!mPStateEnable || !mSocketPowermanagementConfiguration.ProcessorEist= Enable || (mSocketPowermanagementConfiguration.ProcessorHWPMEnable > HWP_MO= DE_NATIVE) ) { + Status =3D EFI_UNSUPPORTED; //CPU EIST + return Status; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +PatchSsdtTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table, + IN OUT EFI_ACPI_TABLE_VERSION *Version + ) +{ + EFI_STATUS Status; + EFI_ACPI_DESCRIPTION_HEADER *TableHeader; + + Status =3D EFI_SUCCESS; + TableHeader =3D (EFI_ACPI_DESCRIPTION_HEADER *)Table; + + // + // Do not load the xHCI table. It is handled by separate function. + // + TableHeader =3D (EFI_ACPI_DESCRIPTION_HEADER *) Table; + if (CompareMem (&TableHeader->OemTableId, "xh_", 3) =3D=3D 0) { + DEBUG ((DEBUG_ERROR,"Xhci TableHeader->OemTableId =3D %x\n ", TableH= eader->OemTableId)); + *Version =3D EFI_ACPI_TABLE_VERSION_NONE; + } + + if (TableHeader->OemTableId =3D=3D SIGNATURE_64 ('S', 'S', 'D', 'T', '= ', ' ', 'P', 'M')) { + PatchCpuPmSsdtTable (Table); //CPU PM + } + + return Status; +} + +/** + Update the OEM2 HWP SSDT table if needed + + @param *TableHeader - The table to be set + + @retval EFI_SUCCESS - Returns Success +**/ +EFI_STATUS +PatchOem2SsdtTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + EFI_STATUS Status =3D EFI_SUCCESS; + + if ((mSocketPowermanagementConfiguration.ProcessorHWPMEnable =3D=3D 0) |= | (mSocketPowermanagementConfiguration.ProcessorHWPMEnable =3D=3D HWP_MODE_= OOB)) { + Status =3D EFI_UNSUPPORTED; + } + + return Status; +} + +/** + Update the OEM3 T-State SSDT table (TST) + + @param *TableHeader - The table to be set + + @retval EFI_SUCCESS - Returns Success +**/ +EFI_STATUS +PatchOem3SsdtTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + UINT8 *CurrPtr; + UINT8 *EndPtr; + UINT8 *SsdtPointer; + UINT32 Signature; + UINT32 CpuFixes; + UINT32 CpuSkt; + UINT32 CpuIndex; + UINT32 ThreadIndex; + UINT32 AdjustSize; + UINT32 DomnValue; + ACPI_NAME_COMMAND *PsdPackage; + PSD_PACKAGE_LAYOUT *PsdPackageItemPtr; + + DEBUG ((DEBUG_INFO, "Patching SSDT PatchOem3SsdtTable\n")); + + if (!mSocketPowermanagementConfiguration.TStateEnable || (mSocketPowerma= nagementConfiguration.ProcessorHWPMEnable > HWP_MODE_NATIVE) ) { + return EFI_UNSUPPORTED; + } + + // + // Loop through the ASL looking for values that we must fix up. + // + DomnValue =3D 0; + CpuFixes =3D 0; + CpuSkt =3D 0; + ThreadIndex =3D 0; + CurrPtr =3D (UINT8 *) Table; + EndPtr =3D (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); + + // + // CurrPtr =3D beginning of table we want to search + // + CurrPtr =3D SkipExternalSbOpcodes(CurrPtr, EndPtr, (UINT32) MAX_CPU_NUM); + + // + // Subtract 11 from EndPtr - this is the size of the larget data item we= will read + // so that we don't read beyond the end of the table + // + EndPtr -=3D 11; + + for (SsdtPointer =3D CurrPtr; SsdtPointer <=3D EndPtr; ++SsdtPointer) { + Signature =3D *(UINT32 *) SsdtPointer; + CpuIndex =3D 0; + AdjustSize =3D 0; + + switch (Signature) { + + case SIGNATURE_32 ('_', 'S', 'B', '_'): + // + // SKTX + // + CpuSkt =3D *(SsdtPointer + 7); + CpuSkt -=3D '0'; + + if ((*(SsdtPointer + 8) !=3D 'C')) { + continue; + } + + if ((*(SsdtPointer + 11) > '0') && (*(SsdtPointer + 11) <=3D '9')) { + CpuIndex =3D (*(SsdtPointer + 11) -'0'); + } else if ((*(SsdtPointer + 11) >=3D 'A') && (*(SsdtPointer + 11) <= =3D 'F')) { + CpuIndex =3D (*(SsdtPointer + 11) -'A' + 10); + } + + if ((*(SsdtPointer + 10) > '0') && ( *(SsdtPointer + 10) <=3D '9')) { + AdjustSize =3D (*(SsdtPointer + 10) -'0') * 0x10; + } else if ((*(SsdtPointer + 10) >=3D 'A') && (*(SsdtPointer + 10) <= =3D 'F')) { + AdjustSize =3D (*(SsdtPointer + 10) -'A' + 10) * 0x10; + } + + CpuIndex +=3D AdjustSize; + AdjustSize =3D 0; + + if ((*(SsdtPointer + 9) > '0') && (*(SsdtPointer + 9) <=3D '9')) { + AdjustSize =3D (*(SsdtPointer + 9) -'0') * 0x100; + } else if ((*(SsdtPointer + 9) >=3D 'A') && (*(SsdtPointer + 9) <=3D= 'F')) { + AdjustSize =3D (*(SsdtPointer + 9) -'A' + 10) * 0x100; + } + + CpuIndex +=3D AdjustSize; + ThreadIndex =3D CpuIndex; + + // + // PCPS - Update DOMN + // + DomnValue =3D (UINT8) CpuSkt; + + if ((mCpuPCPSInfo[CpuSkt] & B_PCPS_DISABLE) =3D=3D 0) { + DomnValue =3D LocateApicIdInfo (CpuSkt, ThreadIndex); + + if (mNcpuValue[CpuSkt] =3D=3D 2) { + DomnValue =3D (DomnValue >> 1); + } + } + + DEBUG (( + DEBUG_VERBOSE, + "PatchOem3SsdtTable(): CpuIndex: 0x%x ThreadIndex: 0x%x CpuFixes: = 0x%x (%d)\n", + CpuIndex, + ThreadIndex, + CpuFixes, + CpuFixes + )); + + DEBUG (( + DEBUG_INFO, + "PatchOem3SsdtTable(): CpuSkt: %d CpuIndex: 0x%x, NcpuValue =3D 0x= %x, DomnValue =3D 0x%x\n", + CpuSkt, + CpuIndex, + mNcpuValue[CpuSkt], + DomnValue + )); + ++CpuFixes; + break; + + case SIGNATURE_32 ('T', 'S', 'D', 'C'): + case SIGNATURE_32 ('T', 'S', 'D', 'D'): + PsdPackage =3D ACPI_NAME_COMMAND_FROM_NAME_STR (SsdtPointer); + if (PsdPackage->StartByte !=3D AML_NAME_OP) { + continue; + } + + PsdPackageItemPtr =3D (PSD_PACKAGE_LAYOUT *) ((UINT8 *) PsdPac= kage); + DEBUG (( + DEBUG_VERBOSE, + "TSDC: PsdPackageItemPtr table: %x is detected...\n", + PsdPackage->NameStr + )); + DEBUG (( + DEBUG_VERBOSE, + " Initial Values: Domain =3D %x, CoordType =3D %x, NumP= rocessors =3D %x\n", + PsdPackageItemPtr->Domain, + PsdPackageItemPtr->CoordType, + PsdPackageItemPtr->NumProcessors + )); + + PsdPackageItemPtr->Domain =3D DomnValue; + PsdPackageItemPtr->NumProcessors =3D mNcpuValue[CpuSkt]; + DEBUG (( + DEBUG_VERBOSE, + " PsdPackage =3D %x, PsdPackageItemPtr =3D %x, SsdtPointer = =3D %x\n", + (UINT8 *)PsdPackage, + (UINT8 *)PsdPackageItemPtr, + (UINT8 *)SsdtPointer + )); + DEBUG (( + DEBUG_VERBOSE, + " Updated TSD Domain =3D %x, CoordType =3D %x, NumProcessor= s =3D %x\n", + PsdPackageItemPtr->Domain, + PsdPackageItemPtr->CoordType, + PsdPackageItemPtr->NumProcessors + )); + break; + + default: + break; + } // switch + } // for + + // + // N fixes together currently + // + ASSERT (CpuFixes =3D=3D (UINT32) MAX_CPU_NUM); + + return EFI_SUCCESS; +} + +/** + Update the OEM4 C State SSDT table (CST) + + @param *TableHeader - The table to be set + + @retval EFI_SUCCESS - Returns Success +**/ +EFI_STATUS +PatchOem4SsdtTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + return EFI_SUCCESS; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dec b/Platform/= Intel/WhitleyOpenBoardPkg/PlatformPkg.dec index 4d416325ae..a80472e73c 100644 --- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dec +++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dec @@ -398,6 +398,11 @@ ## gPlatformModuleTokenSpaceGuid.PcdEnableHighSpeedUart|FALSE|BOOLEAN|0x000= 0002C =20 + ## Platform Not support Acpi Table + # + gPlatformTokenSpaceGuid.PcdPlatformNotSupportAcpiTable|FALSE|BOOLEAN|0x4= 0000012 + gPlatformTokenSpaceGuid.PcdPlatformNotSupportAcpiBdatTable|FALSE|BOOLEAN= |0x40000013 + [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamicEx] ## MemoryCheck value for checking memory before boot OS. # To save the boot performance, the default MemoryCheck is set to 0. diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc b/Platform/= Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc index 39b93d9289..5dfee0eeb5 100644 --- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc +++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc @@ -621,6 +621,7 @@ CrcLib|WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf PlatformSpecificAcpiTableLib|WhitleyOpenBoardPkg/Library/PlatformSpecifi= cAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.inf BuildAcpiTablesLib|WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBui= ldAcpiTablesLib.inf + AcpiPlatformTableLib|WhitleyOpenBoardPkg/Library/AcpiPlatformTableLib/Ac= piPlatformLib.inf =20 [LibraryClasses.Common.SEC, LibraryClasses.Common.PEI_CORE, LibraryClasses= .Common.PEIM] FspWrapperApiLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFs= pWrapperApiLib.inf --=20 2.27.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#87432): https://edk2.groups.io/g/devel/message/87432 Mute This Topic: https://groups.io/mt/89698854/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat May 18 21:45:23 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+87431+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+87431+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1646952115; cv=none; d=zohomail.com; s=zohoarc; b=lz7LWe0p+vdjrNTWy2QPz7PBjOgV6X1QN1YsBsbeIt0OdFqTI4DQptW6VlRcwV5uwDJ4omGzv47ob0S2Hs4ZCY1DjKD6PK4mKb621ti7K10e/TsURaiKC9amucEm/VKDiPYtCx9pmE6PbdlRy9cbayCPHJSDhmWOPGr0y7PE3cc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1646952115; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=Fn44gEpRduRJcZveNhbHDV0MEtDBBlkBzN79VfOUsLU=; b=isdE5TmtANP0DgZByhIi3nQOPWWjtKjiViyQKtymhjRohrDWD25Pi7MEb9susFdtOvamZSSNPds2masAXA3icenj1r4XJ6Y5RWBzjj8M9J3izSI5TvyJeG5jZCtI1NXvzN8eWqej1amTvJ5R8+Ae/CGVqGmugxJWSxJAJWwdh5w= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+87431+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1646952115979460.4441165932277; Thu, 10 Mar 2022 14:41:55 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id RgyiYY1788612xRPJh0IlHss; Thu, 10 Mar 2022 14:41:55 -0800 X-Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mx.groups.io with SMTP id smtpd.web08.849.1646952110863190430 for ; Thu, 10 Mar 2022 14:41:52 -0800 X-IronPort-AV: E=McAfee;i="6200,9189,10282"; a="316121257" X-IronPort-AV: E=Sophos;i="5.90,171,1643702400"; d="scan'208";a="316121257" X-Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2022 14:41:35 -0800 X-IronPort-AV: E=Sophos;i="5.90,171,1643702400"; d="scan'208";a="644643389" X-Received: from iworam-desk.amr.corp.intel.com ([10.7.150.60]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2022 14:41:35 -0800 From: "Oram, Isaac W" To: devel@edk2.groups.io Cc: Nate DeSimone , Chasel Chiu Subject: [edk2-devel][edk2-platforms][PATCH V1 8/9] WhitleyOpenBoardPkg/AcpiPlatform: Add driver for publishing ACPI tables Date: Thu, 10 Mar 2022 14:41:13 -0800 Message-Id: In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,isaac.w.oram@intel.com X-Gm-Message-State: OlaHA1EmDCFJb8yaYzOhWSz8x1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1646952115; bh=rM6aa/i3c1XB6QRAdm1j2XFOPFvdOBelsjkttVvKL44=; h=Cc:Date:From:Reply-To:Subject:To; b=Etl/iHK4PY2+z19zXqMLdUvD9es08HHMN+R8zjnwTMSCDIWOz0SvgRJJdvaiI2cUqJr W1KswQ/ghgA6rXRLV8MJbg78AegSG8Uv77NQxxoNNFi2EmMorrsYhFy8bmS7oeoqoQtg4 8QIYEZgKgqUrPTH7OTOth+Nd99iAkS6gFbY= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1646952118088100002 Content-Type: text/plain; charset="utf-8" AcpiPlatform DXE driver loads and patches ACPI tables before publishing. Cc: Nate DeSimone Cc: Chasel Chiu Signed-off-by: Isaac Oram Reviewed-by: Nate DeSimone --- Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform= .c | 754 +++++++++ Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform= .h | 117 ++ Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform= .inf | 107 ++ Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform= Hooks.c | 384 +++++ Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform= Hooks.h | 51 + Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform= Utils.c | 133 ++ Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform= Utils.h | 66 + Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform= VTDHooks.c | 1762 ++++++++++++++++++++ Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dec = | 11 +- Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc = | 3 + Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.fdf = | 3 + Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaMain/StaticSkuDataDxe/Readme.md = | 1 + Platform/Intel/WhitleyOpenBoardPkg/WilsonCityRvp/AmlOffsets/AmlOffsets.inf= | 2 +- 13 files changed, 3388 insertions(+), 6 deletions(-) diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/= AcpiPlatform.c b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatf= orm/AcpiPlatform.c new file mode 100644 index 0000000000..1648029bd1 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPla= tform.c @@ -0,0 +1,754 @@ +/** @file + ACPI Platform Driver + + @copyright + Copyright 1999 - 2020 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "AcpiPlatform.h" +#include "AcpiPlatformUtils.h" +#include "AcpiPlatformHooks.h" +#include +#include +#include +#include + + +#ifndef __GNUC__ +#pragma optimize("", off) +#endif //__GNUC__ + +extern SOCKET_IIO_CONFIGURATION mSocketIioConfigurat= ion; +extern SOCKET_POWERMANAGEMENT_CONFIGURATION mSocketPowermanageme= ntConfiguration; +extern SOCKET_PROCESSORCORE_CONFIGURATION mSocketProcessorCore= Configuration; +extern EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE *mSpcrTable; +extern EFI_GUID gEfiGlobalVariableGu= id; +extern EFI_GUID gEfiPmSsdtTableStora= geGuid; + +BIOS_ACPI_PARAM *mAcpiParameter =3D NULL; +BOOLEAN mFirstNotify; +SYSTEM_CONFIGURATION mSystemConfiguration; +PCH_SETUP mPchSetup; + +UINT8 mKBPresent =3D 0; +UINT8 mMousePresent =3D 0; +EFI_IIO_UDS_PROTOCOL *mIioUds2 =3D NULL; +extern CPU_CSR_ACCESS_VAR *mCpuCsrAccessVarPtr; +UINT8 mPStateEnable =3D 0; + + +VOID +EFIAPI +AcpiOnPciEnumCmplCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + + Status =3D gBS->LocateProtocol (&gEfiPciEnumerationCompleteProtocolGuid,= NULL, &Context); + if (EFI_ERROR (Status)) { + // + // Skip the first dummy event signal. + // + return; + } + gBS->CloseEvent (Event); + + DEBUG ((DEBUG_INFO, "[ACPI] %a\n", __FUNCTION__)); + AcpiVtdTablesInstall (); +} + + +VOID +EFIAPI +AcpiOnEndOfDxeCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + DEBUG ((DEBUG_INFO, "[ACPI] %a\n", __FUNCTION__)); + // + // Installing ACPI Tables: NFIT, PCAT + // + InstallAndPatchAcpiTable (NVDIMM_FW_INTERFACE_TABLE_SIGNATURE); + InstallAndPatchAcpiTable (NVDIMM_PLATFORM_CONFIG_ATTRIBUTE_TABLE_SIGNATU= RE); +} + + +// +// Enable SCI for ACPI aware OS at ExitBootServices +// +VOID +EFIAPI +AcpiOnExitBootServicesCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + UINT16 Pm1Cnt; + + gBS->CloseEvent (Event); + + DEBUG ((DEBUG_INFO, "[ACPI] %a\n", __FUNCTION__)); + // + // Enable SCI + // + Pm1Cnt =3D IoRead16 (mAcpiParameter->PmBase + R_ACPI_IO_PM1_CNT); + Pm1Cnt |=3D B_ACPI_IO_PM1_CNT_SCI_EN; + IoWrite16 (mAcpiParameter->PmBase + R_ACPI_IO_PM1_CNT, Pm1Cnt); +} + +/** + Disables the SW SMI Timer. + ACPI events are disabled and ACPI event status is cleared. + SCI mode is then enabled. + + Disable SW SMI Timer + + Clear all ACPI event status and disable all ACPI events + Disable PM sources except power button + Clear status bits + + Disable GPE0 sources + Clear status bits + + Disable GPE1 sources + Clear status bits + + Guarantee day-of-month alarm is invalid (ACPI 1.0 section 4.7.2.4) + + Enable SCI + + @param Event - not used + @param Context - not used + + @retval None +**/ +STATIC +VOID +AcpiEnableAtReadyToBoot ( + VOID + ) +{ + UINT32 SmiEn; + UINT8 Data8; + UINT16 Pm1En; + + ASSERT (mAcpiParameter->PmBase !=3D 0); + + SmiEn =3D IoRead32 (mAcpiParameter->PmBase + R_ACPI_IO_SMI_EN); + + // + // Disable SW SMI Timer and legacy USB + // + SmiEn &=3D ~(B_ACPI_IO_SMI_EN_SWSMI_TMR | B_ACPI_IO_SMI_EN_LEGACY_USB | = B_ACPI_IO_SMI_EN_LEGACY_USB2); + + + // + // And enable SMI on write to B_ACPI_IO_PM1_CNT_SLP_EN when SLP_TYP is w= ritten + // + SmiEn |=3D B_ACPI_IO_SMI_EN_ON_SLP_EN; + IoWrite32(mAcpiParameter->PmBase + R_ACPI_IO_SMI_EN, SmiEn); + + // + // Disable PM sources except power button + // + + Pm1En =3D B_ACPI_IO_PM1_EN_PWRBTN; + IoWrite16(mAcpiParameter->PmBase + R_ACPI_IO_PM1_EN, Pm1En); + + // + // Guarantee day-of-month alarm is invalid (ACPI 1.0 section 4.7.2.4) + // + Data8 =3D RTC_ADDRESS_REGISTER_D; + IoWrite8(R_IOPORT_CMOS_STANDARD_INDEX, Data8); + Data8 =3D 0x0; + IoWrite8(R_IOPORT_CMOS_STANDARD_DATA, Data8); + + // + // Do platform specific stuff for ACPI enable SMI + // + + +} + +/** + Executes ACPI Platform actions related with ready to boot event + + @param Event - not used + @param Context - not used + + @retval None +**/ +STATIC +VOID +EFIAPI +AcpiOnReadyToBootCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EFI_ACPI_DESCRIPTION_HEADER Table =3D {0}; + EFI_ACPI_TABLE_VERSION TableVersion; + UINTN TableHandle; + EFI_ACPI_TABLE_PROTOCOL *AcpiTable; + EFI_CPUID_REGISTER CpuidRegisters; + SETUP_DATA SetupData; + UINT8 ARIForward; + + DYNAMIC_SI_LIBARY_PROTOCOL *DynamicSiLibraryProtocol =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, &D= ynamicSiLibraryProtocol); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return; + } + + if (mFirstNotify) { + return; + } + mFirstNotify =3D TRUE; + DEBUG ((DEBUG_INFO, "[ACPI] %a\n", __FUNCTION__)); + + Status =3D GetEntireConfig (&SetupData); + ASSERT_EFI_ERROR (Status); + CopyMem (&mSystemConfiguration, &(SetupData.SystemConfig), sizeof(SYSTEM= _CONFIGURATION)); + CopyMem (&mSocketIioConfiguration, &(SetupData.SocketConfig.IioConfig), = sizeof(SOCKET_IIO_CONFIGURATION)); + CopyMem (&mSocketPowermanagementConfiguration, &(SetupData.SocketConfig.= PowerManagementConfig), sizeof(SOCKET_POWERMANAGEMENT_CONFIGURATION)); + CopyMem (&mSocketProcessorCoreConfiguration, &(SetupData.SocketConfig.So= cketProcessorCoreConfiguration), sizeof(SOCKET_PROCESSORCORE_CONFIGURATION)= ); + CopyMem (&mPchSetup, &(SetupData.PchSetup), sizeof(PCH_SETUP)); + + mAcpiParameter->TpmEnable =3D mSystemConfiguration.TpmEnable; + + // + // CpuPm.Asl: External (CSEN, FieldUnitObj) + // + mAcpiParameter->CStateEnable =3D TRUE; + // + // CpuPm.Asl: External (C3EN, FieldUnitObj) + // + mAcpiParameter->C3Enable =3D mSocketPowermanagementConfiguration.C3E= nable; + // + // CpuPm.Asl: External (C6EN, FieldUnitObj) + // + AsmCpuid (CPUID_MONITOR_MWAIT, &CpuidRegisters.RegEax, &CpuidRegisters.R= egEbx, &CpuidRegisters.RegEcx, &CpuidRegisters.RegEdx); + // + // If C6 is not supported by CPU, disregard setup C6 knob value + // + if (((CpuidRegisters.RegEdx >> 12) & 0xF) > 0) { + if (mSocketPowermanagementConfiguration.C6Enable =3D=3D PPM_AUTO) { + mAcpiParameter->C6Enable =3D 1; // POR Default =3D Enabled + } else { + mAcpiParameter->C6Enable =3D mSocketPowermanagementConfiguration.C6E= nable; + } + } else { + mAcpiParameter->C6Enable =3D 0; + DEBUG ((DEBUG_INFO, "Cpu does not support C6 state\n")); + } + + if (mAcpiParameter->C6Enable && mAcpiParameter->C3Enable) { //C3 and C6= enable are exclusive + mAcpiParameter->C6Enable =3D 1; + mAcpiParameter->C3Enable =3D 0; + } + // + // CpuPm.Asl: External (C7EN, FieldUnitObj) + // + mAcpiParameter->C7Enable =3D 0; + // + // CpuPm.Asl: External (OSCX, FieldUnitObj) + // + mAcpiParameter->OSCX =3D mSocketPowermanagementConfiguration.OSC= x; + // + // CpuPm.Asl: External (MWOS, FieldUnitObj) + // + mAcpiParameter->MonitorMwaitEnable =3D 1; + // + // CpuPm.Asl: External (PSEN, FieldUnitObj) + // + mAcpiParameter->PStateEnable =3D mPStateEnable; + // + // CpuPm.Asl: External (HWAL, FieldUnitObj) + // + mAcpiParameter->HWAllEnable =3D mSocketPowermanagementConfiguration.Proc= essorEistPsdFunc; + + mAcpiParameter->KBPresent =3D mKBPresent; + mAcpiParameter->MousePresent =3D mMousePresent; + mAcpiParameter->TStateEnable =3D mSocketPowermanagementConfiguration.TSt= ateEnable; + // + // Debug mode indicator for Acpi use + // + mAcpiParameter->DebugModeIndicator =3D (UINT8)PcdGet8 (PcdDebugModeEnabl= e); + DEBUG ((DEBUG_ERROR, "DebugModeIndicator =3D %x\n", mAcpiParameter->Debu= gModeIndicator)); + + // + // Fine grained T state + // + AsmCpuid (CPUID_THERMAL_POWER_MANAGEMENT, &CpuidRegisters.RegEax, &Cpui= dRegisters.RegEbx, &CpuidRegisters.RegEcx, &CpuidRegisters.RegEdx); + if ((((CPUID_THERMAL_POWER_MANAGEMENT_EAX*)&CpuidRegisters.RegEax)->Bits= .ECMD) && mSocketPowermanagementConfiguration.TStateEnable) { + mAcpiParameter->TStateFineGrained =3D 1; + } + if (((CPUID_THERMAL_POWER_MANAGEMENT_EAX*)&CpuidRegisters.RegEax)->Bits.= HWP_Notification !=3D 0) { + mAcpiParameter->HwpInterrupt =3D 1; + } + // + // CpuPm.Asl: External (HWEN, FieldUnitObj) + // + mAcpiParameter->HWPMEnable =3D DetectHwpFeature (); + + mAcpiParameter->EmcaEn =3D mSystemConfiguration.EmcaEn; + mAcpiParameter->WheaSupportEn =3D mSystemConfiguration.WheaSupportEn; + + mAcpiParameter->PcieAcpiHotPlugEnable =3D (UINT8) (BOOLEAN) (mSocketIioC= onfiguration.PcieAcpiHotPlugEnable !=3D 0); + // + // Initialize USB3 mode from setup data + // + // If mode !=3D manual control + // just copy mode from setup + // + if (mPchSetup.PchUsbManualMode !=3D 1) { + mAcpiParameter->XhciMode =3D mPchSetup.PchUsbManualMode; + } + + // + // Get ACPI IO Base Address + // + mAcpiParameter->PmBase =3D DynamicSiLibraryProtocol->PmcGetAcpiBase (); + DEBUG ((DEBUG_INFO, "ACPI IO Base Address =3D %x\n", mAcpiParameter->PmB= ase)); + + // + // When X2APIC enabled and VTD support enabled, Enable ApicIdOverrided p= arameter to update ACPI table. + // + if (mSocketIioConfiguration.VTdSupport && mSocketProcessorCoreConfigurat= ion.ProcessorX2apic) { + mAcpiParameter->ApicIdOverrided =3D 1; + } + + // + // Find the AcpiTable protocol + // + Status =3D LocateSupportProtocol ( + &gEfiAcpiTableProtocolGuid, + gEfiAcpiTableStorageGuid, + &AcpiTable, + FALSE + ); + + ASSERT_EFI_ERROR (Status); + + TableVersion =3D EFI_ACPI_TABLE_VERSION_2_0; + Table.Signature =3D EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_S= IGNATURE; + Status =3D PlatformUpdateTables ((EFI_ACPI_COMMON_HEADER *)&Table, &Tabl= eVersion); + if (!EFI_ERROR (Status)) { + // + // Add SPCR table + // + if (mSpcrTable !=3D NULL) { + DEBUG ((DEBUG_INFO, "mSpcrTable->Header.Length=3D%d\n", mSpcrTable->= Header.Length)); + DEBUG ((DEBUG_INFO, "install=3D%x\n", &(AcpiTable->InstallAcpiTable)= )); + DEBUG ((DEBUG_INFO, "acpit=3D%x\n", AcpiTable)); + DEBUG ((DEBUG_INFO, "mSpcr=3D%x\n", mSpcrTable)); + DEBUG ((DEBUG_INFO, "len =3D%d\n", mSpcrTable->Header.Length)); + + TableHandle =3D 0; + Status =3D AcpiTable->InstallAcpiTable ( + AcpiTable, + mSpcrTable, + mSpcrTable->Header.Length, + &TableHandle + ); + ASSERT_EFI_ERROR (Status); + } else { + DEBUG ((DEBUG_INFO, "Warning: mSpcrTable is NULL\n")); + } + } + if (mSpcrTable !=3D NULL) { + gBS->FreePool (mSpcrTable); + } + + AcpiEnableAtReadyToBoot(); + + Status =3D GetOptionData (&gEfiSetupVariableGuid, OFFSET_OF(SYSTEM_CONF= IGURATION, ARIForward), &ARIForward, sizeof(UINT8)); + ASSERT_EFI_ERROR (Status); + if (!ARIForward) { + DisableAriForwarding (); + } + +} + + +/** + Installs ACPI Platform tables + + @param None + + @retval EFI_SUCCESS - Operation completed successfully. +**/ +STATIC +EFI_STATUS +EFIAPI +AcpiPlatformEarlyAcpiTablesInstall ( + VOID + ) +{ + EFI_STATUS Status; + EFI_STATUS AcpiStatus; + BOOLEAN Installed; + EFI_ACPI_TABLE_PROTOCOL *AcpiTable; + EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol; + INTN Instance =3D 0; + EFI_ACPI_COMMON_HEADER *CurrentTable; + EFI_ACPI_TABLE_VERSION TableVersion; + UINTN TableHandle; + UINT32 FvStatus; + UINT32 Size; + + // + // Find the AcpiTable protocol + // + Status =3D LocateSupportProtocol ( + &gEfiAcpiTableProtocolGuid, + gEfiAcpiTableStorageGuid, + &AcpiTable, + FALSE + ); + + ASSERT_EFI_ERROR (Status); + + // + // Locate the firmware volume protocol + // + Status =3D LocateSupportProtocol ( + &gEfiFirmwareVolume2ProtocolGuid, + gEfiAcpiTableStorageGuid, + &FwVol, + TRUE + ); + ASSERT_EFI_ERROR (Status); + + // + // Read tables from the storage file. + // + while (!EFI_ERROR (Status)) { + CurrentTable =3D NULL; + TableVersion =3D EFI_ACPI_TABLE_VERSION_NONE; + TableHandle =3D 0; + Installed =3D FALSE; + + Status =3D FwVol->ReadSection ( + FwVol, + &gEfiAcpiTableStorageGuid, + EFI_SECTION_RAW, + Instance, + &CurrentTable, + (UINTN *) &Size, + &FvStatus + ); + + if (!EFI_ERROR (Status)) { + + DEBUG ((DEBUG_INFO, "[ACPI] Table '%c%c%c%c' found in FwVol\n", + ((CHAR8*)&CurrentTable->Signature)[0], ((CHAR8*)&CurrentTabl= e->Signature)[1], + ((CHAR8*)&CurrentTable->Signature)[2], ((CHAR8*)&CurrentTabl= e->Signature)[3])); + + // + // Check if table should be processed or will be updated later + // + if (CurrentTable->Signature !=3D NVDIMM_FW_INTERFACE_TABLE_SIGNATURE + && CurrentTable->Signature !=3D NVDIMM_PLATFORM_CONFIG_ATTRIBUTE= _TABLE_SIGNATURE + ) { + // + // Allow platform specific code to reject the table or update it + // + AcpiStatus =3D AcpiPlatformHooksIsActiveTable (CurrentTable); //Sy= stemBoard); + if (!EFI_ERROR (AcpiStatus)) { + // + // Perform any table specific updates. + // + AcpiStatus =3D PlatformUpdateTables (CurrentTable, &TableVersion= ); + if (!EFI_ERROR (AcpiStatus)) { + // + // Add the table + // + if (TableVersion !=3D EFI_ACPI_TABLE_VERSION_NONE) { + // + // Install the table + // + AcpiStatus =3D AcpiTable->InstallAcpiTable (AcpiTable, Curre= ntTable, CurrentTable->Length, &TableHandle); + if (!EFI_ERROR (AcpiStatus)) { + Installed =3D TRUE; + } + ASSERT_EFI_ERROR (AcpiStatus); + } + } + } + } + // + // Increment the instance + // + Instance++; + } + } + + // + // Build any from-scratch ACPI tables. Halt on errors for debug builds, = but + // for release builds it is safe to continue. + // + Status =3D PlatformBuildTables (); + ASSERT_EFI_ERROR (Status); + return EFI_SUCCESS; +} + +/** + Installs ACPI Platform tables that wasn't installed in the early phase + + @param None + + @retval EFI_SUCCESS - Operation completed successfully. +**/ +STATIC +EFI_STATUS +EFIAPI +AcpiPlatformLateAcpiTablesInstall ( + VOID + ) +{ + // + // Install xHCI ACPI Table + // + InstallXhciAcpiTable (); + + return EFI_SUCCESS; +} + + +/** + Installs ACPI PmSsdt tables + + @param None + + @retval EFI_SUCCESS - Operation completed successfully. + +**/ +STATIC +EFI_STATUS +EFIAPI +PmSsdtEarlyAcpiTablesInstall ( + VOID + ) +{ + EFI_STATUS Status; + EFI_STATUS AcpiStatus; + BOOLEAN Installed; + EFI_ACPI_TABLE_PROTOCOL *AcpiTable; + EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol; + INTN Instance =3D 0; + EFI_ACPI_COMMON_HEADER *CurrentTable; + EFI_ACPI_TABLE_VERSION TableVersion; + UINTN TableHandle; + UINT32 FvStatus; + UINT32 Size; + + // + // Find the AcpiTable protocol + // + Status =3D LocateSupportProtocol ( + &gEfiAcpiTableProtocolGuid, + gEfiPmSsdtTableStorageGuid, + &AcpiTable, + FALSE + ); + + ASSERT_EFI_ERROR (Status); + + // + // Locate the firmware volume protocol + // + Status =3D LocateSupportProtocol ( + &gEfiFirmwareVolume2ProtocolGuid, + gEfiPmSsdtTableStorageGuid, + &FwVol, + TRUE + ); + ASSERT_EFI_ERROR (Status); + + // + // Read tables from the storage file. + // + while (!EFI_ERROR (Status)) { + CurrentTable =3D NULL; + TableVersion =3D EFI_ACPI_TABLE_VERSION_NONE; + TableHandle =3D 0; + Installed =3D FALSE; + + Status =3D FwVol->ReadSection ( + FwVol, + &gEfiPmSsdtTableStorageGuid, + EFI_SECTION_RAW, + Instance, + &CurrentTable, + (UINTN *) &Size, + &FvStatus + ); + + if (!EFI_ERROR (Status)) { + // + // Check if table should be processed or will be updated later + // + if (CurrentTable->Signature !=3D NVDIMM_FW_INTERFACE_TABLE_SIGNATURE= ) { + // + // Allow platform specific code to reject the table or update it + // + AcpiStatus =3D AcpiPlatformHooksIsActiveTable (CurrentTable); + if (!EFI_ERROR (AcpiStatus)) { + // + // Perform any table specific updates. + // + AcpiStatus =3D PlatformUpdateTables (CurrentTable, &TableVersion= ); + if (!EFI_ERROR (AcpiStatus)) { + // + // Add the table + // + if (TableVersion !=3D EFI_ACPI_TABLE_VERSION_NONE) { + // + // Install the table + // + AcpiStatus =3D AcpiTable->InstallAcpiTable (AcpiTable, Curre= ntTable, CurrentTable->Length, &TableHandle); + if (!EFI_ERROR (AcpiStatus)) { + Installed =3D TRUE; + } + ASSERT_EFI_ERROR (AcpiStatus); + } + } + } + } + // + // Increment the instance + // + Instance++; + } + } + return EFI_SUCCESS; +} // PmSsdtEarlyAcpiTablesInstall() + + +/** + Entry point for Acpi platform driver. + + @param ImageHandle - A handle for the image that is initializing this = driver. + @param SystemTable - A pointer to the EFI system table. + + @retval EFI_SUCCESS - Driver initialized successfully. + @retval EFI_LOAD_ERROR - Failed to Initialize or has been loaded. + @retval EFI_OUT_OF_RESOURCES - Could not allocate needed resources. +**/ +EFI_STATUS +EFIAPI +AcpiPlatformEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_EVENT Event; + VOID *HobList; + VOID *RgstPtr; + + DYNAMIC_SI_LIBARY_PROTOCOL *DynamicSiLibraryProtocol =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, &D= ynamicSiLibraryProtocol); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + mFirstNotify =3D FALSE; + // + // Report Status Code to indicate Acpi Init + // + REPORT_STATUS_CODE ( + EFI_PROGRESS_CODE, + (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_BS_ACPI_INIT) + ); + + Status =3D gBS->LocateProtocol (&gEfiIioUdsProtocolGuid, NULL, &mIioUds2= ); + if (EFI_ERROR (Status)) { + + ASSERT_EFI_ERROR (Status); + return Status; + } + + mCpuCsrAccessVarPtr =3D DynamicSiLibraryProtocol->GetSysCpuCsrAccessVar = (); + // + // Update HOB variable for PCI resource information + // Get the HOB list. If it is not present, then ASSERT. + // + Status =3D EfiGetSystemConfigurationTable (&gEfiHobListGuid, &HobList); + ASSERT_EFI_ERROR (Status); + + // + // Initialize Platform Hooks + // + PlatformHookInit (); + + // + // Install ACPI PLatform Tables + // + Status =3D AcpiPlatformEarlyAcpiTablesInstall (); + ASSERT_EFI_ERROR (Status); + + // + // Install ACPI PMSsdt Tables + // + Status =3D PmSsdtEarlyAcpiTablesInstall (); + ASSERT_EFI_ERROR (Status); + + // + // Install ACPI PLatform Tables that wasn't installed yet (NFIT/xHCI) + // + Status =3D AcpiPlatformLateAcpiTablesInstall (); + ASSERT_EFI_ERROR (Status); + + // + // Register ready to boot event handler + // + Status =3D EfiCreateEventReadyToBootEx (TPL_NOTIFY, AcpiOnReadyToBootCal= lback, NULL, &Event); + ASSERT_EFI_ERROR (Status); + + // + // Create PCI Enumeration Completed callback. + // + Event =3D EfiCreateProtocolNotifyEvent (&gEfiPciEnumerationCompleteProto= colGuid, TPL_CALLBACK, + AcpiOnPciEnumCmplCallback, NULL, &= RgstPtr); + ASSERT (Event !=3D NULL); + + // + // Register EndOfDxe handler + // + Status =3D gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + AcpiOnEndOfDxeCallback, + NULL, + &gEfiEndOfDxeEventGroupGuid, + &Event + ); + ASSERT_EFI_ERROR (Status); + + // + // Register ExitBootServicesEvent handler + // + Status =3D gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + AcpiOnExitBootServicesCallback, + NULL, + &gEfiEventExitBootServicesGuid, + &Event + ); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} // AcpiPlatformEntryPoint() diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/= AcpiPlatform.h b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatf= orm/AcpiPlatform.h new file mode 100644 index 0000000000..162c162df8 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPla= tform.h @@ -0,0 +1,117 @@ +/** @file + + @copyright + Copyright 1999 - 2020 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _ACPI_PLATFORM_H_ +#define _ACPI_PLATFORM_H_ + +// +// Statements that include other header files +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Platform.h" +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define RTC_ADDRESS_REGISTER_D 13 + + +/** + Entry point for Acpi platform driver. + + @param ImageHandle - A handle for the image that is initializing this = driver. + @param SystemTable - A pointer to the EFI system table. + + @retval EFI_SUCCESS - Driver initialized successfully. + @retval EFI_LOAD_ERROR - Failed to Initialize or has been loaded. + @retval EFI_OUT_OF_RESOURCES - Could not allocate needed resources. +**/ +EFI_STATUS +EFIAPI +AcpiPlatformEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +EFI_STATUS +LocateSupportProtocol ( + IN EFI_GUID *Protocol, + IN EFI_GUID gEfiAcpiMultiTableStorageGuid, + OUT VOID **Instance, + IN UINT32 Type + ); + +VOID +AcpiVtdIntRemappingEnable ( + VOID + ); + +EFI_STATUS +AcpiVtdTablesInstall ( + VOID + ); + +#endif // _ACPI_PLATFORM_H_ diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/= AcpiPlatform.inf b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPla= tform/AcpiPlatform.inf new file mode 100644 index 0000000000..f4980ede74 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPla= tform.inf @@ -0,0 +1,107 @@ +## @file +# +# @copyright +# Copyright 2009 - 2020 Intel Corporation.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D AcpiPlatform + FILE_GUID =3D 87AB821C-79B8-4ef6-A913-21D22063F55F + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D AcpiPlatformEntryPoint + +[Sources] + AcpiPlatform.c + AcpiPlatform.h + AcpiPlatformUtils.c + AcpiPlatformUtils.h + AcpiPlatformHooks.c + AcpiPlatformHooks.h + AcpiPlatformVTDHooks.c + +[Packages] + WhitleyOpenBoardPkg/PlatformPkg.dec + WhitleySiliconPkg/SiliconPkg.dec + WhitleySiliconPkg/Cpu/CpuRcPkg.dec + WhitleySiliconPkg/CpRcPkg.dec + WhitleySiliconPkg/WhitleySiliconPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + UefiBootServicesTableLib + UefiDriverEntryPoint + BaseMemoryLib + DebugLib + UefiLib + UefiRuntimeServicesTableLib + HobLib + SetupLib + AcpiPlatformTableLib + ReportStatusCodeLib + PcdLib + LocalApicLib + +[Protocols] + gEfiMpServiceProtocolGuid + gEfiIioUdsProtocolGuid + gEfiGlobalNvsAreaProtocolGuid + gEfiPciEnumerationCompleteProtocolGuid + gEfiPciIoProtocolGuid + gEfiFirmwareVolume2ProtocolGuid + gEfiAcpiTableProtocolGuid # ALWAYS_CONSUMED; before was gEfi= AcpiSupportProtocolGuid + gEfiSerialIoProtocolGuid + gDxeEnhancedSpeedstepProtocolGuid + gEfiPlatformTypeProtocolGuid + gDmaRemapProtocolGuid + gEfiCrystalRidgeGuid + gEfiSmbiosProtocolGuid + gEfiPciRootBridgeIoProtocolGuid + gAcpiPlatformProtocolGuid + gDynamicSiLibraryProtocolGuid ## CONSUMES + gDynamicSiLibraryProtocol2Guid ## CONSUMES + +[Guids] + gEfiGlobalVariableGuid + gEfiAcpiTableStorageGuid + gEfiPmSsdtTableStorageGuid + gEfiPcAnsiGuid + gEfiVT100PlusGuid + gEfiVT100Guid + gEfiVTUTF8Guid + gEfiHobListGuid + gEfiPlatformInfoGuid + gEfiSetupVariableGuid + gEfiEndOfDxeEventGroupGuid + gEfiEventExitBootServicesGuid + gEfiSocketIioVariableGuid + gEfiSocketMemoryVariableGuid + gEfiSocketCommonRcVariableGuid + gEfiSocketMpLinkVariableGuid + gEfiSocketPowermanagementVarGuid + gEfiSocketProcessorCoreVarGuid + gPchInfoHobGuid ## CONSUMES + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId + gOemSkuTokenSpaceGuid.PcdOemTableIdXhci + gPlatformTokenSpaceGuid.PcdDebugModeEnable ## CONSUMES + +[FixedPcd] + gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuSocketCount + gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuCoreCount + +[Depex] + gDynamicSiLibraryProtocolGuid AND + gDynamicSiLibraryProtocol2Guid AND + gDmaRemapProtocolGuid AND + gEfiAcpiTableProtocolGuid AND + gEfiMpServiceProtocolGuid AND + gEfiIioSystemProtocolGuid AND + gSmbiosMemInfoProtocolGuid diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/= AcpiPlatformHooks.c b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/Acpi= Platform/AcpiPlatformHooks.c new file mode 100644 index 0000000000..93f312a178 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPla= tformHooks.c @@ -0,0 +1,384 @@ +/** @file + ACPI Platform Driver Hooks + + @copyright + Copyright 1996 - 2020 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// Statements that include other files +// +#include "AcpiPlatform.h" +#include "AcpiPlatformUtils.h" +#include "AcpiPlatformHooks.h" + +#ifndef __GNUC__ +#pragma optimize("",off) +#endif //__GNUC__ + +extern BOOLEAN mX2ApicEnabled; +extern UINT32 mNumOfBitShift; +extern EFI_PLATFORM_INFO *mPlatformInfo; +extern BIOS_ACPI_PARAM *mAcpiParameter; +extern EFI_IIO_UDS_PROTOCOL *mIioUds2; +extern CPU_CSR_ACCESS_VAR *mCpuCsrAccessVarPtr; + +extern SOCKET_MEMORY_CONFIGURATION mSocketMemoryConfiguration; +extern SOCKET_MP_LINK_CONFIGURATION mSocketMpLinkConfiguration; +extern SOCKET_COMMONRC_CONFIGURATION mSocketCommonRcConfiguration; +extern SOCKET_IIO_CONFIGURATION mSocketIioConfiguration; + +extern SOCKET_POWERMANAGEMENT_CONFIGURATION mSocketPowermanagementConfigur= ation; +extern SOCKET_PROCESSORCORE_CONFIGURATION mSocketProcessorCoreConfigurat= ion; + +extern SYSTEM_CONFIGURATION mSystemConfiguration; +extern PCH_SETUP mPchSetup; +extern BOOLEAN Is14nmCpu; + +EFI_GLOBAL_NVS_AREA_PROTOCOL mGlobalNvsArea; + + +EFI_STATUS +PlatformHookInit ( + VOID + ) +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + EFI_PHYSICAL_ADDRESS AcpiParameterAddr; + EFI_CPUID_REGISTER CpuidRegisters; + SETUP_DATA SetupData; + + ASSERT (mIioUds2); + + Status =3D EFI_SUCCESS; + + Status =3D GetEntireConfig (&SetupData); + + CopyMem (&mSocketMemoryConfiguration, &(SetupData.SocketConfig.MemoryCon= fig), sizeof(SOCKET_MEMORY_CONFIGURATION)); + CopyMem (&mSocketMpLinkConfiguration, &(SetupData.SocketConfig.UpiConfig= ), sizeof(SOCKET_MP_LINK_CONFIGURATION)); + CopyMem (&mSocketCommonRcConfiguration, &(SetupData.SocketConfig.CommonR= cConfig), sizeof(SOCKET_COMMONRC_CONFIGURATION)); + CopyMem (&mSocketPowermanagementConfiguration, &(SetupData.SocketConfig.= PowerManagementConfig), sizeof(SOCKET_POWERMANAGEMENT_CONFIGURATION)); + CopyMem (&mSocketProcessorCoreConfiguration, &(SetupData.SocketConfig.So= cketProcessorCoreConfiguration), sizeof(SOCKET_PROCESSORCORE_CONFIGURATION)= ); + CopyMem (&mSystemConfiguration, &(SetupData.SystemConfig), sizeof(SYSTEM= _CONFIGURATION)); + CopyMem (&mSocketIioConfiguration, &(SetupData.SocketConfig.IioConfig), = sizeof(SOCKET_IIO_CONFIGURATION)); + CopyMem (&mPchSetup, &(SetupData.PchSetup), sizeof(PCH_SETUP)); + + if (EFI_ERROR (Status)) { + mSocketPowermanagementConfiguration.ProcessorEistEnable =3D 0; + mSocketPowermanagementConfiguration.TurboMode =3D 0; + mSocketPowermanagementConfiguration.PackageCState =3D 0; + mSocketPowermanagementConfiguration.PwrPerfTuning =3D PWR_PERF_T= UNING_BIOS_CONTROL; + mSocketProcessorCoreConfiguration.ProcessorX2apic =3D 0; + mSocketProcessorCoreConfiguration.ForcePhysicalModeEnable =3D 0; + } + // + // If Emulation flag set by InitializeDefaultData in ProcMemInit.c + // force X2APIC + // Else read setup data + // + mX2ApicEnabled =3D mSocketProcessorCoreConfiguration.ProcessorX2apic; + + // + // Force x2APIC if the system is configured as X2APIC; or CPU hotplug is= enabled. + // + if ((GetApicMode () =3D=3D LOCAL_APIC_MODE_X2APIC) || (mIioUds2->IioUdsP= tr->SystemStatus.OutKtiCpuSktHotPlugEn)) { + mX2ApicEnabled =3D TRUE; + } + + // + // Allocate 256 runtime memory to pass ACPI parameter + // This Address must be < 4G because we only have 32bit in the dsdt + // + AcpiParameterAddr =3D 0xffffffff; + Status =3D gBS->AllocatePages ( + AllocateMaxAddress, + EfiACPIMemoryNVS, + EFI_SIZE_TO_PAGES (sizeof(BIOS_ACPI_PARAM)), + &AcpiParameterAddr + ); + ASSERT_EFI_ERROR (Status); + mAcpiParameter =3D (BIOS_ACPI_PARAM *)AcpiParameterAddr; + + DEBUG ((DEBUG_INFO, "ACPI Parameter Block Address: 0x%X\n", mAcpiParamet= er)); + + ZeroMem (mAcpiParameter, sizeof (BIOS_ACPI_PARAM)); + mAcpiParameter->PlatformId =3D (UINT32)mPlatformInfo->BoardId; + mAcpiParameter->IoApicEnable =3D mPlatformInfo->SysData.SysIoApicEnable; + mAcpiParameter->PchIoApic_24_119 =3D mPchSetup.PchIoApic24119Entries; + + Handle =3D NULL; + mGlobalNvsArea.Area =3D mAcpiParameter; + gBS->InstallProtocolInterface ( + &Handle, + &gEfiGlobalNvsAreaProtocolGuid, + EFI_NATIVE_INTERFACE, + &mGlobalNvsArea + ); + ASSERT_EFI_ERROR (Status); + + AsmCpuid (CPUID_VERSION_INFO, &CpuidRegisters.RegEax, &CpuidRegisters.R= egEbx, &CpuidRegisters.RegEcx, &CpuidRegisters.RegEdx); + mAcpiParameter->ProcessorId =3D (CpuidRegisters.RegEax & 0xFFFF0); + + // + // support up to 64 threads/socket + // + AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, 1, &mNumOfBitShift, NULL, NULL, NUL= L); + mNumOfBitShift &=3D 0x1F; + + // + // Set the bit shift value for CPU SKU + // + mAcpiParameter->CpuSkuNumOfBitShift =3D (UINT8) mNumOfBitShift; + + mAcpiParameter->ProcessorApicIdBase[0] =3D (UINT32) (0 << mNumOfBitShift= ); + mAcpiParameter->ProcessorApicIdBase[1] =3D (UINT32) (1 << mNumOfBitShift= ); + mAcpiParameter->ProcessorApicIdBase[2] =3D (UINT32) (2 << mNumOfBitShift= ); + mAcpiParameter->ProcessorApicIdBase[3] =3D (UINT32) (3 << mNumOfBitShift= ); + mAcpiParameter->ProcessorApicIdBase[4] =3D (UINT32) (4 << mNumOfBitShift= ); + mAcpiParameter->ProcessorApicIdBase[5] =3D (UINT32) (5 << mNumOfBitShift= ); + mAcpiParameter->ProcessorApicIdBase[6] =3D (UINT32) (6 << mNumOfBitShift= ); + mAcpiParameter->ProcessorApicIdBase[7] =3D (UINT32) (7 << mNumOfBitShift= ); + + // + // If SNC is enabled, and NumOfCluster is 2, set the ACPI variable for P= XM value + // + if (mIioUds2->IioUdsPtr->SystemStatus.OutSncEn) { + mAcpiParameter->SncAnd2Cluster =3D mIioUds2->IioUdsPtr->SystemStatus.O= utNumOfCluster; + } + + mAcpiParameter->MmCfg =3D (UINT32)mIioUds2->IioUdsPtr->PlatformData.Pci= ExpressBase; + mAcpiParameter->TsegSize =3D (UINT32)(mIioUds2->IioUdsPtr->PlatformData= .MemTsegSize >> 20); + + Status =3D PlatformHookAfterAcpiParamInit (); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "PlatformHookAfterAcpiParamInit() failed with Sta= tus: %r\n", Status)); + } + + return Status; +} + + +/** + Install and patch specific ACPI Table + + @param AcpiTableSignature + + @retval None +**/ +VOID +InstallAndPatchAcpiTable ( + UINT32 AcpiTableSignature + ) +{ + EFI_STATUS Status; + EFI_ACPI_TABLE_PROTOCOL *AcpiTable; + EFI_ACPI_TABLE_VERSION TableVersion; + EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol; + EFI_ACPI_COMMON_HEADER *CurrentTable =3D NULL; + UINT32 FvStatus; + UINTN Size; + UINTN TableHandle =3D 0; + INTN Instance =3D 0; + + DEBUG ((DEBUG_INFO, "InstallAndPatchAcpiTable '%c%c%c%c'\n", + ((CHAR8*)&AcpiTableSignature)[0], ((CHAR8*)&AcpiTableSignature)[= 1], + ((CHAR8*)&AcpiTableSignature)[2], ((CHAR8*)&AcpiTableSignature)[= 3])); + + Status =3D LocateSupportProtocol ( + &gEfiAcpiTableProtocolGuid, + gEfiAcpiTableStorageGuid, + &AcpiTable, + FALSE + ); + ASSERT_EFI_ERROR (Status); + + Status =3D LocateSupportProtocol ( + &gEfiFirmwareVolume2ProtocolGuid, + gEfiAcpiTableStorageGuid, + &FwVol, + TRUE + ); + ASSERT_EFI_ERROR (Status); + + while (!EFI_ERROR (Status)) { + + Status =3D FwVol->ReadSection ( + FwVol, + &gEfiAcpiTableStorageGuid, + EFI_SECTION_RAW, + Instance, + &CurrentTable, + (UINTN *) &Size, + &FvStatus + ); + + if (!EFI_ERROR (Status)) { + if (CurrentTable->Signature =3D=3D AcpiTableSignature) { + + Status =3D AcpiPlatformHooksIsActiveTable (CurrentTable); + if (!EFI_ERROR (Status)) { + + Status =3D PlatformUpdateTables (CurrentTable, &TableVersion); + if (!EFI_ERROR (Status)) { + + if (TableVersion !=3D EFI_ACPI_TABLE_VERSION_NONE) { + Status =3D AcpiTable->InstallAcpiTable ( + AcpiTable, + CurrentTable, + CurrentTable->Length, + &TableHandle + ); + } + } + ASSERT_EFI_ERROR (Status); + } else { + DEBUG ((DEBUG_ERROR, "No Table for current platform\n")); + } + } + + CurrentTable =3D NULL; + Instance++; + } + } +} + + +/** + Install Xhci ACPI Table + +**/ +VOID +InstallXhciAcpiTable ( + VOID + ) +{ + EFI_HANDLE *HandleBuffer; + EFI_STATUS Status; + EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol; + EFI_ACPI_COMMON_HEADER *CurrentTable; + UINT32 FvStatus; + UINTN Size; + UINTN TableHandle; + INTN Instance; + EFI_ACPI_TABLE_PROTOCOL *AcpiTable; + EFI_ACPI_DESCRIPTION_HEADER *TableHeader; + UINT64 XhciAcpiTable; + UINT64 *XhciAcpiTablePtr; + UINT64 TempOemTableId; + + HandleBuffer =3D 0; + Instance =3D 0; + TableHandle =3D 0; + CurrentTable =3D NULL; + FwVol =3D NULL; + XhciAcpiTable =3D 0; + + DEBUG ((DEBUG_INFO, "InstallXhciAcpiTable\n")); + + + XhciAcpiTablePtr =3D (UINT64*)PcdGetPtr (PcdOemTableIdXhci); + if (XhciAcpiTablePtr =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "XhciAcpiTablePtr is NULL\n")); + ASSERT (XhciAcpiTablePtr !=3D NULL); + return; + } + + XhciAcpiTable =3D *XhciAcpiTablePtr; + + // + // Find the AcpiSupport protocol + // + Status =3D LocateSupportProtocol ( + &gEfiAcpiTableProtocolGuid, + gEfiAcpiTableStorageGuid, + &AcpiTable, + FALSE + ); + + ASSERT_EFI_ERROR (Status); + + // + // Locate the firmware volume protocol + // + Status =3D LocateSupportProtocol ( + &gEfiFirmwareVolume2ProtocolGuid, + gEfiAcpiTableStorageGuid, + &FwVol, + TRUE + ); + + ASSERT_EFI_ERROR (Status); + + // + // Read tables from the storage file. + // + while (Status =3D=3D EFI_SUCCESS) { + Status =3D FwVol->ReadSection ( + FwVol, + &gEfiAcpiTableStorageGuid, + EFI_SECTION_RAW, + Instance, + &CurrentTable, + &Size, + &FvStatus + ); + + if (!EFI_ERROR (Status)) { + + TableHeader =3D (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable; + + if (TableHeader->OemTableId =3D=3D XhciAcpiTable) { + DEBUG ((DEBUG_INFO, "Install xhci table: %x\n", TableHeader->OemTa= bleId)); + + TempOemTableId =3D PcdGet64 (PcdAcpiDefaultOemTableId); + + CopyMem (TableHeader->OemId, PcdGetPtr (PcdAcpiDefaultOemId), size= of(TableHeader->OemId)); + CopyMem (&TableHeader->OemTableId, &TempOemTableId, sizeof(TableHe= ader->OemTableId)); + + TableHeader->CreatorId =3D EFI_ACPI_CREATOR_ID; + TableHeader->CreatorRevision =3D EFI_ACPI_CREATOR_REVISION; + + // + // Add the table + // + TableHandle =3D 0; + + Status =3D AcpiTable->InstallAcpiTable ( + AcpiTable, + CurrentTable, + CurrentTable->Length, + &TableHandle + ); + break; + } + + // + // Increment the instance + // + + Instance++; + CurrentTable =3D NULL; + } + } +} + +UINT8 +EFIAPI +DetectHwpFeature ( + VOID + ) +{ + EFI_STATUS Status; + DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &= DynamicSiLibraryProtocol2); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return FALSE; + } + + return DynamicSiLibraryProtocol2->DetectHwpFeature (); +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/= AcpiPlatformHooks.h b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/Acpi= Platform/AcpiPlatformHooks.h new file mode 100644 index 0000000000..2201dd5316 --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPla= tformHooks.h @@ -0,0 +1,51 @@ +/** @file + + @copyright + Copyright 1996 - 2020 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _ACPI_PLATFORM_HOOKS_H_ +#define _ACPI_PLATFORM_HOOKS_H_ + +// +// Statements that include other header files +// +#include +#include +#include +#include + +EFI_STATUS +PlatformHookInit ( + VOID + ); + +VOID +DisableAriForwarding ( + VOID + ); + +EFI_STATUS +AllocateRasfSharedMemory ( + VOID + ); + +UINT8 +EFIAPI +DetectHwpFeature ( + VOID + ); + +VOID +InstallAndPatchAcpiTable ( + UINT32 + ); + +VOID +InstallXhciAcpiTable ( + VOID + ); + +#endif diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/= AcpiPlatformUtils.c b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/Acpi= Platform/AcpiPlatformUtils.c new file mode 100644 index 0000000000..27a9803fcc --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPla= tformUtils.c @@ -0,0 +1,133 @@ +/** @file + ACPI Platform Utilities + + @copyright + Copyright 2017 - 2018 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "AcpiPlatformUtils.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + 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 tab= le + storage file. + + @param[in] Protocol - The protocol to find. + @param[in] EfiAcpiStorageGuid - EFI ACPI tables storage guid + @param[out] Instance - Return pointer to the first instance = of the protocol. + @param[in] Type - The type of protocol to locate. + + @retval EFI_SUCCESS - The function completed successfully. + @retval EFI_NOT_FOUND - The protocol could not be located. + @retval EFI_OUT_OF_RESOURCES - There are not enough resources to find = the protocol. +**/ +EFI_STATUS +LocateSupportProtocol ( + IN EFI_GUID *Protocol, + IN EFI_GUID EfiAcpiStorageGuid, + OUT VOID **Instance, + IN UINT32 Type + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN NumberOfHandles; + EFI_FV_FILETYPE FileType; + UINT32 FvStatus; + EFI_FV_FILE_ATTRIBUTES Attributes; + UINTN Size; + UINTN Index; + + FvStatus =3D 0; + // + // Locate protocol. + // + Status =3D gBS->LocateHandleBuffer ( + ByProtocol, + Protocol, + 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 =3D 0; Index < NumberOfHandles; Index++) { + // + // Get the protocol on this handle + // This should not fail because of LocateHandleBuffer + // + Status =3D gBS->HandleProtocol ( + HandleBuffer[Index], + Protocol, + Instance + ); + ASSERT (!EFI_ERROR (Status)); + + if (!Type) { + // + // Not looking for the FV protocol, so find the first instance of the + // protocol. There should not be any errors because our handle buff= er + // should always contain at least one or LocateHandleBuffer would ha= ve + // returned not found. + // + break; + } + // + // See if it has the ACPI storage file + // + Status =3D ((EFI_FIRMWARE_VOLUME2_PROTOCOL *) (*Instance))->ReadFile ( + *I= nstance, + &E= fiAcpiStorageGuid, + NU= LL, + &S= ize, + &F= ileType, + &A= ttributes, + &F= vStatus + ); + + // + // If we found it, then we are done + // + if (!EFI_ERROR (Status)) { + break; + } + } + // + // Our exit status is determined by the success of the previous operatio= ns + // If the protocol was found, Instance already points to it. + // + // + // Free any allocated buffers + // + gBS->FreePool (HandleBuffer); + + return Status; +} diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/= AcpiPlatformUtils.h b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/Acpi= Platform/AcpiPlatformUtils.h new file mode 100644 index 0000000000..50a5f0471e --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPla= tformUtils.h @@ -0,0 +1,66 @@ +/** @file + + @copyright + Copyright 2017 - 2018 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _ACPI_PLATFORM_UTILS_H_ +#define _ACPI_PLATFORM_UTILS_H_ + +extern EFI_GUID gEfiAcpiTableStorageGuid; + + +/** + Function checks if ACPI Platform Protocol is ready to install + + @param None + + @retval TRUE ACPI Platform Protocol can be installed, + FALSE ACPI Platform Protocol not ready yet + +**/ +BOOLEAN +IsAcpiPlatformProtocolReadyForInstall ( + VOID + ); + +/** + Function checks if ACPI Platform Protocol is already installed + + @param None + + @retval TRUE ACPI Platform Protocol is installed, + FALSE ACPI Platform Protocol not installed yet + +**/ +BOOLEAN +IsAcpiPlatformProtocolInstalled ( + VOID + ); + +/** + 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 tab= le + storage file. + + @param[in] Protocol - The protocol to find. + @param[in] EfiAcpiStorageGuid - EFI ACPI tables storage guid + @param[out] Instance - Return pointer to the first instance o= f the protocol. + @param[in] Type - The type of protocol to locate. + + @retval EFI_SUCCESS - The function completed successfully. + @retval EFI_NOT_FOUND - The protocol could not be located. + @retval EFI_OUT_OF_RESOURCES - There are not enough resources to find = the protocol. + +**/ +EFI_STATUS +LocateSupportProtocol ( + IN EFI_GUID *Protocol, + IN EFI_GUID EfiAcpiStorageGuid, + OUT VOID **Instance, + IN UINT32 Type + ); + +#endif // _ACPI_PLATFORM_UTILS_H_ diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/= AcpiPlatformVTDHooks.c b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/A= cpiPlatform/AcpiPlatformVTDHooks.c new file mode 100644 index 0000000000..a517a9adce --- /dev/null +++ b/Platform/Intel/WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPla= tformVTDHooks.c @@ -0,0 +1,1762 @@ +/** @file + ACPI Platform Driver VT-D Hooks + + @copyright + Copyright 2012 - 2021 Intel Corporation.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "AcpiPlatform.h" +#include "AcpiPlatformHooks.h" +#include +#include +#include +#include + +extern EFI_PLATFORM_INFO *mPlatformInfo; +extern BIOS_ACPI_PARAM *mAcpiParameter; +extern EFI_IIO_UDS_PROTOCOL *mIioUds2; +extern CPU_CSR_ACCESS_VAR *mCpuCsrAccessVarPtr; +extern SYSTEM_CONFIGURATION mSystemConfiguration; +extern SOCKET_IIO_CONFIGURATION mSocketIioConfiguration; +extern SOCKET_PROCESSORCORE_CONFIGURATION mSocketProcessorCoreConfigurat= ion; +extern EFI_GUID mSystemConfigurationGuid; +extern BOOLEAN mX2ApicEnabled; + + +#define EFI_PCI_CAPABILITY_PTR 0x34 +#define EFI_PCIE_CAPABILITY_BASE_OFFSET 0x100 +#define EFI_PCIE_CAPABILITY_ID_ACS 0x000D +#define EFI_PCI_CAPABILITY_ID_PCIEXP 0x10 +#define EFI_PCI_EXPRESS_CAPABILITY_REGISTER 0x02 + +#define ACS_CAPABILITY_REGISTER 0x04 +#define ACS_SOURCE_VALIDATION BIT0 +#define ACS_P2P_REQUEST_REDIRECT BIT2 +#define ACS_P2P_COMPLETION_REDIRECT BIT3 +#define ACS_UPSTREAM_FORWARDING BIT4 + +#define ACS_CONTROL_REGISTER 0x06 +#define ACS_SOURCE_VALIDATION_ENABLE BIT0 +#define ACS_P2P_REQUEST_REDIRECT_ENABLE BIT2 +#define ACS_P2P_COMPLETION_REDIRECT_ENABLE BIT3 +#define ACS_UPSTREAM_FORWARDING_ENABLE BIT4 + +#define R_VTD_GCMD_REG 0x18 +#define R_VTD_GSTS_REG 0x1C +#define R_VTD_IQT_REG 0x88 +#define R_VTD_IQA_REG 0x90 +#define R_VTD_IRTA_REG 0xB8 + +#define VTD_ISOCH_ENGINE_OFFSET 0x1000 + +// +// a flag to indicate if we should disable Vt-d for ACS WA +// +BOOLEAN mDisableVtd =3D FALSE; + +DMA_REMAP_PROTOCOL DmaRemapProt; +#define VTD_SUPPORT_INSTANCE_FROM_THIS(a) CR(a, VTD_SUPPORT_INSTANCE, Dm= aRemapProt, EFI_ACPI_6_2_DMA_REMAPPING_TABLE_SIGNATURE) +#define EFI_PCI_CAPABILITY_ID_ATS 0x0F + +#define SEGMENT0 0x00 +#define MEM_BLK_COUNT 0x140 +#define INTRREMAP BIT3 +#define MEMORY_SIZE (MaxIIO * NUMBER_PORTS_PER_SOC= KET) +#define R_VTD_EXT_CAP_LOW 0x10 +#define R_VTD_EXT_CAP_HIGH 0x14 +#define IIO_STACK0 0 +#define IOAT_DEVICE_NUM_10NM 0x01 + + +PCI_NODE mPciPath0_1[] =3D { + {PCI_DEVICE_NUMBER_PCH_HDA, PCI_FUNCTION_NUMBER_PCH_HDA}, + {(UINT8) -1, (UINT8) -1}, +}; + +// +// IOAPIC2 - IIO IoApic +// +PCI_NODE mPciPath2_0_10nm[] =3D { + { PCIE_PORT_0_DEV_0, PCIE_PORT_0_FUNC_0 }, + { (UINT8)-1, (UINT8)-1 }, +}; +PCI_NODE mPciPath2_1_10nm[] =3D { + { PCIE_PORT_1A_DEV_1, PCIE_PORT_1A_FUNC_1 }, + { (UINT8)-1, (UINT8)-1 }, +}; +PCI_NODE mPciPath2_2_10nm[] =3D { + { PCIE_PORT_1B_DEV_1, PCIE_PORT_1B_FUNC_1 }, + { (UINT8)-1, (UINT8)-1 }, +}; +PCI_NODE mPciPath2_3_10nm[] =3D { + { PCIE_PORT_1C_DEV_1, PCIE_PORT_1C_FUNC_1 }, + { (UINT8)-1, (UINT8)-1 }, +}; +PCI_NODE mPciPath2_4_10nm[] =3D { + { PCIE_PORT_1D_DEV_1, PCIE_PORT_1D_FUNC_1 }, + { (UINT8)-1, (UINT8)-1 }, +}; +PCI_NODE mPciPath2_5_10nm[] =3D { + { PCIE_PORT_2A_DEV_2, PCIE_PORT_2A_FUNC_2 }, + { (UINT8)-1, (UINT8)-1 }, +}; +PCI_NODE mPciPath2_6_10nm[] =3D { + { PCIE_PORT_2B_DEV_2, PCIE_PORT_2B_FUNC_2 }, + { (UINT8)-1, (UINT8)-1 }, +}; +PCI_NODE mPciPath2_7_10nm[] =3D { + { PCIE_PORT_2C_DEV_2, PCIE_PORT_2C_FUNC_2 }, + { (UINT8)-1, (UINT8)-1 }, +}; +PCI_NODE mPciPath2_8_10nm[] =3D { + { PCIE_PORT_2D_DEV_2, PCIE_PORT_2D_FUNC_2 }, + { (UINT8)-1, (UINT8)-1 }, +}; +PCI_NODE mPciPath2_9_10nm[] =3D { + { PCIE_PORT_3A_DEV_3, PCIE_PORT_3A_FUNC_3 }, + { (UINT8)-1, (UINT8)-1 }, +}; +PCI_NODE mPciPath2_10_10nm[] =3D { + { PCIE_PORT_3B_DEV_3, PCIE_PORT_3B_FUNC_3 }, + { (UINT8)-1, (UINT8)-1 }, +}; +PCI_NODE mPciPath2_11_10nm[] =3D { + { PCIE_PORT_3C_DEV_3, PCIE_PORT_3C_FUNC_3 }, + { (UINT8)-1, (UINT8)-1 }, +}; +PCI_NODE mPciPath2_12_10nm[] =3D { + { PCIE_PORT_3D_DEV_3, PCIE_PORT_3D_FUNC_3 }, + { (UINT8)-1, (UINT8)-1 }, +}; +PCI_NODE mPciPath2_13_10nm[] =3D { + { PCIE_PORT_4A_DEV_4, PCIE_PORT_4A_FUNC_4 }, + { (UINT8)-1, (UINT8)-1 }, +}; +PCI_NODE mPciPath2_14_10nm[] =3D { + { PCIE_PORT_4B_DEV_4, PCIE_PORT_4B_FUNC_4 }, + { (UINT8)-1, (UINT8)-1 }, +}; +PCI_NODE mPciPath2_15_10nm[] =3D { + { PCIE_PORT_4C_DEV_4, PCIE_PORT_4C_FUNC_4 }, + { (UINT8)-1, (UINT8)-1 }, +}; +PCI_NODE mPciPath2_16_10nm[] =3D { + { PCIE_PORT_4D_DEV_4, PCIE_PORT_4D_FUNC_4 }, + { (UINT8)-1, (UINT8)-1 }, +}; +PCI_NODE mPciPath2_17_10nm[] =3D { + { PCIE_PORT_5A_DEV_5, PCIE_PORT_5A_FUNC_5 }, + { (UINT8)-1, (UINT8)-1 }, +}; +PCI_NODE mPciPath2_18_10nm[] =3D { + { PCIE_PORT_5B_DEV_5, PCIE_PORT_5B_FUNC_5 }, + { (UINT8)-1, (UINT8)-1 }, +}; +PCI_NODE mPciPath2_19_10nm[] =3D { + { PCIE_PORT_5C_DEV_5, PCIE_PORT_5C_FUNC_5 }, + { (UINT8)-1, (UINT8)-1 }, +}; +PCI_NODE mPciPath2_20_10nm[] =3D { + { PCIE_PORT_5D_DEV_5, PCIE_PORT_5D_FUNC_5 }, + { (UINT8)-1, (UINT8)-1 }, +}; + +DEVICE_SCOPE mDevScopeDRHD[] =3D { + { + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT, // Device type - HD = Audio + 00, // Enumeration ID + DEFAULT_PCI_BUS_NUMBER_PCH, // Start Bus Number + &mPciPath0_1[0] + }, +}; + +DEVICE_SCOPE mDevScopeATSR10nm[] =3D { + { + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE, // Pcie Port1 + 00, // Enumeration ID + DMI_BUS_NUM, + &mPciPath2_0_10nm[0] + }, + { + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE, // Pcie Port2 + 00, // Enumeration ID + DMI_BUS_NUM, + &mPciPath2_1_10nm[0] + }, + { + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE, // Pcie Port3 + 00, // Enumeration ID + DMI_BUS_NUM, + &mPciPath2_2_10nm[0] + }, + { + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE, // Pcie Port4 + 00, // Enumeration ID + DMI_BUS_NUM, + &mPciPath2_3_10nm[0] + }, + { + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE, // Pcie Port5 + 00, // Enumeration ID + DMI_BUS_NUM, + &mPciPath2_4_10nm[0] + }, + { + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE, // Pcie Port6 + 00, // Enumeration ID + DMI_BUS_NUM, + &mPciPath2_5_10nm[0] + }, + { + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE, // Pcie Port7 + 00, // Enumeration ID + DMI_BUS_NUM, + &mPciPath2_6_10nm[0] + }, + { + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE, // Pcie Port8 + 00, // Enumeration ID + DMI_BUS_NUM, + &mPciPath2_7_10nm[0] + }, + { + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE, // Pcie Port9 + 00, // Enumeration ID + DMI_BUS_NUM, + &mPciPath2_8_10nm[0] + }, + { + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE, // Pcie Port10 + 00, // Enumeration ID + DMI_BUS_NUM, + &mPciPath2_9_10nm[0] + }, + { + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE, // Pcie Port11 + 00, // Enumeration ID + DMI_BUS_NUM, + &mPciPath2_10_10nm[0] + }, + { + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE, // Pcie Port12 + 00, // Enumeration ID + DMI_BUS_NUM, + &mPciPath2_11_10nm[0] + }, + { + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE, // Pcie Port13 + 00, // Enumeration ID + DMI_BUS_NUM, + &mPciPath2_12_10nm[0] + }, + { + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE, // Pcie Port14 + 00, // Enumeration ID + DMI_BUS_NUM, + &mPciPath2_13_10nm[0] + }, + { + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE, // Pcie Port15 + 00, // Enumeration ID + DMI_BUS_NUM, + &mPciPath2_14_10nm[0] + }, + { + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE, // Pcie Port16 + 00, // Enumeration ID + DMI_BUS_NUM, + &mPciPath2_15_10nm[0] + }, + { + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE, // Pcie Port17 + 00, // Enumeration ID + DMI_BUS_NUM, + &mPciPath2_16_10nm[0] + }, + { + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE, // Pcie Port18 + 00, // Enumeration ID + DMI_BUS_NUM, + &mPciPath2_17_10nm[0] + }, + { + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE, // Pcie Port19 + 00, // Enumeration ID + DMI_BUS_NUM, + &mPciPath2_18_10nm[0] + }, + { + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE, // Pcie Port20 + 00, // Enumeration ID + DMI_BUS_NUM, + &mPciPath2_19_10nm[0] + }, + { + EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE, // Pcie Port21 + 00, // Enumeration ID + DMI_BUS_NUM, + &mPciPath2_20_10nm[0] + } +}; + +DMAR_DRHD mDrhd =3D { + DRHD_SIGNATURE, + 00, // Flags + SEGMENT0, // Segment number + 00, // Base Address + 00, // Number of dev scope s= tructures + &mDevScopeDRHD[0] +}; + +DMAR_DRHD mDrhdIsoc =3D { + DRHD_SIGNATURE, + 00, // Flags + SEGMENT0, // Segment number + 00, // Base Address + 00, // Number of dev scope s= tructures + &mDevScopeDRHD[0] +}; + +DMAR_ATSR mAtsr10nm =3D { + ATSR_SIGNATURE, + SEGMENT0, // Segment number + 00, + NUMBER_PORTS_PER_SOCKET - 1, + 00, + &mDevScopeATSR10nm[0] +}; + +PCI_NODE mPciPath[] =3D { + { 00, 00}, + { (UINT8)-1, (UINT8)-1}, +}; + +UINT8 IoApicID[] =3D { PCH_IOAPIC_ID, //PCH + PC00_IOAPIC_ID, PC01_IOAPIC_ID, PC02_IOAPIC_ID, PC03_IOAPIC_ID, PC04_IO= APIC_ID, PC05_IOAPIC_ID, //Socket0 + PC06_IOAPIC_ID, PC07_IOAPIC_ID, PC08_IOAPIC_ID, PC09_IOAPIC_ID, PC10_IO= APIC_ID, PC11_IOAPIC_ID, //Socket1 + PC12_IOAPIC_ID, PC13_IOAPIC_ID, PC14_IOAPIC_ID, PC15_IOAPIC_ID, PC16_IO= APIC_ID, PC17_IOAPIC_ID, //Socket2 + PC18_IOAPIC_ID, PC19_IOAPIC_ID, PC20_IOAPIC_ID, PC21_IOAPIC_ID, PC22_IO= APIC_ID, PC23_IOAPIC_ID, //Socket3 + PC24_IOAPIC_ID, PC25_IOAPIC_ID, PC26_IOAPIC_ID, PC27_IOAPIC_ID, PC28_IO= APIC_ID, PC29_IOAPIC_ID, //Socket4 + PC30_IOAPIC_ID, PC31_IOAPIC_ID, PC32_IOAPIC_ID, PC33_IOAPIC_ID, PC34_IO= APIC_ID, PC35_IOAPIC_ID, //Socket5 + PC36_IOAPIC_ID, PC37_IOAPIC_ID, PC38_IOAPIC_ID, PC39_IOAPIC_ID, PC40_IO= APIC_ID, PC41_IOAPIC_ID, //Socket6 + PC42_IOAPIC_ID, PC43_IOAPIC_ID, PC44_IOAPIC_ID, PC45_IOAPIC_ID, PC46_IO= APIC_ID, PC47_IOAPIC_ID, //Socket7 +}; + +PCI_NODE mPciPath7[] =3D { + { PCI_DEVICE_NUMBER_PCH_XHCI, PCI_FUNCTION_NUMBER_PCH_XHCI }, + { (UINT8)-1, (UINT8)-1}, +}; +DEVICE_SCOPE DevScopeRmrr[] =3D { + { + 1, // RMRR dev Scope - XHCI + 0, // Enumeration ID + 0, // Start Bus Number + &mPciPath7[0] + }, +}; + +DMAR_RMRR mRmrr =3D { + RMRR_SIGNATURE, // Signature + SEGMENT0, // Segment number + ' ', // Reserved Memory RegionBase Addr= ess + ' ', // Reserved Memory RegionLimit Add= ress + ' ', // Number of Dev Scope structures + &DevScopeRmrr[0] +}; + +typedef struct { + UINT8 aBuf[32]; +} MEM_BLK; + +DMAR_RHSA mRhsa; + +typedef struct { + UINT8 Bus; + UINT8 Dev; + UINT8 Func; +} DMAR_DEVICE; + +EFI_STATUS +LocateCapRegBlock( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT8 CapID, + OUT UINT8 *PciExpressOffset, + OUT UINT8 *NextRegBlock + ); + +EFI_STATUS +LocatePciExpressCapRegBlock ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT16 CapID, + OUT UINT32 *Offset, + OUT UINT32 *NextRegBlock +); + +DMAR_DRHD mDrhd; +DMAR_RHSA mRhsa; + +DMAR_ATSR* GetDmarAtsrTablePointer ( + VOID + ) +{ + DMAR_ATSR* pAtsr =3D NULL; + + pAtsr =3D &mAtsr10nm; + + return pAtsr; +} + + +/** + Enable VT-d interrupt remapping. + + This function should be called late at ReadyToBoot event. If called in A= cpiVtdTablesInstall() + would hang in CpuDeadLoop() because of timeout when waiting for invalida= tion commands complete. +**/ +VOID +AcpiVtdIntRemappingEnable ( + VOID + ) +{ + EFI_STATUS Status; + UINT64 *xApicAddr; + UINT64 *IRTA; + UINT64 *Addr; + UINT64 Value=3D0; + UINT16 IRTECount; + UINT16 Count; + UINT64 IRTEValue; + UINT8 RemapEng; + UINT8 RemapEngCount; + EFI_CPUID_REGISTER CpuidRegisters; + UINT32 VtdBarAddress; + UINT8 Stack; + VTD_SUPPORT_INSTANCE *DmarPrivateData; + DMA_REMAP_PROTOCOL *DmaRemap =3D NULL; + + static volatile UINT64 TempQWord[MaxIIO] =3D {0}; + + DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &= DynamicSiLibraryProtocol2); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return; + } + + Status =3D gBS->LocateProtocol (&gDmaRemapProtocolGuid, NULL, &DmaRemap); + if (EFI_ERROR (Status) || !DmaRemap->VTdSupport || !DmaRemap->InterruptR= emap) { + + DEBUG ((DEBUG_INFO, "[VTD] %a disabled\n", + (DmaRemap !=3D NULL && DmaRemap->VTdSupport) ? "Interrupt rema= pping" : "Virtualization Technology for Directed I/O")); + return; + } + ASSERT (mIioUds2); + + IRTEValue =3D 00; + RemapEng =3D 0; + RemapEngCount =3D mIioUds2->IioUdsPtr->PlatformData.numofIIO; + DmarPrivateData =3D VTD_SUPPORT_INSTANCE_FROM_THIS (DmaRemap); + + if (RemapEngCount > NELEMENTS (TempQWord)) { + DEBUG ((DEBUG_ERROR, "[ACPI](DMAR) ERROR: Number of IIO exceed interna= l table (%d > %d)\n", RemapEngCount, NELEMENTS (TempQWord))); + RemapEngCount =3D NELEMENTS (TempQWord); + } + + // + // Xapic tables update + // + IRTECount =3D 16 * 24; // Total 24 IRTE entries with 128 bits each. + // + // Allocate 4K alligned space for IRTE entries Added extra space of 500= bytes. + // + Status =3D gBS->AllocatePool (EfiACPIReclaimMemory, IRTECount + 0x1500, = &xApicAddr); + ASSERT_EFI_ERROR (Status); + + // + // Allocate IRT - Allocate zero-initialized, 4KB aligned, 4KB memory for= interrupt-remap-table and mark this memory as "ACPI Reclaim Memory" + // + xApicAddr =3D (UINT64 *)((UINT64)xApicAddr & (~0xFFF)); + ZeroMem (xApicAddr, IRTECount +0x1500); + + // + // 1. Program IRTE - Initialize the interrupt-remap-table as follows: (t= his table will be shared by all VT-d units) + // + for (Count =3D 0; Count < 24; Count++) { + + IRTEValue =3D 00; + if (Count =3D=3D 0) { + IRTEValue =3D (7 << 05) + 03; // Preset flag set, Ext int enabled= , FPD set + } + + AsmCpuid ( + CPUID_EXTENDED_TOPOLOGY, + &CpuidRegisters.RegEax, + &CpuidRegisters.RegEbx, + &CpuidRegisters.RegEcx, + &CpuidRegisters.RegEdx + ); + IRTEValue |=3D (UINT64)CpuidRegisters.RegEdx << 32; // Destination = Processor Apic ID + + *(volatile UINT64 *)((UINT64)xApicAddr + (Count * 16))=3D IRTEValue; + + // + // Perform a CLFLUSH instruction for each cachline in this 4KB memory = to ensure that updates to the interrupt-remap-table are visible in memory + // + AsmFlushCacheLine ((VOID *)((UINT64)xApicAddr + (Count * 16))); + } + // + // 3. Program the VT-D remap engines + // + for (RemapEng =3D 0; RemapEng < RemapEngCount; RemapEng++) { + for (Stack =3D 0; Stack < MAX_IIO_STACK; Stack++) { + // + // Check for valid stack + // + if (!(mIioUds2->IioUdsPtr->PlatformData.CpuQpiInfo[RemapEng].stackPr= esentBitmap & (1 << Stack))) { + continue; + } + VtdBarAddress =3D DynamicSiLibraryProtocol2->GetVtdBar (RemapEng, St= ack); + if (VtdBarAddress) { + // + // 2. For each VT-d unit in the platform, allocate and initialize = the invalidation queue/commands as follows + // + + // + // Allocate memory for the queued invalidation. + // + Status =3D gBS->AllocatePool (EfiACPIReclaimMemory, 0x1000 + 0x100= 0, &Addr); + if (EFI_ERROR (Status)) { + ASSERT (FALSE); + return; + } + ZeroMem (Addr, 0x1000 + 0x1000); + Addr =3D (UINT64 *)((UINT64)Addr & (~0xFFF)); + + // + // Submit two descriptors to the respective VT-d unit's invalidati= on queue as follows: + // Program 1st descriptor in invalidation-queue as Interrupt-Entry= -Cache Invalidation Descriptor + // with G (Granularity) field Clear + // + Addr[0] =3D 0x04; // Interrupt Entry Cache Invalidate Descript= or + Addr[1] =3D 0x00; + + // + // Program 2nd descriptor in invalidation-queue as Invalidation-Wa= it-Descriptor as follows: +Status-Data=3D1 + // +Status-Address=3Daddress of variable tmp[unit +SW=3D1 +FN=3D1 = +IF=3D0 + // + + Addr[2] =3D ((UINT64)1 << 32) + (06 << 04) + 05; // Invalidat= ion Wait Descriptor + + TempQWord[RemapEng] =3D 00; + Addr[3] =3D (UINTN)&TempQWord[RemapEng]; // Status Address [63:= 2] bits[127:65] + + // + // 3. Program the IRTA register to point to the IRT table. + // For each VT-d unit in the platform, program interrupt-remap-tab= le address and enable extended-interrupt-mode as follows + // + IRTA =3D (UINT64 *)((UINT64)VtdBarAddress + R_VTD_IRTA_REG); + Value =3D *(volatile UINT32 *)((UINT64)VtdBarAddress+ R_VTD_GSTS_R= EG); + // + // *(volatile UINT64*)IRTA =3D 04 + 0x800 + (UINT64)xApicAddr ; = // [0:3] size =3D 2 Power (X+1). Bit11 =3D1 Xapic mode Bit[12:63] address + // + if (DmarPrivateData->Dmar->Flags && EFI_ACPI_DMAR_FLAGS_X2APIC_OPT= _OUT) { + *(volatile UINT64*)IRTA =3D 07 + (UINT64)xApicAddr ; // [0:3] = size =3D 2 Power (X+1). Bit11 =3D1 Xapic mode Bit[12:63] address + *(volatile UINT32 *)((UINT64)VtdBarAddress+ R_VTD_GCMD_REG) =3D = (UINT32)(Value | BIT23); + } else { + *(volatile UINT64*)IRTA =3D 07 + 0x800 + (UINT64)xApicAddr ; = // [0:3] size =3D 2 Power (X+1). Bit11 =3D1 Xapic mode Bit[12:63] addrerss + } + // + // b. Set SIRTP in the command register. + // + Count =3D 0x1000; + *(volatile UINT32 *)((UINT64)VtdBarAddress+ R_VTD_GCMD_REG) =3D (U= INT32)(Value | BIT24); + + // + // Wait till the status bit is set indicating the completion of th= e SIRTP. + // + while (Count) { + Count--; + Value =3D *(volatile UINT32 *)((UINT64)VtdBarAddress + R_VTD_GST= S_REG); + if (Value & BIT24) { + break; + } + } + if (Count =3D=3D 0) { + ASSERT(FALSE); + CpuDeadLoop (); + } + *(volatile UINT64 *)((UINT64)VtdBarAddress+ R_VTD_IQA_REG) =3D (UI= NT64)Addr; + } // End of if (VtdBarAddress) + } // End of for (Stack =3D 0; Stack < MAX_IIO_STACK; Stack++) + } + + for (RemapEng =3D 0; RemapEng < RemapEngCount; RemapEng++) { + + for (Stack =3D 0; Stack < MAX_IIO_STACK; Stack++) { + + // + // Check for valid stack + // + if (!(mIioUds2->IioUdsPtr->PlatformData.CpuQpiInfo[RemapEng].stackPr= esentBitmap & (1 << Stack))) { + continue; + } + VtdBarAddress =3D DynamicSiLibraryProtocol2->GetVtdBar (RemapEng, St= ack); + if (VtdBarAddress) { + + // + // 4. For each VT-d unit in the platform, setup invalidation-queue= base registers and enable invalidation as follows + // Initialize a single descriptor which invalidates all the interr= upt entries. + // IQA register write (zeros IQH and IQT) + // + + // + // Enable queued invalidation in the command register. + // + Count =3D 0x1000; + Value =3D *(volatile UINT32 *)((UINT64)VtdBarAddress+ R_VTD_GSTS_R= EG); + *(volatile UINT32 *)((UINT64)VtdBarAddress + R_VTD_GCMD_REG) =3D (= UINT32)(Value | BIT26); + + while (Count) { + Count--; + Value =3D *(volatile UINT32 *)((UINT64)VtdBarAddress+ R_VTD_GSTS= _REG); + if( Value & BIT26) { + break; + } + } + if (Count =3D=3D 0) { + ASSERT(FALSE); + CpuDeadLoop (); + } + + // + // Start invalidations, program the IQT register + // Write the invalidation queue tail (IQT_REG) register as follows= to indicate to hardware two descriptors are submitted: + // +Bits 63:19 are 0 +Bits 18:4 gets value of 2h +Bits 3:0 are 0 + // + + *(volatile UINT64 *)((UINT64)VtdBarAddress + R_VTD_IQT_REG) =3D (0= 2 << 04); // Set tail to 02 + } // End of if (VtdAddress) + } //End of for (Stack =3D 0; Stack < MAX_IIO_STACK; Stack++) + } + + for (RemapEng =3D 0; RemapEng < RemapEngCount; RemapEng++) { + + for (Stack =3D 0; Stack < MAX_IIO_STACK; Stack++) { + + if (!(mIioUds2->IioUdsPtr->PlatformData.CpuQpiInfo[RemapEng].stackPr= esentBitmap & (1 << Stack))) { + continue; // Skip invalid stacks + } + VtdBarAddress =3D DynamicSiLibraryProtocol2->GetVtdBar (RemapEng, St= ack); + if (VtdBarAddress) { + // + // 5. For each VT-d unit in the platform, wait for invalidation co= mpletion, and enable interrupt remapping as follows + // Wait till the previously submitted invalidation commands are co= mpleted as follows + // Poll on the variable tmp[unit] in memory, until its value is 1h. + // + Count =3D 0x1000; + while (Count) { + Count--; + Value =3D TempQWord[RemapEng]; + if (Value & 01) { + break; + } + } + if (Count =3D=3D 0) { + ASSERT(FALSE); + CpuDeadLoop (); + } + } // End of if VtdBarAddress + } //End of for (Stack =3D 0; Stack < MAX_IIO_STACK; Stack++) + } + + // + // 5. Enable external interrupts in the IOAPIC RTE entry 0 + // + *(volatile UINT32 *)((UINT64)PCH_IOAPIC_ADDRESS) =3D 0x10; + *(volatile UINT32 *)((UINT64)PCH_IOAPIC_ADDRESS + 0x10) =3D 0x00; // Set= index to the IRTE0 + + *(volatile UINT32 *)((UINT64)PCH_IOAPIC_ADDRESS) =3D 0x10+1; + *(volatile UINT32 *)((UINT64)PCH_IOAPIC_ADDRESS + 0x10) =3D 0x10000;// S= et Remap enable bit +} + + +/** + Build DRHD entry into ACPI DMAR table for specific stack. + Include IOxAPIC, PCIExpress ports, and CBDMA if C-STACK. + + @param DmaRemap - pointer to DMA remapping protocol + @param IioIndex - IIO index to be processed + @param Stack - stack index to be processed + @param DevScope - buffer for device scope data structure + @param PciNode - buffer for PCI node data structure + @param PciRootBridgePtr- pointer to PciRootBridgeIo protocol for PCI acc= ess + + @retval EFI_SUCCESS - DRHD entry built successfully +**/ +EFI_STATUS +BuildDRHDForStack ( + DMA_REMAP_PROTOCOL *DmaRemap, + UINT8 IioIndex, + UINT8 Stack, + DEVICE_SCOPE *DevScope, + PCI_NODE *PciNode, + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgePtr, + UINT8 ApicIndex + ) +{ + EFI_STATUS Status =3D EFI_SUCCESS; + UINT8 Bus; + UINT8 Dev; + UINT8 Func; + UINT8 DevIndex; + UINT8 PciNodeIndex; + UINT8 PortIndex; + UINT8 MaxPortNumberPerSocket; + UINT8 CBIndex; + UINT64 VtdMmioExtCap; + UINT32 VtdBase; + UINT32 VidDid; + DMAR_ATSR *pAtsr =3D NULL; + DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &= DynamicSiLibraryProtocol2); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return EFI_NOT_FOUND; + } + + ASSERT (mIioUds2); + if (Stack > MAX_IIO_STACK){ + return EFI_UNSUPPORTED; + } + if (PciRootBridgePtr =3D=3D NULL) { + ASSERT (!(PciRootBridgePtr =3D=3D NULL)); + return EFI_INVALID_PARAMETER; + } + + mDrhd.Flags =3D 0; // all non-legacy stack has INCLUDE_ALL flag cleared + + VtdBase =3D DynamicSiLibraryProtocol2->GetVtdBar (IioIndex, Stack); + + if (VtdBase =3D=3D 0) { + return EFI_UNSUPPORTED; + } + + VtdMmioExtCap =3D *(volatile UINT64*)((UINTN)VtdBase + R_VTD_EXT_CAP_LOW= ); + mDrhd.RegisterBase =3D VtdBase; + + DevIndex =3D 00; + PciNodeIndex =3D 00; + mDrhd.DeviceScopeNumber =3D 00; + ZeroMem (DevScope, MEMORY_SIZE * sizeof (DEVICE_SCOPE)); + ZeroMem (PciNode, MEMORY_SIZE * sizeof (PCI_NODE)); + + // + // DRHD - CBDMA entry + // + if (Stack =3D=3D IIO_STACK0) { + + for (CBIndex =3D 0; CBIndex <=3D 7; CBIndex++) { + + DevScope[DevIndex].DeviceType =3D EFI_ACPI_DEVICE_SCOPE_ENTR= Y_TYPE_PCI_ENDPOINT; + DevScope[DevIndex].EnumerationID =3D 00; + DevScope[DevIndex].StartBusNumber =3D mCpuCsrAccessVarPtr ->Stac= kBus[IioIndex][IIO_STACK0]; + DevScope[DevIndex].PciNode =3D &PciNode[PciNodeIndex]; + + PciNode[PciNodeIndex].Device =3D IOAT_DEVICE_NUM_10NM; + PciNode[PciNodeIndex].Function =3D CBIndex; + DEBUG ((DEBUG_INFO, "[ACPI](DMAR) [%d.%d] Build DRHD CBDMA: Type %d,= EnumId %d, StartBus 0x%x, PciNode %02X.%X\n", + IioIndex, Stack, + DevScope[DevIndex].DeviceType, DevScope[DevIndex].Enumeratio= nID, DevScope[DevIndex].StartBusNumber, + DevScope[DevIndex].PciNode->Device, DevScope[DevIndex].PciNo= de->Function)); + DevIndex++; + PciNodeIndex++; + PciNode[PciNodeIndex].Device =3D (UINT8) -1; + PciNode[PciNodeIndex].Function =3D (UINT8) -1; + PciNodeIndex++; + + mDrhd.DeviceScopeNumber++; + } // End of for for(CBIndex =3D 0; CBIndex <=3D 07; CBIndex++) + } + + // + // DRHD - PCI-Ex ports + // + pAtsr =3D GetDmarAtsrTablePointer (); + MaxPortNumberPerSocket =3D DynamicSiLibraryProtocol2->GetMaxPortPerSocke= t (IioIndex); + for (PortIndex =3D 1; PortIndex < MaxPortNumberPerSocket; PortIndex++) { + + if (DynamicSiLibraryProtocol2->GetStackPerPort (IioIndex, PortIndex) != =3D Stack) { + continue; + } + Bus =3D DynamicSiLibraryProtocol2->GetSocketPortBusNum (IioIndex, Port= Index); + Dev =3D 0; + Func =3D 0; + if (pAtsr !=3D NULL) { + Dev =3D pAtsr->DeviceScope[PortIndex].PciNode->Device; + Func =3D pAtsr->DeviceScope[PortIndex].PciNode->Function; + } + if (DynamicSiLibraryProtocol2->IioNtbIsEnabled (IioIndex, PortIndex, &= Dev, &Func)) { + + DevScope[DevIndex].DeviceType =3D EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_P= CI_ENDPOINT; + } else { + DevScope[DevIndex].DeviceType =3D EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_P= CI_BRIDGE; + } + // + // Skip root ports which do not respond to PCI configuration cycles. + // + VidDid =3D 0; + Status =3D PciRootBridgePtr->Pci.Read ( + PciRootBridgePtr, + EfiPciWidthUint32, + EFI_PCI_ADDRESS (Bus, Dev, Func, 0), + 1, + &VidDid); + if (EFI_ERROR (Status) || VidDid =3D=3D 0xffffffff) { + + DEBUG ((DEBUG_INFO, "[ACPI](DMAR) [%d.%d p%d] %02X:%02X:%02X.%d Hidd= en (%X) - skip\n", + IioIndex, Stack, PortIndex, + mIioUds2->IioUdsPtr->PlatformData.CpuQpiInfo[IioIndex].PcieS= egment, + Bus, Dev, Func, VidDid)); + continue; + } + if (DynamicSiLibraryProtocol2->IioVmdPortIsEnabled (IioIndex, PortInde= x) || DynamicSiLibraryProtocol2->GetCurrentPXPMap (IioIndex, PortIndex) =3D= =3D 0) { + + DEBUG ((DEBUG_INFO, "[ACPI](DMAR) [%d.%d p%d] %a - skip\n", IioIndex= , Stack, PortIndex, + (DynamicSiLibraryProtocol2->GetCurrentPXPMap (IioIndex, Port= Index) =3D=3D 0) ? "Link width not set" : "Dummy VMD function")); + continue; + } + DevScope[DevIndex].EnumerationID =3D 00; + DevScope[DevIndex].StartBusNumber =3D Bus; + DevScope[DevIndex].PciNode =3D &PciNode[PciNodeIndex]; + PciNode[PciNodeIndex].Device =3D Dev; + PciNode[PciNodeIndex].Function =3D Func; + DEBUG ((DEBUG_INFO, "[ACPI](DMAR) [%d.%d p%d] Build DRHD PCI: Type %d,= EnumId %d, StartBus 0x%x, PciNode %02X.%X\n", + IioIndex, Stack, PortIndex, + DevScope[DevIndex].DeviceType, DevScope[DevIndex].EnumerationI= D, DevScope[DevIndex].StartBusNumber, + DevScope[DevIndex].PciNode->Device, DevScope[DevIndex].PciNode= ->Function)); + DevIndex++; + PciNodeIndex++; + PciNode[PciNodeIndex].Device =3D (UINT8) -1; + PciNode[PciNodeIndex].Function =3D (UINT8) -1; + PciNodeIndex++; + + mDrhd.DeviceScopeNumber++; + } // for (PortIndex...) + + Status =3D DynamicSiLibraryProtocol2->IioVmdGetPciLocation (IioIndex, St= ack, + &PciNode[PciNodeIndex].Device, &PciNode[P= ciNodeIndex].Function); + if (!EFI_ERROR (Status)) { + // + // VMD is enabled in this stack, expose VMD PCI device in DMAR for DMA= remapping. + // + DevScope[DevIndex].DeviceType =3D EFI_ACPI_DEVICE_SCOPE_ENTRY_= TYPE_PCI_ENDPOINT; + DevScope[DevIndex].EnumerationID =3D 00; + DevScope[DevIndex].StartBusNumber =3D mCpuCsrAccessVarPtr->StackBu= s[IioIndex][Stack]; + DevScope[DevIndex].PciNode =3D &PciNode[PciNodeIndex]; + DEBUG ((DEBUG_INFO, "[ACPI](DMAR) [%d.%d] Build DRHD VMD: Type %d, Enu= mId %d, StartBus 0x%x, PciNode %02X.%X\n", + IioIndex, Stack, + DevScope[DevIndex].DeviceType, DevScope[DevIndex].EnumerationI= D, DevScope[DevIndex].StartBusNumber, + DevScope[DevIndex].PciNode->Device, DevScope[DevIndex].PciNode= ->Function)); + DevIndex++; + PciNodeIndex++; + PciNode[PciNodeIndex].Device =3D (UINT8)-1; + PciNode[PciNodeIndex].Function =3D (UINT8)-1; + PciNodeIndex++; + + mDrhd.DeviceScopeNumber++; + } + + DmaRemap->InsertDmaRemap (DmaRemap, DrhdType, &mDrhd); + + return EFI_SUCCESS; +} + + +EFI_STATUS +ReportDmar ( + IN DMA_REMAP_PROTOCOL *DmaRemap + ) +{ + EFI_STATUS Status =3D EFI_SUCCESS; + UINT8 SocketIndex, IioBusBase, Bus; + UINT8 Dev, Func; + UINT8 DevIndex; + UINT8 PciNodeIndex; + UINT8 PciPortIndex; + UINT8 MaxPortNumberPerSocket; + UINT64 VtdMmioExtCap; + UINT32 VtdBase; + VTD_SUPPORT_INSTANCE *DmarPrivateData; + UINT16 NumberOfHpets; + UINT16 HpetCapIdValue; + DEVICE_SCOPE *DevScope; + PCI_NODE *PciNode; + EFI_PHYSICAL_ADDRESS Pointer; + UINT32 AlignedSize; + UINT32 NumberofPages; + BOOLEAN IntrRemapSupport; + EFI_CPUID_REGISTER CpuidRegisters; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgePtr; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeTab[MAX_SOCKET]; + UINT32 VidDid; + UINT8 Index; + UINT8 Stack =3D 0; + UINT8 FirstRun =3D 0; + VOID *HobPtr; + PCH_INFO_HOB *PchInfoHob; + DMAR_ATSR *pAtsr =3D NULL; + UINT8 ApicIndex =3D 1; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, &= DynamicSiLibraryProtocol2); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return FALSE; + } + + HobPtr =3D GetFirstGuidHob (&gPchInfoHobGuid); + if (HobPtr =3D=3D NULL) { + ASSERT (HobPtr !=3D NULL); + return EFI_INVALID_PARAMETER; + } + + PchInfoHob =3D (PCH_INFO_HOB*) GET_GUID_HOB_DATA (HobPtr); + if (PchInfoHob =3D=3D NULL) { + ASSERT (PchInfoHob !=3D NULL); + return EFI_INVALID_PARAMETER; + } + + ASSERT (mIioUds2); + + DmarPrivateData =3D VTD_SUPPORT_INSTANCE_FROM_THIS (DmaRemap); + // + // Get DMAR_HOST_ADDRESS_WIDTH from CPUID.(EAX=3D80000008h) return the P= hyical Address + // Size in the EAX register. EAX[7:0] + // Sync with Brickland code DMAR_HOST_ADDRESS_WIDTH 45 =3D 46 - 1 + // + AsmCpuid ( + CPUID_VIR_PHY_ADDRESS_SIZE, + &CpuidRegisters.RegEax, + &CpuidRegisters.RegEbx, + &CpuidRegisters.RegEcx, + &CpuidRegisters.RegEdx + ); + + DmarPrivateData->Dmar->HostAddressWidth =3D (UINT8)((CpuidRegisters.RegE= ax & 0xFF)-1); + DmarPrivateData->Dmar->Flags =3D 0; // INTR_REMAP + + // + // Locate PCI root bridge I/O protocol, for confirming PCI functions res= pond + // to PCI configuration cycles. + // + ZeroMem (&PciRootBridgeTab[0], sizeof(PciRootBridgeTab)); + + Status =3D gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiPciRootBridgeIoProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + + ASSERT_EFI_ERROR (Status); + + for (Index =3D 0; Index < HandleCount; Index ++) { + Status =3D gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiPciRootBridgeIoProtocolGuid, + &PciRootBridgePtr + ); + + ASSERT_EFI_ERROR (Status); + + PciRootBridgeTab[PciRootBridgePtr->SegmentNumber] =3D PciRootBridgePtr; + } + FreePool (HandleBuffer); + + // + // Allocate memory to DevScope structures + // + Status =3D gBS->AllocatePool (EfiACPIMemoryNVS, MEMORY_SIZE * sizeof (DE= VICE_SCOPE), &DevScope); + ASSERT_EFI_ERROR (Status); + + Status =3D gBS->AllocatePool (EfiACPIMemoryNVS, MEMORY_SIZE * sizeof (PC= I_NODE), &PciNode); + ASSERT_EFI_ERROR (Status); + + for (Index =3D 1; Index <=3D MAX_SOCKET; Index++) { + // + // VT-d specification request that DHRD entry 0 should be the latest e= ntry of the DMAR table. + // To accomplish this, the following check will ensure that latest ent= ry will be the one related to Socket 0. + // + if (Index =3D=3D MAX_SOCKET) { + SocketIndex =3D 0; + } else { + SocketIndex =3D Index; + } + + if (SocketIndex >=3D MAX_SOCKET) { + return EFI_INVALID_PARAMETER; + } + + if (!DynamicSiLibraryProtocol2->SocketPresent (SocketIndex)) { + continue; + } + + if (mIioUds2->IioUdsPtr->PlatformData.CpuQpiInfo[SocketIndex].PcieSegm= ent >=3D MAX_SOCKET) { + return EFI_INVALID_PARAMETER; + } + PciRootBridgePtr =3D PciRootBridgeTab[mIioUds2->IioUdsPtr->PlatformDat= a.CpuQpiInfo[SocketIndex].PcieSegment]; + + Stack =3D IIO_STACK0; + VtdBase =3D DynamicSiLibraryProtocol2->GetVtdBar (SocketIndex, Stack); + + DevIndex =3D 00; + PciNodeIndex =3D 00; + + mDrhd.Signature =3D DRHD_SIGNATURE; + mDrhd.SegmentNumber =3D mIioUds2->IioUdsPtr->PlatformData.Cp= uQpiInfo[SocketIndex].PcieSegment; + mDrhd.DeviceScopeNumber =3D 00; + mDrhd.DeviceScope =3D DevScope; + mDrhd.RegisterBase =3D VtdBase; + ZeroMem (DevScope, MEMORY_SIZE * sizeof (DEVICE_SCOPE)); + ZeroMem (PciNode, MEMORY_SIZE * sizeof (PCI_NODE)); + + VtdMmioExtCap =3D *(volatile UINT64*)((UINTN)VtdBase + R_VTD_EXT_CAP_L= OW); + + // + // Check Interrupt Remap support. + // + IntrRemapSupport =3D FALSE; + if (VtdMmioExtCap & INTRREMAP) { + IntrRemapSupport =3D TRUE; + } + DEBUG ((DEBUG_INFO, "[ACPI](DMAR) [%d.%d] VT-d base 0x%X, ExtCap=3D0x%= X\n", + SocketIndex, Stack, VtdBase, VtdMmioExtCap)); + + if (SocketIndex =3D=3D 0) { + ApicIndex =3D 1; + // + // DRHD - Legacy IOH + // + // Build DRHD on IIO0 - Stack1 to Stack5, not include C-STACK + // + for (Stack =3D 1; Stack < MAX_IIO_STACK; Stack++) { + + if (!DynamicSiLibraryProtocol2->IfStackPresent (SocketIndex, Stack= )) { // Skip invalid stack + continue; + } + BuildDRHDForStack (DmaRemap, SocketIndex, Stack, DevScope, PciNode= , PciRootBridgePtr, ApicIndex); + ApicIndex++; + } + + Stack =3D IIO_STACK0; + + // + // Re-initialize DRHD template for DRHD entry in legacy socket C-STA= CK + // + DevIndex =3D 00; + PciNodeIndex =3D 00; + mDrhd.DeviceScopeNumber =3D 00; + mDrhd.RegisterBase =3D DynamicSiLibraryProtocol2->GetVtdB= ar (SocketIndex, Stack); + ZeroMem (DevScope, MEMORY_SIZE * sizeof (DEVICE_SCOPE)); + ZeroMem (PciNode, MEMORY_SIZE * sizeof (PCI_NODE)); + + IioBusBase =3D mCpuCsrAccessVarPtr ->StackBus[SocketIndex][Stack]; /= / Stack 0 + mDrhd.Flags =3D 1; + + DEBUG ((DEBUG_INFO, "[ACPI](DMAR) InterruptRemap is %aabled (%d & %d= )\n", + (DmaRemap->InterruptRemap && IntrRemapSupport) ? "en" : "dis= ", DmaRemap->InterruptRemap, IntrRemapSupport)); + if (DmaRemap->InterruptRemap && IntrRemapSupport) { + + DmarPrivateData->Dmar->Flags =3D 0x01; // INTR_REMAP + + if (DmaRemap->X2ApicOptOut) { + DmarPrivateData->Dmar->Flags |=3D 0x02; // X2APIC_OPT_OUT + } + // + // PCH - IOAPIC + // This information will be provided by PCH side + // Currently is a hard-coded temporal solution to set: + // Bus =3D 0; Device and Function (together) =3D 0xF7; + // This is the value that is stored in IBDF register: + //#define V_P2SB_CFG_IBDF_BUS 0 + //#define V_P2SB_CFG_IBDF_DEV 30 + //#define V_P2SB_CFG_IBDF_FUNC 7 + // + DevScope[DevIndex].DeviceType =3D EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE= _IOAPIC; + DevScope[DevIndex].EnumerationID =3D PCH_IOAPIC_ID; // PCH team ne= eds confirm this value. (This value affects VTd functionality?) + DevScope[DevIndex].StartBusNumber =3D (UINT8)PchInfoHob->IoApicBus= Num; + DevScope[DevIndex].PciNode =3D &PciNode[PciNodeIndex]; + + PciNode[PciNodeIndex].Device =3D (UINT8)PchInfoHob->IoApicDevNum; + PciNode[PciNodeIndex].Function =3D (UINT8)PchInfoHob->IoApicFuncNu= m; + DEBUG ((DEBUG_INFO, "[ACPI](DMAR) [%d.%d] Build DRHD PCH IOAPIC: T= ype %d, EnumId %d, StartBus 0x%x, PciNode %02X.%X\n", + SocketIndex, Stack, + DevScope[DevIndex].DeviceType, DevScope[DevIndex].Enumerat= ionID, DevScope[DevIndex].StartBusNumber, + DevScope[DevIndex].PciNode->Device, DevScope[DevIndex].Pci= Node->Function)); + DevIndex++; + PciNodeIndex++; + PciNode[PciNodeIndex].Device =3D (UINT8)-1; + PciNode[PciNodeIndex].Function =3D (UINT8)-1; + PciNodeIndex++; + + mDrhd.DeviceScopeNumber++; + + HpetCapIdValue =3D *(UINT16 *)(UINTN)(HPET_BLOCK_ADDRESS); + NumberOfHpets =3D (HpetCapIdValue >> 0x08) & 0x1F; // Bits [8:12]= contains the number of Hpets + + if (NumberOfHpets && (NumberOfHpets !=3D 0x1f) && + (*((volatile UINT32 *)(UINTN)(HPET_BLOCK_ADDRESS + 0x100)) & B= IT15)) { + + DevScope[DevIndex].DeviceType =3D EFI_ACPI_DEVICE_SCOPE_ENTRY_= TYPE_MSI_CAPABLE_HPET; + DevScope[DevIndex].EnumerationID =3D 00; //Hard-coded + DevScope[DevIndex].StartBusNumber =3D (UINT8)PchInfoHob->HpetB= usNum; + DevScope[DevIndex].PciNode =3D &PciNode[PciNodeIndex]; + PciNode[PciNodeIndex].Device =3D (UINT8)PchInfoHob->HpetDevNum; + PciNode[PciNodeIndex].Function =3D (UINT8)PchInfoHob->HpetFunc= Num; + DEBUG ((DEBUG_INFO, "[ACPI](DMAR) [%d.%d] Build DRHD HPET: Typ= e %d, EnumId %d, StartBus 0x%x, PciNode %02X.%X\n", + SocketIndex, Stack, + DevScope[DevIndex].DeviceType, DevScope[DevIndex].Enum= erationID, DevScope[DevIndex].StartBusNumber, + DevScope[DevIndex].PciNode->Device, DevScope[DevIndex]= .PciNode->Function)); + DevIndex++; + PciNodeIndex++; + PciNode[PciNodeIndex].Device =3D (UINT8)-1; + PciNode[PciNodeIndex].Function =3D (UINT8)-1; + PciNodeIndex++; + + mDrhd.DeviceScopeNumber++; + } + } // DmaRemap->InterruptRemap + + DEBUG ((DEBUG_INFO, "[ACPI](DMAR) DMA_CTRL_PLATFORM_OPT_IN_FLAG is %= aabled\n", (DmaRemap->DmaCtrlOptIn) ? "En" : "Dis")); + if (DmaRemap->DmaCtrlOptIn) { + + DmarPrivateData->Dmar->Flags |=3D 0x04; // DMA_CTRL_PLATFORM_OPT_I= N_FLAG + } + DmaRemap->InsertDmaRemap (DmaRemap, DrhdType, &mDrhd); + + } else { // End of if (IioSocketId =3D=3D 0) + + if (FirstRun =3D=3D 0) { + ApicIndex =3D 0; + for (Stack =3D 0; Stack < MAX_IIO_STACK; Stack++) { + // + // Skip not valid stack + // + if (!DynamicSiLibraryProtocol2->IfStackPresent (0 ,Stack)) { + continue; + } + ApicIndex++; + } + FirstRun =3D 1; + } + // + // Build DRHD on IIO1 - Stack0 to Stack5 + // + for (Stack =3D 0; Stack < MAX_IIO_STACK; Stack++) { + // + // Skip not valid stack + // + if (!DynamicSiLibraryProtocol2->IfStackPresent (SocketIndex,Stack)= ) { + continue; + } + BuildDRHDForStack (DmaRemap, SocketIndex, Stack, DevScope, PciNode= , PciRootBridgePtr, ApicIndex); + ApicIndex++; + } //for( StackIndex=3D0; StackIndexATS) { + for (SocketIndex =3D 0; SocketIndex < MAX_SOCKET; SocketIndex++) { + + DEBUG((DEBUG_ERROR, "T_TEST: Build ATSR SocketIndex=3D%d.\n", Socket= Index)); + DEBUG((DEBUG_ERROR, " IIO_resource.valid=3D%d.\n", mIioUds2->= IioUdsPtr->PlatformData.IIO_resource[SocketIndex].Valid)); + + if (SocketIndex >=3D MAX_SOCKET) { + return EFI_INVALID_PARAMETER; + } + + if (!DynamicSiLibraryProtocol2->SocketPresent (SocketIndex)) { + continue; + } + + IioBusBase =3D mIioUds2->IioUdsPtr->PlatformData.IIO_resource[Socket= Index].BusBase; + + if (mIioUds2->IioUdsPtr->PlatformData.CpuQpiInfo[SocketIndex].PcieSe= gment >=3D MAX_SOCKET) { + return EFI_INVALID_PARAMETER; + } + PciRootBridgePtr =3D PciRootBridgeTab[mIioUds2->IioUdsPtr->PlatformD= ata.CpuQpiInfo[SocketIndex].PcieSegment]; + + PciNodeIndex =3D 00; + DevIndex =3D 00; + + ZeroMem (DevScope, MEMORY_SIZE * sizeof (DEVICE_SCOPE)); + ZeroMem (PciNode, MEMORY_SIZE * sizeof (PCI_NODE)); + + if (pAtsr !=3D NULL) { + pAtsr->Signature =3D ATSR_SIGNATURE; + pAtsr->Flags =3D 00; + pAtsr->SegmentNumber =3D mIioUds2->IioUdsPtr->PlatformData.CpuQpiI= nfo[SocketIndex].PcieSegment; + pAtsr->DeviceScopeNumber =3D 00; + pAtsr->DeviceScope =3D DevScope; + pAtsr->ATSRPresentBit =3D (UINT32)-1; // Not useful really Backw= ards project compatability (remove it later) + } + + // + // Loop From Port 1 to 15 for Legacy IOH and 0 to 15 for Non-Legacy = IOH + // + MaxPortNumberPerSocket =3D DynamicSiLibraryProtocol2->GetMaxPortPerS= ocket (SocketIndex); + for (PciPortIndex =3D 1; PciPortIndex < MaxPortNumberPerSocket; PciP= ortIndex++) { + // + // Check device IOTLBs supported or not in VT-d Extended capabilit= y register + // + Stack =3D DynamicSiLibraryProtocol2->GetStackPerPort (SocketIndex,= PciPortIndex); + // + // Check for a valid stack + // + if (!(DynamicSiLibraryProtocol2->IfStackPresent (SocketIndex, Stac= k))) { + DEBUG ((DEBUG_WARN, "[ACPI](DMAR) [%d.%d p%d] Stack not present\= n", SocketIndex, Stack, PciPortIndex)); + continue; + } + + VtdBase =3D DynamicSiLibraryProtocol2->GetVtdBar (SocketIndex, Sta= ck); + if (VtdBase !=3D 0) { + + VtdMmioExtCap =3D *(volatile UINT64*)((UINTN)VtdBase + R_VTD_EXT= _CAP_LOW); + // + // ATSR is applicable only for platform supporting device IOTLBs= through the VT-d extended capability register + // + if ((VtdMmioExtCap & BIT2) !=3D 0) { + + Bus =3D DynamicSiLibraryProtocol2->GetSocketPortBusNum (Socket= Index,PciPortIndex); + Dev =3D 0; + Func =3D 0; + Dev =3D mDevScopeATSR10nm[PciPortIndex].PciNode->Device; + Func =3D mDevScopeATSR10nm[PciPortIndex].PciNode->Function; + if (DynamicSiLibraryProtocol2->IioNtbIsEnabled (SocketIndex, P= ciPortIndex, &Dev, &Func)) { + DevScope[DevIndex].DeviceType =3D EFI_ACPI_DEVICE_SCOPE_ENTR= Y_TYPE_PCI_ENDPOINT; + } else { + DevScope[DevIndex].DeviceType =3D EFI_ACPI_DEVICE_SCOPE_ENTR= Y_TYPE_PCI_BRIDGE; + } + // + // Skip root ports which do not respond to PCI configuration c= ycles. + // + VidDid =3D 0; + Status =3D PciRootBridgePtr->Pci.Read ( + PciRootBridgePtr, + EfiPciWidthUint32, + EFI_PCI_ADDRESS (Bus, Dev, Func, 0), + 1, + &VidDid); + if (EFI_ERROR (Status) || VidDid =3D=3D 0xffffffff) { + + DEBUG ((DEBUG_INFO, "[ACPI](DMAR) [%d.%d p%d] %02X:%02X:%02X= .%d Hidden (%X) - skip\n", + SocketIndex, Stack, PciPortIndex, + mIioUds2->IioUdsPtr->PlatformData.CpuQpiInfo[SocketI= ndex].PcieSegment, + Bus, Dev, Func, VidDid)); + continue; + } + if (DynamicSiLibraryProtocol2->IioVmdPortIsEnabled (SocketInde= x, PciPortIndex) || DynamicSiLibraryProtocol2->GetCurrentPXPMap (SocketInde= x, PciPortIndex) =3D=3D 0) { + + DEBUG ((DEBUG_INFO, "[ACPI](DMAR) [%d.%d p%d] %a - skip\n", = SocketIndex, Stack, PciPortIndex, + (DynamicSiLibraryProtocol2->GetCurrentPXPMap (Socket= Index, PciPortIndex) =3D=3D 0) ? "Link width not set" : "Dummy VMD function= ")); + continue; + } + DevScope[DevIndex].EnumerationID =3D 00; + DevScope[DevIndex].StartBusNumber =3D Bus; + DevScope[DevIndex].PciNode =3D &PciNode[PciNodeInde= x]; + PciNode[PciNodeIndex].Device =3D Dev; + PciNode[PciNodeIndex].Function =3D Func; + DEBUG ((DEBUG_INFO, "[ACPI](DMAR) [%d.%d p%d] Build DRHD PCI: = Type %d, EnumId %d, StartBus 0x%x, PciNode %02X.%X\n", + SocketIndex, Stack, PciPortIndex, + DevScope[DevIndex].DeviceType, DevScope[DevIndex].Enum= erationID, DevScope[DevIndex].StartBusNumber, + DevScope[DevIndex].PciNode->Device, DevScope[DevIndex]= .PciNode->Function)); + DevIndex++; + PciNodeIndex++; + PciNode[PciNodeIndex].Device =3D (UINT8) -1; + PciNode[PciNodeIndex].Function =3D (UINT8) -1; + PciNodeIndex++; + if(pAtsr !=3D NULL){ + pAtsr->DeviceScopeNumber++; + } + } // End of if ((VtdMmioExtCap & BIT2) !=3D 0) + } // End of if VtdBase + } // for (PciPortIndex...) + + if (pAtsr !=3D NULL){ + if (pAtsr->DeviceScopeNumber) { + DmaRemap->InsertDmaRemap(DmaRemap, AtsrType, pAtsr); + } + } + } // End of for (RootBridgeLoop =3D 0; RootBridgeLoop < mIioUds2->IioU= dsPtr->PlatformData.numofIIO; RootBridgeLoop++) + } // End of if (ATS) { + + // + // RMRR + // + AlignedSize =3D (MEM_BLK_COUNT * sizeof(MEM_BLK)); + if (AlignedSize % 0x1000) { + AlignedSize =3D ( (MEM_BLK_COUNT * sizeof(MEM_BLK)) & (~0xfff) ) + 0x= 1000; + } // aligend to 4k Boundary + NumberofPages =3D AlignedSize/0x1000; + // + // Allocate memory (below 4GB) + // + Pointer =3D 0xffffffff; + Status =3D gBS->AllocatePages ( + AllocateMaxAddress, + EfiReservedMemoryType, + NumberofPages, + &Pointer // Base address need to be 4K aligned for VT-d= RMRR + ); + ASSERT_EFI_ERROR (Status); + + if (DmaRemap->VTdSupport) { + // + // RMRR + // + mRmrr.DeviceScope =3D &DevScopeRmrr[0]; + // + // Calculate the right size of DevScope for mRmrr entry + // + mRmrr.DeviceScopeNumber =3D sizeof(DevScopeRmrr) / sizeof(DEVICE_SCOPE= ); + mRmrr.RsvdMemBase =3D (UINT64)Pointer; + mRmrr.RsvdMemLimit =3D mRmrr.RsvdMemBase + AlignedSize - 1; + DEBUG ((DEBUG_INFO, "[ACPI](DMAR) RMRR Base 0x%llX, Limit 0x%llX\n", m= Rmrr.RsvdMemBase, mRmrr.RsvdMemLimit)); + DmaRemap->InsertDmaRemap (DmaRemap, RmrrType, &mRmrr); + } + gBS->FreePool (PciNode); + gBS->FreePool (DevScope); + + return EFI_SUCCESS; +} + + +/** + Install ACPI DMAR table for VT-d. + + This function needs gEfiPciIoProtocolGuid so it can run only after PCI E= numeraion is complete. + + @retval EFI_SUCCESS DMAR installed successfuly. + @retval EFI_NOT_FOUND gEfiPciIoProtocolGuid or gDmaRemapProtocolG= uid not found. + @retval EFI_OUT_OF_RESOURCES Could not allocate resources. +**/ +EFI_STATUS +AcpiVtdTablesInstall ( + VOID + ) +{ + EFI_STATUS Status; + EFI_ACPI_TABLE_VERSION TableVersion; + DMA_REMAP_PROTOCOL *DmaRemap; + UINTN TableHandle; + EFI_ACPI_COMMON_HEADER *CurrentTable; + EFI_ACPI_TABLE_PROTOCOL *AcpiTable; + + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + UINTN Index; + EFI_PCI_IO_PROTOCOL *PciIo; + PCI_TYPE01 PciConfigHeader; + UINTN Segment; + UINTN Bus; + UINTN Device; + UINTN Function; + UINT8 PciExpressOffset; + UINT32 AcsOffset; + UINT16 PciExpressCapabilityReg; + UINT8 AcsCapCount; + UINT16 RequiredAcsCap; + UINT32 AcsCapRegValue; + UINT16 AcsConRegValue; + USRA_PCIE_ADDR_TYPE *AcsDevArray; + USRA_ADDRESS Address; + + DYNAMIC_SI_LIBARY_PROTOCOL *DynamicSiLibraryProtocol =3D NULL; + + Status =3D gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, &D= ynamicSiLibraryProtocol); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return EFI_NOT_FOUND; + } + + PciExpressOffset =3D 0; + AcsOffset =3D 0; + AcsCapCount =3D 0; + AcsCapRegValue =3D 0; + AcsConRegValue =3D 0; + RequiredAcsCap =3D ACS_SOURCE_VALIDATION | ACS_P2P_REQUEST_REDIRECT |= ACS_P2P_COMPLETION_REDIRECT | ACS_UPSTREAM_FORWARDING; + + // + // Locate all PciIo protocols + // + Status =3D gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiPciIoProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + + DEBUG((DEBUG_ERROR, "[ACPI](DMAR) ERROR: Cannot locate gEfiPciIoProtoc= olGuid (%r)\n", Status)); + ASSERT (FALSE); + return Status; + } + AcsDevArray =3D AllocateZeroPool (sizeof (USRA_PCIE_ADDR_TYPE) * HandleC= ount); + if (AcsDevArray =3D=3D NULL) { + ASSERT (AcsDevArray !=3D NULL); + return EFI_OUT_OF_RESOURCES; + } + + for (Index =3D 0; Index < HandleCount; Index ++) { + + gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, &Pci= Io); + PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0, sizeof(PciConfigHeader= ) / sizeof(UINT32), &PciConfigHeader); + if ((PciConfigHeader.Hdr.ClassCode[0] =3D=3D 0x00 || PciConfigHeader.H= dr.ClassCode[0] =3D=3D 0x01) && PciConfigHeader.Hdr.ClassCode[1] =3D=3D 0x0= 4 && PciConfigHeader.Hdr.ClassCode[2] =3D=3D 0x06) { + // + // 060400h or 060401h indicates it's PCI-PCI bridge, get its bus num= ber, device number and function number + // + + PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function); + + USRA_PCIE_SEG_ADDRESS(Address, UsraWidth16, Segment, Bus, Device, Fu= nction, 0); + + if (PciConfigHeader.Hdr.Status =3D=3D EFI_PCI_STATUS_CAPABILITY) { + // + // the bridge support Capability list and offset 0x34 is the point= er to the data structure + // + // Detect if PCI Express Device + // + Status =3D LocateCapRegBlock (PciIo, EFI_PCI_CAPABILITY_ID_PCIEXP,= &PciExpressOffset, NULL); + + if (Status =3D=3D EFI_SUCCESS) { + // + // this bridge device is a PCI Express bridge + // Check if it is downstream port of PCIE switch + // + Address.Pcie.Offset =3D PciExpressOffset + EFI_PCI_EXPRESS_CAPAB= ILITY_REGISTER; + DynamicSiLibraryProtocol->RegisterRead(&Address, &PciExpressCapa= bilityReg); + + // + // BIT 7:4 indicate Device/port type, 0110b indicates downstream= port of PCI express switch + // + if ((PciExpressCapabilityReg & 0x00F0) =3D=3D 0x60) { + // + // it is downstream port of PCI Express switch + // Look for ACS capability register in PCI express configurati= on space + // + Status =3D LocatePciExpressCapRegBlock (PciIo, EFI_PCIE_CAPABI= LITY_ID_ACS, &AcsOffset, NULL); + DEBUG((DEBUG_ERROR, "ACS capable port is B%x.D%x.F%x - ACS Cap= offset - 0x%x\n", Bus, Device, Function, AcsOffset)); + + if (Status =3D=3D EFI_SUCCESS) { + // + // Read ACS capability register + // + Address.Pcie.Offset =3D AcsOffset + ACS_CAPABILITY_REGISTER; + Address.Attribute.AccessWidth =3D UsraWidth32; + DynamicSiLibraryProtocol->RegisterRead(&Address, &AcsCapRegV= alue); + DEBUG((DEBUG_INFO, "Bus =3D%x, Device=3D%x, Function=3D%x, A= csCapRegValue =3D %x \n", Bus, Device, Function, AcsCapRegValue)); + + if ((AcsCapRegValue & RequiredAcsCap) =3D=3D RequiredAcsCap)= { + // + // The PCI express downstream port support ACS, record thi= s port + // + AcsDevArray[AcsCapCount].Bus =3D (UINT32)Bus; + AcsDevArray[AcsCapCount].Dev =3D (UINT32)Device; + AcsDevArray[AcsCapCount].Func =3D (UINT32)Function; + AcsDevArray[AcsCapCount].Offset =3D AcsOffset; + AcsDevArray[AcsCapCount].Seg =3D (UINT32)Segment; + AcsCapCount++; + } + } + } + } + } + } + } /// End for + + // + // Free the Handle buffer + // + if (HandleBuffer !=3D NULL) { + gBS->FreePool (HandleBuffer); + } + + ASSERT (AcsCapCount <=3D HandleCount); + + // + // all PCI express switch downstream ports support ACS and meet the requ= ired ACS capabilities + // for each downstream ports, enable the required Capabilities in ACS co= ntrol register + // + Address.Attribute.AccessWidth =3D UsraWidth16; + for (Index =3D 0; Index < AcsCapCount; Index ++) { + // + // Program the corresponding bits in ACS control register + // + Address.Pcie =3D AcsDevArray[Index]; + Address.Pcie.Offset +=3D ACS_CONTROL_REGISTER; + DynamicSiLibraryProtocol->RegisterRead (&Address, &AcsConRegValue); + DEBUG ((DEBUG_ERROR, "AcsConRegValue is 0x%x\n", AcsConRegValue)); + AcsConRegValue |=3D (ACS_SOURCE_VALIDATION_ENABLE | ACS_P2P_REQUEST_RE= DIRECT_ENABLE | ACS_P2P_COMPLETION_REDIRECT_ENABLE | ACS_UPSTREAM_FORWARDIN= G_ENABLE); + DEBUG ((DEBUG_ERROR, "After Enable BITs AcsConRegValue is 0x%x\n", Acs= ConRegValue)); + DynamicSiLibraryProtocol->RegisterWrite (&Address, &AcsConRegValue); + // + // report VT-d and other features to OS/VMM, report DMAR and remapping= engine to OS/VMM + // + } + + // + // Find the AcpiSupport protocol + // + Status =3D LocateSupportProtocol (&gEfiAcpiTableProtocolGuid, gEfiAcpiTa= bleStorageGuid, &AcpiTable, FALSE); + ASSERT_EFI_ERROR (Status); + + TableVersion =3D EFI_ACPI_TABLE_VERSION_2_0; + + Status =3D gBS->LocateProtocol (&gDmaRemapProtocolGuid, NULL, &DmaRemap); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "[ACPI](DMAR) ERROR: Cannot locate gDmaRemapProto= colGuid (%r)\n", Status)); + } else { + if (DmaRemap->VTdSupport) { + ReportDmar (DmaRemap); + Status =3D DmaRemap->GetDmarTable (DmaRemap, &CurrentTable); + + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + } else { + // + // Perform any table specific updates. + // + Status =3D PlatformUpdateTables (CurrentTable, &TableVersion); + ASSERT_EFI_ERROR (Status); + + TableHandle =3D 0; + Status =3D AcpiTable->InstallAcpiTable ( + AcpiTable, + CurrentTable, + CurrentTable->Length, + &TableHandle + ); + ASSERT_EFI_ERROR (Status); + } + } + } + FreePool (AcsDevArray); + + return EFI_SUCCESS; +} + + +EFI_STATUS +LocateCapRegBlock ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT8 CapID, + OUT UINT8 *PciExpressOffset, + OUT UINT8 *NextRegBlock + ) +{ + UINT16 CapabilityID; + UINT32 Temp; + UINT8 CapabilityPtr; + UINT16 CapabilityEntry; + + PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint32, + PCI_CAPBILITY_POINTER_OFFSET, + 1, + &Temp + ); + + CapabilityPtr =3D (UINT8)Temp; + // + // According to the PCI spec a value of 0x00 + // is the end of the list + // + while (CapabilityPtr >=3D 0x40) { + // + // Mask it to DWORD alignment per PCI spec + // + CapabilityPtr &=3D 0xFC; + PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint16, + CapabilityPtr, + 1, + &CapabilityEntry + ); + + CapabilityID =3D (UINT8) CapabilityEntry; + + if (CapabilityID =3D=3D CapID) { + *PciExpressOffset =3D CapabilityPtr; + if (NextRegBlock !=3D NULL) { + *NextRegBlock =3D (UINT8) ((CapabilityEntry >> 8) & 0xFC); + } + + return EFI_SUCCESS; + } + + CapabilityPtr =3D (UINT8) ((CapabilityEntry >> 8) & 0xFC); + } + + return EFI_NOT_FOUND; +} + + +EFI_STATUS +LocatePciExpressCapRegBlock ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT16 CapID, + OUT UINT32 *Offset, + OUT UINT32 *NextRegBlock +) +{ + UINT32 CapabilityPtr; + UINT32 CapabilityEntry; + UINT16 CapabilityID; + + CapabilityPtr =3D EFI_PCIE_CAPABILITY_BASE_OFFSET; + + while ((CapabilityPtr !=3D 0) && (CapabilityPtr < 0x1000)) { + // + // Mask it to DWORD alignment per PCI spec + // + CapabilityPtr &=3D 0xFFC; + PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint32, + CapabilityPtr, + 1, + &CapabilityEntry + ); + + CapabilityID =3D (UINT16) CapabilityEntry; + + if (CapabilityID =3D=3D CapID) { + *Offset =3D CapabilityPtr; + if (NextRegBlock !=3D NULL) { + *NextRegBlock =3D (CapabilityEntry >> 20) & 0xFFF; + } + + return EFI_SUCCESS; + } + + CapabilityPtr =3D (CapabilityEntry >> 20) & 0xFFF; + } + + return EFI_NOT_FOUND; +} + + +VOID +DisableAriForwarding ( + VOID + ) +{ + EFI_STATUS Status; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + UINTN Index; + EFI_PCI_IO_PROTOCOL *PciIo; + PCI_TYPE01 PciConfigHeader; + UINTN Segment; + UINTN Bus; + UINTN Device; + UINTN Function; + UINT8 PciExpressOffset; + PCI_REG_PCIE_DEVICE_CONTROL2 DevCtl2; + + // + // Disable ARI forwarding before handoff to OS, as it may not be ARI-awa= re + // + // + // ARI forwarding exist in bridge + // + + // + // Locate all PciIo protocol + // + Status =3D gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiPciIoProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + for (Index =3D 0; Index < HandleCount; Index ++) { + gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiPciIoProtocolGuid, + &PciIo + ); + PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint32, + 0, + sizeof (PciConfigHeader) / sizeof (UINT32), + &PciConfigHeader + ); + if ((PciConfigHeader.Hdr.ClassCode[0] =3D=3D 0x00 || PciConfigHeader.H= dr.ClassCode[0] =3D=3D 0x01) && PciConfigHeader.Hdr.ClassCode[1] =3D=3D 0x0= 4 && PciConfigHeader.Hdr.ClassCode[2] =3D=3D 0x06) { + // + // 060400h or 060401h indicates it's PCI-PCI bridge, get its bus num= ber, device number and function number + // + PciIo->GetLocation ( + PciIo, + &Segment, + &Bus, + &Device, + &Function + ); + if (PciConfigHeader.Hdr.Status =3D=3D EFI_PCI_STATUS_CAPABILITY) { + // + // the bridge support Capability list and offset 0x34 is the point= er to the data structure + // + // + // Detect if PCI Express Device + // + Status =3D LocateCapRegBlock (PciIo, EFI_PCI_CAPABILITY_ID_PCIEXP,= &PciExpressOffset, NULL); + if (Status =3D=3D EFI_SUCCESS) { + // + // this bridge device is a PCI Express bridge, Check ARI forward= ing bit in Device Control 2 register + // + PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint16, + PciExpressOffset + OFFSET_OF (PCI_CAPABILITY_PCIEXP, Dev= iceControl2), + 1, + &DevCtl2 + ); + if (DevCtl2.Bits.AriForwarding) { + // + // ARI forwarding enable bit is set, we need to clear this bit= before handing off control to OS + // because OS may not ARI aware + // + DEBUG((DEBUG_INFO, "[VTD] %02X:%02X:%02X.%X: ARI forwarding di= sable before booting OS, DevCtl2 0x%02X -> 0x%02X\n", + Segment, Bus, Device, Function, DevCtl2.Uint16, DevCtl2= .Uint16 & ~BIT5)); + DevCtl2.Bits.AriForwarding =3D 0; + PciIo->Pci.Write ( + PciIo, + EfiPciIoWidthUint16, + PciExpressOffset + OFFSET_OF (PCI_CAPABILITY_PCIEXP, Dev= iceControl2), + 1, + &DevCtl2 + ); + } + } + } + } + } +} // DisableAriForwarding() diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dec b/Platform/= Intel/WhitleyOpenBoardPkg/PlatformPkg.dec index a80472e73c..27253b1a58 100644 --- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dec +++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dec @@ -24,6 +24,7 @@ =20 [Guids] gBiosInfoGuid =3D { 0x1b453c67, 0x= cb1a, 0x46ec, { 0x86, 0x4b, 0xe2, 0x24, 0xa6, 0xb7, 0xfe, 0xe8 } } + gEfiAcpiTableStorageGuid =3D { 0x7e374e25, 0x= 8e01, 0x4fee, { 0x87, 0xf2, 0x39, 0x0c, 0x23, 0xc6, 0x06, 0xcd } } gClvBootTimeTestExecution =3D { 0x3ff7d152, 0x= ef86, 0x47c3, { 0x97, 0xb0, 0xce, 0xd9, 0xbb, 0x80, 0x9a, 0x67 } } gUbaCurrentConfigHobGuid =3D { 0xe4b2025b, 0x= c7db, 0x4e5d, { 0xa6, 0x5e, 0x2b, 0x25, 0x7e, 0xb1, 0x5, 0x8e } } =20 @@ -181,6 +182,11 @@ gPlatformTokenSpaceGuid.PcdSupportLegacyStack|TRUE|BOOLEAN|0x30000030 gPlatformTokenSpaceGuid.PcdMaxOptionRomNumber|0x4|UINT8|0x30000031 =20 + # + # Debug Mode indicator + # + gPlatformTokenSpaceGuid.PcdDebugModeEnable|0x01|UINT8|0xE0000040 + gPlatformTokenSpaceGuid.PcdCmosDebugPrintLevelReg|0x4C|UINT8|0x30000032 =20 # Choose the default serial debug message level when CMOS is bad; in the= later BIOS phase, the setup default is applied @@ -238,11 +244,6 @@ gPlatformModuleTokenSpaceGuid.PcdPcIoApicInterruptBase|24|UINT32|0x90000= 018 =20 =20 - gPlatformModuleTokenSpaceGuid.PcdMaxCpuThreadCount|2|UINT32|0x90000021 - gPlatformModuleTokenSpaceGuid.PcdMaxCpuCoreCount|8|UINT32|0x90000022 - gPlatformModuleTokenSpaceGuid.PcdMaxCpuSocketCount|4|UINT32|0x90000023 - gPlatformModuleTokenSpaceGuid.PcdHpetTimerBlockId|0x8086A201|UINT32|0x90= 000024 - gPlatformModuleTokenSpaceGuid.PcdFadtPreferredPmProfile|0x02|UINT8|0x900= 00025 gPlatformModuleTokenSpaceGuid.PcdFadtIaPcBootArch|0x0001|UINT16|0x900000= 26 gPlatformModuleTokenSpaceGuid.PcdFadtFlags|0x000086A5|UINT32|0x90000027 diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc b/Platform/= Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc index 5dfee0eeb5..042c27c709 100644 --- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc +++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc @@ -809,7 +809,10 @@ =20 $(RP_PKG)/Features/Pci/Dxe/PciPlatform/PciPlatform.inf =20 +!if $(CPUTARGET) =3D=3D "ICX" + $(RP_PKG)/Features/Acpi/AcpiPlatform/AcpiPlatform.inf $(RP_PKG)/Features/Acpi/AcpiTables/AcpiTables10nm.inf +!endif $(RP_PKG)/Features/AcpiVtd/AcpiVtd.inf =20 $(PLATFORM_PKG)/Acpi/AcpiSmm/AcpiSmm.inf diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.fdf b/Platform/= Intel/WhitleyOpenBoardPkg/PlatformPkg.fdf index ca3514b8ba..ab594ff409 100644 --- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.fdf +++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.fdf @@ -671,7 +671,10 @@ SET gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize = =3D 0x01000000 INF BoardModulePkg/LegacySioDxe/LegacySioDxe.inf INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf =20 +!if $(CPUTARGET) =3D=3D "ICX" INF RuleOverride =3D ACPITABLE WhitleyOpenBoardPkg/Features/Acpi/AcpiTa= bles/AcpiTables10nm.inf + INF WhitleyOpenBoardPkg/Features/Acpi/AcpiPlatform/AcpiPlatform.inf +!endif INF WhitleyOpenBoardPkg/Features/AcpiVtd/AcpiVtd.inf INF MinPlatformPkg/Acpi/AcpiSmm/AcpiSmm.inf =20 diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaMain/StaticSkuDataDx= e/Readme.md b/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaMain/StaticSkuDataD= xe/Readme.md index 08fd02f922..58f9b88dae 100644 --- a/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaMain/StaticSkuDataDxe/Readm= e.md +++ b/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaMain/StaticSkuDataDxe/Readm= e.md @@ -16,4 +16,5 @@ The AmlOffsetTable.c file is generated in two key steps: =20 Common Issues: * The same iasl compiler version must be used to build the AML offset tabl= e and to build the DSDT. +* The same iasl compiler version must be used to build the AML offset tabl= e and to build the DSDT. With the addition of -so for building the AML off= set table. * The Board/*AmlOffsets*.dsc file name, Board/*AmlOffsets* directory name,= Board/AmlOffsets/*AmlOffsets*.inf file name, and the BASE_NAME in *AmlOffs= ets*.inf must all match exactly. diff --git a/Platform/Intel/WhitleyOpenBoardPkg/WilsonCityRvp/AmlOffsets/Am= lOffsets.inf b/Platform/Intel/WhitleyOpenBoardPkg/WilsonCityRvp/AmlOffsets/= AmlOffsets.inf index 8945f372e3..859875ab5b 100644 --- a/Platform/Intel/WhitleyOpenBoardPkg/WilsonCityRvp/AmlOffsets/AmlOffset= s.inf +++ b/Platform/Intel/WhitleyOpenBoardPkg/WilsonCityRvp/AmlOffsets/AmlOffset= s.inf @@ -23,4 +23,4 @@ =20 [BuildOptions] # add -vr and -so to generate offset.h - *_*_*_ASL_FLAGS =3D -oi -vr -so + *_*_*_ASL_FLAGS =3D -so --=20 2.27.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#87431): https://edk2.groups.io/g/devel/message/87431 Mute This Topic: https://groups.io/mt/89698853/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat May 18 21:45:23 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+87433+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+87433+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1646952118; cv=none; d=zohomail.com; s=zohoarc; b=l/XLJKkYwJVd3R6s7GgYuY+8qKiIHzCkx5PwunxtHoychdIaiaCw5xf45hRAaRvKqnDz1+b7qnhOC032JZ46fGcY7uVKaCF626ZbiF8Kyca+y2XagDx58HHrCBcsZqKaSpuY3AZj7crV/6/Azun/2Eb5WRMn8rFj+/oP0XWnAGA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1646952118; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=N6x0aA/4C0rd4Z8QQHm7QAeuskmF1zM2Sw66pCsoT4U=; b=DHSW2CZ5b+jVEtKOqm+hqZbuiCWTLL07P6sufdDOPiivC7hBwkYVR7SOOG6PD/+d8T3yzNzma5eBtWSmf/XNbJQFnxTeg87HqfNgA0W/Qws5Alra6ELQ5KItXqCn+U6WFCW4MNZs/jw/458q4GbkWHzYzH+LmQNfrkYLJU/7LPg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+87433+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1646952118972154.43618503359755; Thu, 10 Mar 2022 14:41:58 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id A7M2YY1788612xAfQPt89jZm; Thu, 10 Mar 2022 14:41:58 -0800 X-Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mx.groups.io with SMTP id smtpd.web12.860.1646952112302807460 for ; Thu, 10 Mar 2022 14:41:53 -0800 X-IronPort-AV: E=McAfee;i="6200,9189,10282"; a="316121258" X-IronPort-AV: E=Sophos;i="5.90,171,1643702400"; d="scan'208";a="316121258" X-Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2022 14:41:35 -0800 X-IronPort-AV: E=Sophos;i="5.90,171,1643702400"; d="scan'208";a="644643391" X-Received: from iworam-desk.amr.corp.intel.com ([10.7.150.60]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2022 14:41:35 -0800 From: "Oram, Isaac W" To: devel@edk2.groups.io Cc: Nate DeSimone , Chasel Chiu Subject: [edk2-devel][edk2-platforms][PATCH V1 9/9] WhitleyOpenBoardPkg/Build: Remove confusing build options Date: Thu, 10 Mar 2022 14:41:14 -0800 Message-Id: <913dc55a294c52a74ff62db2c99854119eccde6c.1646951441.git.isaac.w.oram@intel.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,isaac.w.oram@intel.com X-Gm-Message-State: lW8FRifYY3SUgBHDTm0jVakkx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1646952118; bh=QthtYab63nfCGIS/cXguehJX9/asgsQ9a+wU0eUbp2Y=; h=Cc:Date:From:Reply-To:Subject:To; b=grcnh/sKZ2vvDNn1ypn17KioBT+maCOav13KbmGbOO/G0jE7kVa79tZyNlKpiAIHG5H CDf3jzwEozpdofGU7i9qqTuMC6aqRth9zFjVZ4z3R6W66NtsFPwZa1sDMMMoGT+/igjDb fLxtsKK7jrS5/VIt/G9wceHe/YoZYJusTvw= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1646952120270100014 Content-Type: text/plain; charset="utf-8" There is an unnecessary inheritance of a SKX build option that has confused the build settings. Removed unused IE_ENABLE, PCH_PKG_OPTIONS, and SECURITY_OPTIONS Fix a bug where changes in PlatformPkgConfig.dsc were not taking effect because of missing [Defines] context. Cc: Nate DeSimone Cc: Chasel Chiu Signed-off-by: Isaac Oram Reviewed-by: Nate DeSimone --- Platform/Intel/WhitleyOpenBoardPkg/Include/Dsc/BuildOptions.dsc | 1= 2 ++++-------- Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc | = 8 ++++---- Platform/Intel/WhitleyOpenBoardPkg/PlatformPkgConfig.dsc | = 7 +------ Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaDxeRpBoards.fdf | = 6 ++++-- Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaRpBoards.dsc | = 6 ++++-- Silicon/Intel/WhitleySiliconPkg/Product/Whitley/SiliconPkg10nmPcds.dsc | = 4 ++-- 6 files changed, 19 insertions(+), 24 deletions(-) diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Include/Dsc/BuildOptions.ds= c b/Platform/Intel/WhitleyOpenBoardPkg/Include/Dsc/BuildOptions.dsc index 1a85a26e25..068ca195bf 100644 --- a/Platform/Intel/WhitleyOpenBoardPkg/Include/Dsc/BuildOptions.dsc +++ b/Platform/Intel/WhitleyOpenBoardPkg/Include/Dsc/BuildOptions.dsc @@ -55,20 +55,16 @@ DEFINE NVDIMM_OPTIONS =3D =20 !if $(CPUTARGET) =3D=3D "ICX" DEFINE CPU_TYPE_OPTIONS =3D -D ICX_HOST -D A0_HOST -D B0_HOST + DEFINE MAX_IMC_CH_OPTIONS =3D -D MAX_IMC=3D4 -D MAX_MC_CH=3D2 !elseif $(CPUTARGET) =3D=3D "CPX" DEFINE CPU_TYPE_OPTIONS =3D -D SKX_HOST -D CLX_HOST -D CPX_HOST -D A0_H= OST -D B0_HOST + DEFINE MAX_IMC_CH_OPTIONS =3D -D MAX_IMC=3D2 -D MAX_MC_CH=3D3 !endif =20 DEFINE MAX_SOCKET_CORE_THREAD_OPTIONS =3D -D MAX_SOCKET=3D$(MAX_SOCKET) -D= MAX_CORE=3D$(MAX_CORE) -D MAX_THREAD=3D$(MAX_THREAD) =20 DEFINE MRC_OPTIONS =3D -D LRDIMM_SUPPORT -D DDRT_SUPPORT =20 -!if $(CPU_SKX_ONLY_SUPPORT) =3D=3D FALSE - DEFINE MAX_IMC_CH_OPTIONS =3D -D MAX_IMC=3D4 -D MAX_MC_CH=3D2 -!else - DEFINE MAX_IMC_CH_OPTIONS =3D -D MAX_IMC=3D2 -D MAX_MC_CH=3D3 -!endif - DEFINE MAX_SAD_RULE_OPTION =3D -D MAX_SAD_RULES=3D24 -D MAX_DRAM_CLUSTERS= =3D1 =20 DEFINE LT_BUILD_OPTIONS =3D -D LT_FLAG @@ -88,9 +84,9 @@ DEFINE IIO_STACK_OPTIONS =3D -D MAX_IIO_STACK=3D6 -D MAX_= LOGIC_IIO_STACK=3D8 =20 DEFINE PCH_BIOS_BUILD_OPTIONS =3D $(PCH_BUILD_OPTION) $(SC_PATH) $(SERVER_= BUILD_OPTION) =20 -DEFINE EDKII_DSC_FEATURE_BUILD_OPTIONS =3D $(CRB_EDKII_BUILD_OPTIONS) $(ED= KII_DEBUG_BUILD_OPTIONS) $(PCH_BIOS_BUILD_OPTIONS) $(PCH_PKG_OPTIONS) $(MAX= _SOCKET_CORE_THREAD_OPTIONS) $(MAX_IMC_CH_OPTIONS) $(MAX_SAD_RULE_OPTION) $= (KTI_OPTIONS) $(IIO_STACK_OPTIONS) $(LT_BUILD_OPTIONS) $(SECURITY_OPTIONS) = $(SPARING_SCRATCHPAD_OPTION) $(SCRATCHPAD_DEBUG_OPTION) $(NVDIMM_OPTIONS) -= D EFI_PCI_IOV_SUPPORT -D WHEA_SUPPORT $(CPU_TYPE_OPTIONS) -D MMCFG_BASE_ADD= RESS=3D0x80000000 -D DISABLE_NEW_DEPRECATED_INTERFACES $(MRC_OPTIONS) $(FSP= _BUILD_OPTIONS) +DEFINE EDKII_DSC_FEATURE_BUILD_OPTIONS =3D $(CRB_EDKII_BUILD_OPTIONS) $(ED= KII_DEBUG_BUILD_OPTIONS) $(PCH_BIOS_BUILD_OPTIONS) $(MAX_SOCKET_CORE_THREAD= _OPTIONS) $(MAX_IMC_CH_OPTIONS) $(MAX_SAD_RULE_OPTION) $(KTI_OPTIONS) $(IIO= _STACK_OPTIONS) $(LT_BUILD_OPTIONS) $(SPARING_SCRATCHPAD_OPTION) $(SCRATCHP= AD_DEBUG_OPTION) $(NVDIMM_OPTIONS) -D EFI_PCI_IOV_SUPPORT -D WHEA_SUPPORT $= (CPU_TYPE_OPTIONS) -D MMCFG_BASE_ADDRESS=3D0x80000000 -D DISABLE_NEW_DEPREC= ATED_INTERFACES $(MRC_OPTIONS) $(FSP_BUILD_OPTIONS) =20 -DEFINE IE_OPTIONS =3D $(IE_PATH) -DIE_SUPPORT=3D0 +DEFINE IE_OPTIONS =3D $(IE_PATH) =20 !if $(LINUX_GCC_BUILD) =3D=3D TRUE DEFINE EDK2_LINUX_BUILD_OPTIONS =3D -D EDK2_CTE_BUILD diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc b/Platform/= Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc index 042c27c709..8c4b9cf6ce 100644 --- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc +++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc @@ -169,7 +169,7 @@ ## This PCD specifies whether FPGA routine will be active gSocketPkgFpgaGuid.PcdSktFpgaActive|TRUE =20 -!if $(CPU_SKX_ONLY_SUPPORT) =3D=3D TRUE +!if $(CPUTARGET) =3D=3D "CPX" gEfiCpRcPkgTokenSpaceGuid.PerBitMargin|FALSE gEfiCpRcPkgTokenSpaceGuid.PcdSeparateCwlAdj|TRUE !endif @@ -343,7 +343,7 @@ # Disable Fast Warm Boot for Whitley Openboard Package gEfiCpRcPkgTokenSpaceGuid.PcdMrcFastBootDefault|FALSE =20 -!if $(CPU_SKX_ONLY_SUPPORT) =3D=3D FALSE +!if $(CPUTARGET) =3D=3D "ICX" gCpuUncoreTokenSpaceGuid.PcdWaSerializationEn|FALSE gEfiCpRcPkgTokenSpaceGuid.PcdMrcCmdVrefCenteringTrainingEnable|FALSE !endif @@ -426,7 +426,7 @@ # =20 gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07 # = Enable status codes for debug, progress, and errors - gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000042 # = Displayed messages: Error, Info, warn + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000047 # = Displayed messages: Error, Info, warn =20 gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0x80000000 gUefiCpuPkgTokenSpaceGuid.PcdCpuNumberOfReservedVariableMtrrs|0 @@ -856,7 +856,7 @@ DEFINE CPU_CPX_SUPPORT =3D FALSE !endif [PcdsFixedAtBuild] -!if ($(CPU_SKX_ONLY_SUPPORT) =3D=3D TRUE) +!if $(CPUTARGET) =3D=3D "CPX" gSiPkgTokenSpaceGuid.PcdPostedCsrAccessSupported |FALSE !endif [LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.UEFI_DRIVER, Libr= aryClasses.common.UEFI_APPLICATION] diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkgConfig.dsc b/Pla= tform/Intel/WhitleyOpenBoardPkg/PlatformPkgConfig.dsc index ecfdb895ba..a4ac8b6935 100644 --- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkgConfig.dsc +++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkgConfig.dsc @@ -11,6 +11,7 @@ # TRUE is ENABLE. FALSE is DISABLE. # =20 +[Defines] DEFINE CRB_FLAG_ENABLE =3D TRUE DEFINE DEBUG_FLAGS_ENABLE =3D FALSE =20 @@ -19,12 +20,6 @@ DEFINE PERFORMANCE_ENABLE =3D TRUE DEFINE SERVER_BIOS_ENABLE =3D TRUE DEFINE PCH_SERVER_BIOS_ENABLE =3D TRUE =20 -!if $(CPUTARGET) =3D=3D "CPX" - DEFINE CPU_SKX_ONLY_SUPPORT =3D TRUE -!else - DEFINE CPU_SKX_ONLY_SUPPORT =3D FALSE -!endif - !if $(CPUTARGET) =3D=3D "CPX" DEFINE CPU_CPX_SUPPORT =3D TRUE !else diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaDxeRpBoards.fdf b/Pl= atform/Intel/WhitleyOpenBoardPkg/Uba/UbaDxeRpBoards.fdf index 7c182db5df..6010637a73 100644 --- a/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaDxeRpBoards.fdf +++ b/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaDxeRpBoards.fdf @@ -8,9 +8,11 @@ ## =20 # -# Currently shared by all platforms +# Currently shared by all ICX platforms # -INF $(RP_PKG)/Uba/UbaMain/StaticSkuDataDxe/StaticSkuDataDxe.inf +!if $(CPUTARGET) =3D=3D "ICX" + INF $(RP_PKG)/Uba/UbaMain/StaticSkuDataDxe/StaticSkuDataDxe.inf +!endif =20 # # Platform TypeWilsonCityRP diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaRpBoards.dsc b/Platf= orm/Intel/WhitleyOpenBoardPkg/Uba/UbaRpBoards.dsc index 48b26de427..477745df07 100644 --- a/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaRpBoards.dsc +++ b/Platform/Intel/WhitleyOpenBoardPkg/Uba/UbaRpBoards.dsc @@ -31,9 +31,11 @@ $(RP_PKG)/Uba/BoardInit/Pei/BoardInitPei.inf { =20 [Components.X64] # -# Currently shared by all platforms +# Currently shared by all ICX platforms # -$(RP_PKG)/Uba/UbaMain/StaticSkuDataDxe/StaticSkuDataDxe.inf +!if $(CPUTARGET) =3D=3D "ICX" + $(RP_PKG)/Uba/UbaMain/StaticSkuDataDxe/StaticSkuDataDxe.inf +!endif =20 # # Platform TypeWilsonCityRP diff --git a/Silicon/Intel/WhitleySiliconPkg/Product/Whitley/SiliconPkg10nm= Pcds.dsc b/Silicon/Intel/WhitleySiliconPkg/Product/Whitley/SiliconPkg10nmPc= ds.dsc index 4402540f91..f9c588b61c 100644 --- a/Silicon/Intel/WhitleySiliconPkg/Product/Whitley/SiliconPkg10nmPcds.dsc +++ b/Silicon/Intel/WhitleySiliconPkg/Product/Whitley/SiliconPkg10nmPcds.dsc @@ -52,7 +52,7 @@ # for 10nm # =20 -!if $(CPU_SKX_ONLY_SUPPORT) =3D=3D TRUE +!if $(CPUTARGET) =3D=3D "CPX" =20 gEfiCpRcPkgTokenSpaceGuid.PcdMrcBdatDefault|FALSE gEfiCpRcPkgTokenSpaceGuid.PcdMrcWritePreambleTclkDefault|0x0 @@ -96,4 +96,4 @@ # # enable NVDIMM support # - gEfiCpRcPkgTokenSpaceGuid.PcdNvDimmEn|TRUE \ No newline at end of file + gEfiCpRcPkgTokenSpaceGuid.PcdNvDimmEn|TRUE --=20 2.27.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#87433): https://edk2.groups.io/g/devel/message/87433 Mute This Topic: https://groups.io/mt/89698855/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-