From nobody Mon Feb 9 22:23:34 2026 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 --- 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-