From nobody Fri Apr 26 02:55:24 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+46943+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+46943+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1567719522; cv=none; d=zoho.com; s=zohoarc; b=XQmNyD7tr/QQ+k0OiZsvYsJga/8RKrr2PjSCIG/Zcou252IASffhDJ15Xn3onz86yIic/ylEtN3GgH676u1ahK3s2vinahDV9/IbPUMlr5ZtG5e0LXgU5kIlz03cLjfx0R8eaJpk3pSjzjCBXcBfCI5Bl16M27GuSSLMF+fN+qQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1567719522; h=Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To:ARC-Authentication-Results; bh=XWFO7po/SKFEdCuigQ8u1Mu9So4hd7j4Rz1wTg9YqHg=; b=QwvUB/wbE70L6gT06/abvtMuz1Mu4/Z/TRoXSNjPVTwWg/c2DZgqvWDnyqlm0qLemG2l4p9pu9NNJQGoYfn5eTET1I3gSpO11OuIJg2OdT1d+NDmbTnHCgXBqKSj4LyxsAew7oHMkjBSYUJ61RW16CRbeVOG1IBmTnGfkGZVtlc= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+46943+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1567719522709656.2613074781026; Thu, 5 Sep 2019 14:38:42 -0700 (PDT) Return-Path: X-Received: from mga11.intel.com (mga11.intel.com []) by groups.io with SMTP; Thu, 05 Sep 2019 14:38:41 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Sep 2019 14:38:40 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,471,1559545200"; d="scan'208";a="267151613" X-Received: from ydwei-desk.amr.corp.intel.com ([10.24.15.168]) by orsmga001.jf.intel.com with ESMTP; 05 Sep 2019 14:38:40 -0700 From: "David Wei" To: devel@edk2.groups.io Cc: Hao Wu , Liming Gao , Ankit Sinha , Agyeman Prince , Kubacki Michael A , Nate DeSimone , Michael D Kinney Subject: [edk2-devel] [edk2-platforms PATCH v5 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58 Date: Thu, 5 Sep 2019 14:38:34 -0700 Message-Id: In-Reply-To: References: In-Reply-To: References: Precedence: Bulk List-Unsubscribe: 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,david.y.wei@intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1567719522; bh=nimVf6xik5U1ybGYz/LNNUDUC9Kua+XOTA+rmmuMq/s=; h=Cc:Date:From:Reply-To:Subject:To; b=N1wN5em8XiHrK0JUmkmF44M2lgohzhpKjiVYhBV3s1j4bDAZjGX/JSGBuG2Nwlojmq8 wInkfrQ/2RsVGDixX6YFyqLk5fXEanG3OJvyw5urEt7kVEUM6AumlcmwdqKS+nVt5oiq8 rKomkX4PxjbAasXa8SWfbEf/maNs2KP3eOw= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add CPU Pkg for SimicsX58. It is added for simics Quick Start Platform proj= ect support Cc: Hao Wu Cc: Liming Gao Cc: Ankit Sinha Cc: Agyeman Prince Cc: Kubacki Michael A Cc: Nate DeSimone Cc: Michael D Kinney Signed-off-by: David Wei --- .../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c | 148 +++++++++ .../SimicsX58SktPkg/Smm/Access/SmmAccessPei.c | 346 +++++++++++++++++= ++++ .../SimicsX58SktPkg/Smm/Access/SmramInternal.c | 200 ++++++++++++ .../Include/Register/X58SmramSaveStateMap.h | 178 +++++++++++ Silicon/Intel/SimicsX58SktPkg/SktPkg.dec | 37 +++ Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc | 14 + .../Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf | 9 + .../Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf | 10 + Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf | 16 + .../Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf | 14 + .../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf | 54 ++++ .../SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf | 65 ++++ .../SimicsX58SktPkg/Smm/Access/SmramInternal.h | 82 +++++ 13 files changed, 1173 insertions(+) create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c create mode 100644 Silicon/Intel/SimicsX58SktPkg/Include/Register/X58Smram= SaveStateMap.h create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPkg.dec create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.= inf create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.i= nf create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c b/Sil= icon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c new file mode 100644 index 0000000000..5d3b2c14aa --- /dev/null +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c @@ -0,0 +1,148 @@ +/** @file + A DXE_DRIVER providing SMRAM access by producing EFI_SMM_ACCESS2_PROTOCO= L. + + X58 TSEG is expected to have been verified and set up by the SmmAccessPei + driver. + + Copyright (C) 2013, 2015, Red Hat, Inc.
+ Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include + +#include "SmramInternal.h" + +/** + Opens the SMRAM area to be accessible by a boot-service driver. + + This function "opens" SMRAM so that it is visible while not inside of SM= M. + The function should return EFI_UNSUPPORTED if the hardware does not supp= ort + hiding of SMRAM. The function should return EFI_DEVICE_ERROR if the SMRAM + configuration is locked. + + @param[in] This The EFI_SMM_ACCESS2_PROTOCOL instance. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_UNSUPPORTED The system does not support opening and closin= g of + SMRAM. + @retval EFI_DEVICE_ERROR SMRAM cannot be opened, perhaps because it is + locked. +**/ +STATIC +EFI_STATUS +EFIAPI +SmmAccess2DxeOpen ( + IN EFI_SMM_ACCESS2_PROTOCOL *This + ) +{ + return SmramAccessOpen (&This->LockState, &This->OpenState); +} + +/** + Inhibits access to the SMRAM. + + This function "closes" SMRAM so that it is not visible while outside of = SMM. + The function should return EFI_UNSUPPORTED if the hardware does not supp= ort + hiding of SMRAM. + + @param[in] This The EFI_SMM_ACCESS2_PROTOCOL instance. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_UNSUPPORTED The system does not support opening and closin= g of + SMRAM. + @retval EFI_DEVICE_ERROR SMRAM cannot be closed. +**/ +STATIC +EFI_STATUS +EFIAPI +SmmAccess2DxeClose ( + IN EFI_SMM_ACCESS2_PROTOCOL *This + ) +{ + return SmramAccessClose (&This->LockState, &This->OpenState); +} + +/** + Inhibits access to the SMRAM. + + This function prohibits access to the SMRAM region. This function is us= ually + implemented such that it is a write-once operation. + + @param[in] This The EFI_SMM_ACCESS2_PROTOCOL instance. + + @retval EFI_SUCCESS The device was successfully locked. + @retval EFI_UNSUPPORTED The system does not support locking of SMRAM. +**/ +STATIC +EFI_STATUS +EFIAPI +SmmAccess2DxeLock ( + IN EFI_SMM_ACCESS2_PROTOCOL *This + ) +{ + return SmramAccessLock (&This->LockState, &This->OpenState); +} + +/** + Queries the memory controller for the possible regions that will support + SMRAM. + + @param[in] This The EFI_SMM_ACCESS2_PROTOCOL instance. + @param[in,out] SmramMapSize A pointer to the size, in bytes, of the + SmramMemoryMap buffer. + @param[in,out] SmramMap A pointer to the buffer in which firmware + places the current memory map. + + @retval EFI_SUCCESS The chipset supported the given resource. + @retval EFI_BUFFER_TOO_SMALL The SmramMap parameter was too small. The + current buffer size needed to hold the mem= ory + map is returned in SmramMapSize. +**/ +STATIC +EFI_STATUS +EFIAPI +SmmAccess2DxeGetCapabilities ( + IN CONST EFI_SMM_ACCESS2_PROTOCOL *This, + IN OUT UINTN *SmramMapSize, + IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap + ) +{ + return SmramAccessGetCapabilities (This->LockState, This->OpenState, + SmramMapSize, SmramMap); +} + +// +// LockState and OpenState will be filled in by the entry point. +// +STATIC EFI_SMM_ACCESS2_PROTOCOL mAccess2 =3D { + &SmmAccess2DxeOpen, + &SmmAccess2DxeClose, + &SmmAccess2DxeLock, + &SmmAccess2DxeGetCapabilities +}; + +// +// Entry point of this driver. +// +EFI_STATUS +EFIAPI +SmmAccess2DxeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + // + // This module should only be included if SMRAM support is required. + // + ASSERT (FeaturePcdGet (PcdSmmSmramRequire)); + + GetStates (&mAccess2.LockState, &mAccess2.OpenState); + return gBS->InstallMultipleProtocolInterfaces (&ImageHandle, + &gEfiSmmAccess2ProtocolGuid, &mAccess2, + NULL); +} diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c b/Sili= con/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c new file mode 100644 index 0000000000..c54026b4d1 --- /dev/null +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c @@ -0,0 +1,346 @@ +/** @file + A PEIM with the following responsibilities: + + - verify & configure the X58 TSEG in the entry point, + - provide SMRAM access by producing PEI_SMM_ACCESS_PPI, + - set aside the SMM_S3_RESUME_STATE object at the bottom of TSEG, and ex= pose + it via the gEfiAcpiVariableGuid GUID HOB. + + This PEIM runs from RAM, so we can write to variables with static storage + duration. + + Copyright (C) 2013, 2015, Red Hat, Inc.
+ Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "SmramInternal.h" + +// +// PEI_SMM_ACCESS_PPI implementation. +// + +/** + Opens the SMRAM area to be accessible by a PEIM driver. + + This function "opens" SMRAM so that it is visible while not inside of SM= M. + The function should return EFI_UNSUPPORTED if the hardware does not supp= ort + hiding of SMRAM. The function should return EFI_DEVICE_ERROR if the SMRAM + configuration is locked. + + @param PeiServices General purpose services available to eve= ry + PEIM. + @param This The pointer to the SMM Access Interface. + @param DescriptorIndex The region of SMRAM to Open. + + @retval EFI_SUCCESS The region was successfully opened. + @retval EFI_DEVICE_ERROR The region could not be opened because lo= cked + by chipset. + @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds. + +**/ +STATIC +EFI_STATUS +EFIAPI +SmmAccessPeiOpen ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_SMM_ACCESS_PPI *This, + IN UINTN DescriptorIndex + ) +{ + if (DescriptorIndex >=3D DescIdxCount) { + return EFI_INVALID_PARAMETER; + } + + // + // According to current practice, DescriptorIndex is not considered at a= ll, + // beyond validating it. + // + return SmramAccessOpen (&This->LockState, &This->OpenState); +} + +/** + Inhibits access to the SMRAM. + + This function "closes" SMRAM so that it is not visible while outside of = SMM. + The function should return EFI_UNSUPPORTED if the hardware does not supp= ort + hiding of SMRAM. + + @param PeiServices General purpose services available to e= very + PEIM. + @param This The pointer to the SMM Access Interface. + @param DescriptorIndex The region of SMRAM to Close. + + @retval EFI_SUCCESS The region was successfully closed. + @retval EFI_DEVICE_ERROR The region could not be closed because + locked by chipset. + @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds. + +**/ +STATIC +EFI_STATUS +EFIAPI +SmmAccessPeiClose ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_SMM_ACCESS_PPI *This, + IN UINTN DescriptorIndex + ) +{ + if (DescriptorIndex >=3D DescIdxCount) { + return EFI_INVALID_PARAMETER; + } + + // + // According to current practice, DescriptorIndex is not considered at a= ll, + // beyond validating it. + // + return SmramAccessClose (&This->LockState, &This->OpenState); +} + +/** + Inhibits access to the SMRAM. + + This function prohibits access to the SMRAM region. This function is us= ually + implemented such that it is a write-once operation. + + @param PeiServices General purpose services available to e= very + PEIM. + @param This The pointer to the SMM Access Interface. + @param DescriptorIndex The region of SMRAM to Close. + + @retval EFI_SUCCESS The region was successfully locked. + @retval EFI_DEVICE_ERROR The region could not be locked because at + least one range is still open. + @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds. + +**/ +STATIC +EFI_STATUS +EFIAPI +SmmAccessPeiLock ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_SMM_ACCESS_PPI *This, + IN UINTN DescriptorIndex + ) +{ + if (DescriptorIndex >=3D DescIdxCount) { + return EFI_INVALID_PARAMETER; + } + + // + // According to current practice, DescriptorIndex is not considered at a= ll, + // beyond validating it. + // + return SmramAccessLock (&This->LockState, &This->OpenState); +} + +/** + Queries the memory controller for the possible regions that will support + SMRAM. + + @param PeiServices General purpose services available to every + PEIM. + @param This The pointer to the SmmAccessPpi Interface. + @param SmramMapSize The pointer to the variable containing siz= e of + the buffer to contain the description + information. + @param SmramMap The buffer containing the data describing = the + Smram region descriptors. + + @retval EFI_BUFFER_TOO_SMALL The user did not provide a sufficient buff= er. + @retval EFI_SUCCESS The user provided a sufficiently-sized buf= fer. + +**/ +STATIC +EFI_STATUS +EFIAPI +SmmAccessPeiGetCapabilities ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_SMM_ACCESS_PPI *This, + IN OUT UINTN *SmramMapSize, + IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap + ) +{ + return SmramAccessGetCapabilities (This->LockState, This->OpenState, Smr= amMapSize, SmramMap); +} + +// +// LockState and OpenState will be filled in by the entry point. +// +STATIC PEI_SMM_ACCESS_PPI mAccess =3D { + &SmmAccessPeiOpen, + &SmmAccessPeiClose, + &SmmAccessPeiLock, + &SmmAccessPeiGetCapabilities +}; + + +STATIC EFI_PEI_PPI_DESCRIPTOR mPpiList[] =3D { + { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gPeiSmmAccessPpiGuid, &mAccess + } +}; + + +// +// Utility functions. +// +STATIC +UINT8 +CmosRead8 ( + IN UINT8 Index + ) +{ + IoWrite8 (0x70, Index); + return IoRead8 (0x71); +} + +STATIC +UINT32 +GetSystemMemorySizeBelow4gb ( + VOID + ) +{ + UINT32 Cmos0x34; + UINT32 Cmos0x35; + + Cmos0x34 =3D CmosRead8 (0x34); + Cmos0x35 =3D CmosRead8 (0x35); + + return ((Cmos0x35 << 8 | Cmos0x34) << 16) + SIZE_16MB; +} + + +// +// Entry point of this driver. +// +EFI_STATUS +EFIAPI +SmmAccessPeiEntryPoint ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + UINT16 HostBridgeDevId; + UINT32 EsmramcVal; + UINT32 TopOfLowRam, TopOfLowRamMb; + EFI_STATUS Status; + UINTN SmramMapSize; + EFI_SMRAM_DESCRIPTOR SmramMap[DescIdxCount]; + VOID *GuidHob; + + // + // This module should only be included if SMRAM support is required. + // + ASSERT (FeaturePcdGet (PcdSmmSmramRequire)); + + // + // Verify if we're running on a X58 machine type. + // + HostBridgeDevId =3D PciRead16 (SIMICS_HOSTBRIDGE_DID); + if (HostBridgeDevId !=3D INTEL_ICH10_DEVICE_ID) { + DEBUG ((EFI_D_ERROR, "%a: no SMRAM with host bridge DID=3D0x%04x; only= " + "DID=3D0x%04x (X58) is supported\n", __FUNCTION__, HostBridgeDevId, + INTEL_ICH10_DEVICE_ID)); + goto WrongConfig; + } + + // + // Confirm if Simics supports SMRAM. + // + // With no support for it, the ESMRAMC (Extended System Management RAM + // Control) register reads as zero. If there is support, the cache-enable + // bits are hard-coded as 1 by Simics. + // + + TopOfLowRam =3D GetSystemMemorySizeBelow4gb (); + ASSERT ((TopOfLowRam & (SIZE_1MB - 1)) =3D=3D 0); + TopOfLowRamMb =3D TopOfLowRam >> 20; + DEBUG((EFI_D_INFO, "TopOfLowRam =3D0x%x; TopOfLowRamMb =3D0x%x \n", TopO= fLowRam, TopOfLowRamMb)); + + + // + // Set Top of Low Usable DRAM. + // + PciWrite32 (DRAMC_REGISTER_X58(MCH_TOLUD), TopOfLowRam); + DEBUG((EFI_D_INFO, "MCH_TOLUD =3D0x%x; \n", PciRead32(DRAMC_REGISTER_X58= (MCH_TOLUD)))); + + // + // Set TSEG Memory Base. + // + EsmramcVal =3D (TopOfLowRamMb - FixedPcdGet8(PcdX58TsegMbytes)) << MCH_T= SEGMB_MB_SHIFT; + // + // Set TSEG size, and disable TSEG visibility outside of SMM. Note that = the + // T_EN bit has inverse meaning; when T_EN is set, then TSEG visibility = is + // *restricted* to SMM. + // + EsmramcVal &=3D ~(UINT32)MCH_ESMRAMC_TSEG_MASK; + EsmramcVal |=3D FixedPcdGet8 (PcdX58TsegMbytes) =3D=3D 8 ? MCH_ESMRAMC_T= SEG_8MB : + FixedPcdGet8 (PcdX58TsegMbytes) =3D=3D 2 ? MCH_ESMRAMC_TSE= G_2MB : + MCH_ESMRAMC_TSEG_1MB; + EsmramcVal |=3D MCH_ESMRAMC_T_EN; + PciWrite32(DRAMC_REGISTER_X58(MCH_TSEGMB), EsmramcVal); + DEBUG((EFI_D_INFO, "MCH_TSEGMB =3D0x%x; \n", PciRead32(DRAMC_REGISTER_X5= 8(MCH_TSEGMB)))); + DEBUG((EFI_D_INFO, "MCH_TSEGMB_1 =3D0x%x; MCH_TSEGMB_2 =3D0x%x;\n", ((To= pOfLowRamMb - FixedPcdGet8(PcdX58TsegMbytes)) << MCH_TSEGMB_MB_SHIFT), Esmr= amcVal)); + + // + // Create the GUID HOB and point it to the first SMRAM range. + // + GetStates (&mAccess.LockState, &mAccess.OpenState); + SmramMapSize =3D sizeof SmramMap; + Status =3D SmramAccessGetCapabilities (mAccess.LockState, mAccess.OpenSt= ate, &SmramMapSize, SmramMap); + ASSERT_EFI_ERROR (Status); + + DEBUG_CODE_BEGIN (); + { + UINTN Count; + UINTN Idx; + + Count =3D SmramMapSize / sizeof SmramMap[0]; + DEBUG ((EFI_D_VERBOSE, "%a: SMRAM map follows, %d entries\n", __FUNCTI= ON__, (INT32)Count)); + DEBUG ((EFI_D_VERBOSE, "% 20a % 20a % 20a % 20a\n", "PhysicalStart(0x)= ", + "PhysicalSize(0x)", "CpuStart(0x)", "RegionState(0x)")); + for (Idx =3D 0; Idx < Count; ++Idx) { + DEBUG ((EFI_D_VERBOSE, "% 20Lx % 20Lx % 20Lx % 20Lx\n", + SmramMap[Idx].PhysicalStart, SmramMap[Idx].PhysicalSize, + SmramMap[Idx].CpuStart, SmramMap[Idx].RegionState)); + } + } + DEBUG_CODE_END (); + + GuidHob =3D BuildGuidHob (&gEfiAcpiVariableGuid, sizeof SmramMap[DescIdx= SmmS3ResumeState]); + if (GuidHob =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + CopyMem (GuidHob, &SmramMap[DescIdxSmmS3ResumeState], sizeof SmramMap[De= scIdxSmmS3ResumeState]); + + // + // We're done. The next step should succeed, but even if it fails, we ca= n't + // roll back the above BuildGuidHob() allocation, because PEI doesn't su= pport + // releasing memory. + // + return PeiServicesInstallPpi (mPpiList); + +WrongConfig: + // + // We really don't want to continue in this case. + // + ASSERT (FALSE); + CpuDeadLoop (); + return EFI_UNSUPPORTED; +} diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c b/Sil= icon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c new file mode 100644 index 0000000000..4b5a92f602 --- /dev/null +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c @@ -0,0 +1,200 @@ +/** @file + Functions and types shared by the SMM accessor PEI and DXE modules. + + Copyright (C) 2015, Red Hat, Inc. + Copyright (C) 2019, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include + +#include "SmramInternal.h" + +BOOLEAN gLockState; +BOOLEAN gOpenState; + +/** + Read the MCH_SMRAM and ESMRAMC registers, and update the LockState and + OpenState fields in the PEI_SMM_ACCESS_PPI / EFI_SMM_ACCESS2_PROTOCOL ob= ject, + from the D_LCK and T_EN bits. + + PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL member functions can rel= y on + the LockState and OpenState fields being up-to-date on entry, and they n= eed + to restore the same invariant on exit, if they touch the bits in questio= n. + + @param[out] LockState Reflects the D_LCK bit on output; TRUE iff SMRAM = is + locked. + @param[out] OpenState Reflects the inverse of the T_EN bit on output; T= RUE + iff SMRAM is open. +**/ +VOID +GetStates ( + OUT BOOLEAN *LockState, + OUT BOOLEAN *OpenState +) +{ + UINT8 EsmramcVal; + + EsmramcVal =3D PciRead8(DRAMC_REGISTER_X58(MCH_TSEGMB)); + + *OpenState =3D !(EsmramcVal & MCH_ESMRAMC_T_EN); + *LockState =3D !*OpenState; + + *OpenState =3D gOpenState; + *LockState =3D gLockState; +} + +// +// The functions below follow the PEI_SMM_ACCESS_PPI and +// EFI_SMM_ACCESS2_PROTOCOL member declarations. The PeiServices and This +// pointers are removed (TSEG doesn't depend on them), and so is the +// DescriptorIndex parameter (TSEG doesn't support range-wise locking). +// +// The LockState and OpenState members that are common to both +// PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL are taken and updated in +// isolation from the rest of the (non-shared) members. +// + +EFI_STATUS +SmramAccessOpen ( + OUT BOOLEAN *LockState, + OUT BOOLEAN *OpenState + ) +{ + + // + // Open TSEG by clearing T_EN. + // + PciAnd8(DRAMC_REGISTER_X58(MCH_TSEGMB), + (UINT8)((~(UINT32)MCH_ESMRAMC_T_EN) & 0xff)); + + gOpenState =3D TRUE; + gLockState =3D !gOpenState; + + GetStates (LockState, OpenState); + if (!*OpenState) { + return EFI_DEVICE_ERROR; + } + return EFI_SUCCESS; +} + +EFI_STATUS +SmramAccessClose ( + OUT BOOLEAN *LockState, + OUT BOOLEAN *OpenState + ) +{ + // + // Close TSEG by setting T_EN. + // + PciOr8(DRAMC_REGISTER_X58(MCH_TSEGMB), MCH_ESMRAMC_T_EN); + + gOpenState =3D FALSE; + gLockState =3D !gOpenState; + + GetStates (LockState, OpenState); + if (*OpenState) { + return EFI_DEVICE_ERROR; + } + return EFI_SUCCESS; +} + +EFI_STATUS +SmramAccessLock ( + OUT BOOLEAN *LockState, + IN OUT BOOLEAN *OpenState + ) +{ + if (*OpenState) { + return EFI_DEVICE_ERROR; + } + + // + // Close & lock TSEG by setting T_EN and D_LCK. + // + PciOr8 (DRAMC_REGISTER_X58(MCH_TSEGMB), MCH_ESMRAMC_T_EN); + + gOpenState =3D FALSE; + gLockState =3D !gOpenState; + + GetStates (LockState, OpenState); + if (*OpenState || !*LockState) { + return EFI_DEVICE_ERROR; + } + return EFI_SUCCESS; +} + +EFI_STATUS +SmramAccessGetCapabilities ( + IN BOOLEAN LockState, + IN BOOLEAN OpenState, + IN OUT UINTN *SmramMapSize, + IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap + ) +{ + UINTN OriginalSize; + UINT32 TsegMemoryBaseMb, TsegMemoryBase; + UINT64 CommonRegionState; + UINT8 TsegSizeBits; + + OriginalSize =3D *SmramMapSize; + *SmramMapSize =3D DescIdxCount * sizeof *SmramMap; + if (OriginalSize < *SmramMapSize) { + return EFI_BUFFER_TOO_SMALL; + } + + // + // Read the TSEG Memory Base register. + // + TsegMemoryBaseMb =3D PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB)); + + TsegMemoryBaseMb =3D 0xDF800000; + + TsegMemoryBase =3D (TsegMemoryBaseMb >> MCH_TSEGMB_MB_SHIFT) << 20; + + // + // Precompute the region state bits that will be set for all regions. + // + CommonRegionState =3D (OpenState ? EFI_SMRAM_OPEN : EFI_SMRAM_CLOSED) | + (LockState ? EFI_SMRAM_LOCKED : 0) | + EFI_CACHEABLE; + + // + // The first region hosts an SMM_S3_RESUME_STATE object. It is located a= t the + // start of TSEG. We round up the size to whole pages, and we report it = as + // EFI_ALLOCATED, so that the SMM_CORE stays away from it. + // + SmramMap[DescIdxSmmS3ResumeState].PhysicalStart =3D TsegMemoryBase; + SmramMap[DescIdxSmmS3ResumeState].CpuStart =3D TsegMemoryBase; + SmramMap[DescIdxSmmS3ResumeState].PhysicalSize =3D + EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (sizeof (SMM_S3_RESUME_STATE))); + SmramMap[DescIdxSmmS3ResumeState].RegionState =3D + CommonRegionState | EFI_ALLOCATED; + + // + // Get the TSEG size bits from the ESMRAMC register. + // + TsegSizeBits =3D PciRead8 (DRAMC_REGISTER_X58(MCH_TSEGMB)) & + MCH_ESMRAMC_TSEG_MASK; + + TsegSizeBits =3D MCH_ESMRAMC_TSEG_8MB; + + // + // The second region is the main one, following the first. + // + SmramMap[DescIdxMain].PhysicalStart =3D + SmramMap[DescIdxSmmS3ResumeState].PhysicalStart + + SmramMap[DescIdxSmmS3ResumeState].PhysicalSize; + SmramMap[DescIdxMain].CpuStart =3D SmramMap[DescIdxMain].PhysicalStart; + SmramMap[DescIdxMain].PhysicalSize =3D + (TsegSizeBits =3D=3D MCH_ESMRAMC_TSEG_8MB ? SIZE_8MB : + TsegSizeBits =3D=3D MCH_ESMRAMC_TSEG_2MB ? SIZE_2MB : + SIZE_1MB) - SmramMap[DescIdxSmmS3ResumeState].PhysicalSize; + SmramMap[DescIdxMain].RegionState =3D CommonRegionState; + + return EFI_SUCCESS; +} diff --git a/Silicon/Intel/SimicsX58SktPkg/Include/Register/X58SmramSaveSta= teMap.h b/Silicon/Intel/SimicsX58SktPkg/Include/Register/X58SmramSaveStateM= ap.h new file mode 100644 index 0000000000..a067d1488a --- /dev/null +++ b/Silicon/Intel/SimicsX58SktPkg/Include/Register/X58SmramSaveStateMap.h @@ -0,0 +1,178 @@ +/** @file +SMRAM Save State Map Definitions. + +SMRAM Save State Map definitions based on contents of the +Intel(R) 64 and IA-32 Architectures Software Developer's Manual + Volume 3C, Section 34.4 SMRAM + Volume 3C, Section 34.5 SMI Handler Execution Environment + Volume 3C, Section 34.7 Managing Synchronous and Asynchronous SMIs + +and the AMD64 Architecture Programmer's Manual + Volume 2, Section 10.2 SMM Resources + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+Copyright (c) 2015, Red Hat, Inc.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __X58_SMRAM_SAVE_STATE_MAP_H__ +#define __X58_SMRAM_SAVE_STATE_MAP_H__ + +#pragma pack (1) + +/// +/// 32-bit SMRAM Save State Map +/// +typedef struct { + UINT8 Reserved0[0x200]; // 7c00h + UINT8 Reserved1[0xf8]; // 7e00h + UINT32 SMBASE; // 7ef8h + UINT32 SMMRevId; // 7efch + UINT16 IORestart; // 7f00h + UINT16 AutoHALTRestart; // 7f02h + UINT8 Reserved2[0x9C]; // 7f08h + UINT32 IOMemAddr; // 7fa0h + UINT32 IOMisc; // 7fa4h + UINT32 _ES; // 7fa8h + UINT32 _CS; // 7fach + UINT32 _SS; // 7fb0h + UINT32 _DS; // 7fb4h + UINT32 _FS; // 7fb8h + UINT32 _GS; // 7fbch + UINT32 Reserved3; // 7fc0h + UINT32 _TR; // 7fc4h + UINT32 _DR7; // 7fc8h + UINT32 _DR6; // 7fcch + UINT32 _EAX; // 7fd0h + UINT32 _ECX; // 7fd4h + UINT32 _EDX; // 7fd8h + UINT32 _EBX; // 7fdch + UINT32 _ESP; // 7fe0h + UINT32 _EBP; // 7fe4h + UINT32 _ESI; // 7fe8h + UINT32 _EDI; // 7fech + UINT32 _EIP; // 7ff0h + UINT32 _EFLAGS; // 7ff4h + UINT32 _CR3; // 7ff8h + UINT32 _CR0; // 7ffch +} X58_SMRAM_SAVE_STATE_MAP32; + +/// +/// 64-bit SMRAM Save State Map +/// +typedef struct { + UINT8 Reserved0[0x200]; // 7c00h + + UINT16 _ES; // 7e00h + UINT16 _ESAccessRights; // 7e02h + UINT32 _ESLimit; // 7e04h + UINT64 _ESBase; // 7e08h + + UINT16 _CS; // 7e10h + UINT16 _CSAccessRights; // 7e12h + UINT32 _CSLimit; // 7e14h + UINT64 _CSBase; // 7e18h + + UINT16 _SS; // 7e20h + UINT16 _SSAccessRights; // 7e22h + UINT32 _SSLimit; // 7e24h + UINT64 _SSBase; // 7e28h + + UINT16 _DS; // 7e30h + UINT16 _DSAccessRights; // 7e32h + UINT32 _DSLimit; // 7e34h + UINT64 _DSBase; // 7e38h + + UINT16 _FS; // 7e40h + UINT16 _FSAccessRights; // 7e42h + UINT32 _FSLimit; // 7e44h + UINT64 _FSBase; // 7e48h + + UINT16 _GS; // 7e50h + UINT16 _GSAccessRights; // 7e52h + UINT32 _GSLimit; // 7e54h + UINT64 _GSBase; // 7e58h + + UINT32 _GDTRReserved1; // 7e60h + UINT16 _GDTRLimit; // 7e64h + UINT16 _GDTRReserved2; // 7e66h + UINT64 _GDTRBase; // 7e68h + + UINT16 _LDTR; // 7e70h + UINT16 _LDTRAccessRights; // 7e72h + UINT32 _LDTRLimit; // 7e74h + UINT64 _LDTRBase; // 7e78h + + UINT32 _IDTRReserved1; // 7e80h + UINT16 _IDTRLimit; // 7e84h + UINT16 _IDTRReserved2; // 7e86h + UINT64 _IDTRBase; // 7e88h + + UINT16 _TR; // 7e90h + UINT16 _TRAccessRights; // 7e92h + UINT32 _TRLimit; // 7e94h + UINT64 _TRBase; // 7e98h + + UINT64 IO_RIP; // 7ea0h + UINT64 IO_RCX; // 7ea8h + UINT64 IO_RSI; // 7eb0h + UINT64 IO_RDI; // 7eb8h + UINT32 IO_DWord; // 7ec0h + UINT8 Reserved1[0x04]; // 7ec4h + UINT8 IORestart; // 7ec8h + UINT8 AutoHALTRestart; // 7ec9h + UINT8 Reserved2[0x06]; // 7ecah + + UINT64 IA32_EFER; // 7ed0h + UINT64 SVM_Guest; // 7ed8h + UINT64 SVM_GuestVMCB; // 7ee0h + UINT64 SVM_GuestVIntr; // 7ee8h + UINT8 Reserved3[0x0c]; // 7ef0h + + UINT32 SMMRevId; // 7efch + UINT32 SMBASE; // 7f00h + + UINT8 Reserved4[0x1c]; // 7f04h + UINT64 SVM_GuestPAT; // 7f20h + UINT64 SVM_HostIA32_EFER; // 7f28h + UINT64 SVM_HostCR4; // 7f30h + UINT64 SVM_HostCR3; // 7f38h + UINT64 SVM_HostCR0; // 7f40h + + UINT64 _CR4; // 7f48h + UINT64 _CR3; // 7f50h + UINT64 _CR0; // 7f58h + UINT64 _DR7; // 7f60h + UINT64 _DR6; // 7f68h + UINT64 _RFLAGS; // 7f70h + UINT64 _RIP; // 7f78h + UINT64 _R15; // 7f80h + UINT64 _R14; // 7f88h + UINT64 _R13; // 7f90h + UINT64 _R12; // 7f98h + UINT64 _R11; // 7fa0h + UINT64 _R10; // 7fa8h + UINT64 _R9; // 7fb0h + UINT64 _R8; // 7fb8h + UINT64 _RDI; // 7fc0h + UINT64 _RSI; // 7fc8h + UINT64 _RBP; // 7fd0h + UINT64 _RSP; // 7fd8h + UINT64 _RBX; // 7fe0h + UINT64 _RDX; // 7fe8h + UINT64 _RCX; // 7ff0h + UINT64 _RAX; // 7ff8h +} X58_SMRAM_SAVE_STATE_MAP64; + +/// +/// Union of 32-bit and 64-bit SMRAM Save State Maps +/// +typedef union { + X58_SMRAM_SAVE_STATE_MAP32 x86; + X58_SMRAM_SAVE_STATE_MAP64 x64; +} X58_SMRAM_SAVE_STATE_MAP; + +#pragma pack () + +#endif diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPkg.dec b/Silicon/Intel/Simic= sX58SktPkg/SktPkg.dec new file mode 100644 index 0000000000..9fbc546167 --- /dev/null +++ b/Silicon/Intel/SimicsX58SktPkg/SktPkg.dec @@ -0,0 +1,37 @@ +## @file +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + DEC_SPECIFICATION =3D 0x00010005 + PACKAGE_NAME =3D SimicsX58SktPkg + PACKAGE_GUID =3D 070FEC45-BF03-41C1-8D46-8BBE032A7C0C + PACKAGE_VERSION =3D 0.91 + +[Includes] + Include + +[Guids] + gSimicsX58PkgTokenSpaceGuid =3D {0x5b276d20, 0x37d0, 0x4af0, {0x8d, 0x= 04, 0x47, 0x91, 0x2b, 0x7c, 0x1d, 0x44}} + +[PcdsFixedAtBuild] + ## The following setting controls how many megabytes we configure as TSE= G on + # X58, for SMRAM purposes. Permitted values are: 1, 2, 8. Other values = cause + # undefined behavior. + # + # This PCD is only consulted if PcdSmmSmramRequire is TRUE (see below). + gSimicsX58PkgTokenSpaceGuid.PcdX58TsegMbytes|8|UINT8|0x20 + +[PcdsFeatureFlag] + ## This feature flag enables SMM/SMRAM support. Note that it also requir= es + # such support from the underlying QEMU instance; if that support is not + # present, the firmware will reject continuing after a certain point. + # + # The flag also acts as a general "security switch"; when TRUE, many + # components will change behavior, with the goal of preventing a malici= ous + # runtime OS from tampering with firmware structures (special memory ra= nges + # used by OVMF, the varstore pflash chip, LockBox etc). + gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire|FALSE|BOOLEAN|0x1e diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc b/Silicon/Intel/Si= micsX58SktPkg/SktPkgPei.dsc new file mode 100644 index 0000000000..af83c380b8 --- /dev/null +++ b/Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc @@ -0,0 +1,14 @@ +## @file +# Component description file for the X58 SiPkg PEI drivers. +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + + # + # SEC Phase modules + # + UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf + UefiCpuPkg/CpuMpPei/CpuMpPei.inf diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf b/Silic= on/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf new file mode 100644 index 0000000000..b599df6e96 --- /dev/null +++ b/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf @@ -0,0 +1,9 @@ +## @file +# Component description file for the Simics X58 SiPkg DXE drivers. +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf b/Silico= n/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf new file mode 100644 index 0000000000..5b9cd9ee25 --- /dev/null +++ b/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf @@ -0,0 +1,10 @@ +## @file +# Component description file for the X58 SiPkg PEI drivers. +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +INF UefiCpuPkg/CpuMpPei/CpuMpPei.inf diff --git a/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf b/Silicon/Inte= l/SimicsX58SktPkg/SktSecInclude.fdf new file mode 100644 index 0000000000..5019e362e3 --- /dev/null +++ b/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf @@ -0,0 +1,16 @@ +## @file +# Component description file for the X58 SiPkg PEI drivers. +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +# +# SEC Phase modules +# +# The code in this FV handles the initial firmware startup, and +# decompresses the PEI and DXE FVs which handles the rest of the boot sequ= ence. +# +INF RuleOverride=3DRESET_VECTOR USE =3D IA32 UefiCpuPkg/ResetVector/Vtf0/= Bin/ResetVector.inf diff --git a/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf b/Silicon= /Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf new file mode 100644 index 0000000000..fdcb4fb9a7 --- /dev/null +++ b/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf @@ -0,0 +1,14 @@ +## @file +# Component description file for the Simics X58 SiPkg DXE drivers. +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly =3D=3D FALSE + INF $(SKT_PKG)/Smm/Access/SmmAccess2Dxe.inf + INF UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf +!endif +INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf b/S= ilicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf new file mode 100644 index 0000000000..eb8c8f93dd --- /dev/null +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf @@ -0,0 +1,54 @@ +## @file +# A DXE_DRIVER providing SMRAM access by producing EFI_SMM_ACCESS2_PROTOCO= L. +# +# X58 TSEG is expected to have been verified and set up by the SmmAccessPei +# driver. +# +# Copyright (C) 2013, 2015, Red Hat, Inc. +# Copyright (C) 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D SmmAccess2Dxe + FILE_GUID =3D AC95AD3D-4366-44BF-9A62-E4B29D7A2206 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + PI_SPECIFICATION_VERSION =3D 0x00010400 + ENTRY_POINT =3D SmmAccess2DxeEntryPoint + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 +# + +[Sources] + SmmAccess2Dxe.c + SmramInternal.c + SmramInternal.h + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + SimicsX58SktPkg/SktPkg.dec + SimicsIch10Pkg/Ich10Pkg.dec + +[LibraryClasses] + DebugLib + PcdLib + PciLib + UefiBootServicesTableLib + UefiDriverEntryPoint + +[Protocols] + gEfiSmmAccess2ProtocolGuid ## PRODUCES + +[FeaturePcd] + gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire + +[Depex] + TRUE diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf b/Si= licon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf new file mode 100644 index 0000000000..2b6b14f437 --- /dev/null +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf @@ -0,0 +1,65 @@ +## @file +# A PEIM with the following responsibilities: +# +# - provide SMRAM access by producing PEI_SMM_ACCESS_PPI, +# - verify & configure the X58 TSEG in the entry point, +# - set aside the SMM_S3_RESUME_STATE object at the bottom of TSEG, and ex= pose +# it via the gEfiAcpiVariableGuid GUIDed HOB. +# +# Copyright (C) 2013, 2015, Red Hat, Inc. +# Copyright (C) 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D SmmAccessPei + FILE_GUID =3D 6C0E75B4-B0B9-44D1-8210-3377D7B4E066 + MODULE_TYPE =3D PEIM + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D SmmAccessPeiEntryPoint + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 +# + +[Sources] + SmmAccessPei.c + SmramInternal.c + SmramInternal.h + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + SimicsX58SktPkg/SktPkg.dec + SimicsIch10Pkg/Ich10Pkg.dec + +[Guids] + gEfiAcpiVariableGuid + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + HobLib + IoLib + PcdLib + PciLib + PeiServicesLib + PeimEntryPoint + +[FeaturePcd] + gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire + +[FixedPcd] + gSimicsX58PkgTokenSpaceGuid.PcdX58TsegMbytes + +[Ppis] + gPeiSmmAccessPpiGuid ## PRODUCES + +[Depex] + gEfiPeiMemoryDiscoveredPpiGuid diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h b/Sil= icon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h new file mode 100644 index 0000000000..81180a9c8e --- /dev/null +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h @@ -0,0 +1,82 @@ +/** @file + Functions and types shared by the SMM accessor PEI and DXE modules. + + Copyright (C) 2015, Red Hat, Inc. + Copyright (C) 2019, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include + +// +// We'll have two SMRAM ranges. +// +// The first is a tiny one that hosts an SMM_S3_RESUME_STATE object, to be +// filled in by the CPU SMM driver during normal boot, for the PEI instanc= e of +// the LockBox library (which will rely on the object during S3 resume). +// +// The other SMRAM range is the main one, for the SMM core and the SMM dri= vers. +// +typedef enum { + DescIdxSmmS3ResumeState =3D 0, + DescIdxMain =3D 1, + DescIdxCount =3D 2 +} DESCRIPTOR_INDEX; + +/** + Read the MCH_SMRAM and ESMRAMC registers, and update the LockState and + OpenState fields in the PEI_SMM_ACCESS_PPI / EFI_SMM_ACCESS2_PROTOCOL ob= ject, + from the D_LCK and T_EN bits. + + PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL member functions can rel= y on + the LockState and OpenState fields being up-to-date on entry, and they n= eed + to restore the same invariant on exit, if they touch the bits in questio= n. + + @param[out] LockState Reflects the D_LCK bit on output; TRUE iff SMRAM = is + locked. + @param[out] OpenState Reflects the inverse of the T_EN bit on output; T= RUE + iff SMRAM is open. +**/ +VOID +GetStates ( + OUT BOOLEAN *LockState, + OUT BOOLEAN *OpenState + ); + +// +// The functions below follow the PEI_SMM_ACCESS_PPI and +// EFI_SMM_ACCESS2_PROTOCOL member declarations. The PeiServices and This +// pointers are removed (TSEG doesn't depend on them), and so is the +// DescriptorIndex parameter (TSEG doesn't support range-wise locking). +// +// The LockState and OpenState members that are common to both +// PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL are taken and updated in +// isolation from the rest of the (non-shared) members. +// + +EFI_STATUS +SmramAccessOpen ( + OUT BOOLEAN *LockState, + OUT BOOLEAN *OpenState + ); + +EFI_STATUS +SmramAccessClose ( + OUT BOOLEAN *LockState, + OUT BOOLEAN *OpenState + ); + +EFI_STATUS +SmramAccessLock ( + OUT BOOLEAN *LockState, + IN OUT BOOLEAN *OpenState + ); + +EFI_STATUS +SmramAccessGetCapabilities ( + IN BOOLEAN LockState, + IN BOOLEAN OpenState, + IN OUT UINTN *SmramMapSize, + IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap + ); --=20 2.16.2.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 (#46943): https://edk2.groups.io/g/devel/message/46943 Mute This Topic: https://groups.io/mt/33159238/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Fri Apr 26 02:55:24 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+46944+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+46944+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1567719523; cv=none; d=zoho.com; s=zohoarc; b=MSTppjXl0yxSKMxA9knKvQNglk54Gf5pP4tONf4HqZQttHuo0MmBOW16TS9smh7+hzt9ezCbz73uU9KTa4vbupNDGjeWxeSvdB3Nko4muMaeI7+lOZT9UasfRDpGo5eSZmDl86egB4km4oUYlnlb2V5Y8wwsrea1k9gsvDUZXzk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1567719523; h=Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To:ARC-Authentication-Results; bh=BaU4HR4PuO/g3NBBANEBQ8XyNpOTP/l4GcYSpdCtPxI=; b=hHthA0TDyWibKpIGhAx3PvRyDLc5FnQaViXCZQtaTCQuGHepn6W/YOgCnaJzOto2OFPC47fMysbUZVcqWHkcwFxl7o6hCtX/HSKtjLFbW8rmuAJybeeL8G7rJ0/Cv4fZV0YxpYclVmjCxVjFydal3s1ApOOi7Bo0pQ4ywyM9OKw= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+46944+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1567719523890965.5396961884074; Thu, 5 Sep 2019 14:38:43 -0700 (PDT) Return-Path: X-Received: from mga11.intel.com (mga11.intel.com []) by groups.io with SMTP; Thu, 05 Sep 2019 14:38:42 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Sep 2019 14:38:41 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,471,1559545200"; d="scan'208";a="267151616" X-Received: from ydwei-desk.amr.corp.intel.com ([10.24.15.168]) by orsmga001.jf.intel.com with ESMTP; 05 Sep 2019 14:38:40 -0700 From: "David Wei" To: devel@edk2.groups.io Cc: Hao Wu , Liming Gao , Ankit Sinha , Agyeman Prince , Kubacki Michael A , Nate DeSimone , Michael D Kinney Subject: [edk2-devel] [edk2-platforms PATCH v5 2/7] SimicsIch10Pkg: Add Ich Pkg for SimicsIch10 Date: Thu, 5 Sep 2019 14:38:35 -0700 Message-Id: In-Reply-To: References: In-Reply-To: References: Precedence: Bulk List-Unsubscribe: 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,david.y.wei@intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1567719523; bh=LEBlzdhJa+a7QjUgaaocztCguPbrrfswR+bR/ZE6x08=; h=Cc:Date:From:Reply-To:Subject:To; b=Xj7WRZgAcVsWnHTki8pBCatk534rz7FVL0/+U7hS/aSOZNfhWSG4/iMhIkBJ0kqz3sz kn3nn+Km5lu4YTTbV5td1TP9VEKvM9rPycWSCxCmxT6CCBm1+k85Ry+9e1ALUIleoJ2bt Ld2hL9zBkYrPDi1C4dRz+jUyB30Dz5y7bCU= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add Ich Pkg for SimicsIch10. It is added for simics Quick Start Platform pr= oject support Cc: Hao Wu Cc: Liming Gao Cc: Ankit Sinha Cc: Agyeman Prince Cc: Kubacki Michael A Cc: Nate DeSimone Cc: Michael D Kinney Signed-off-by: David Wei --- .../Library/ResetSystemLib/ResetSystemLib.c | 137 +++ .../Library/SmmSpiFlashCommonLib/SpiFlashCommon.c | 194 +++++ .../SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c | 54 ++ .../LibraryPrivate/BasePchSpiCommonLib/SpiCommon.c | 935 +++++++++++++++++= ++++ .../SmmControl/RuntimeDxe/SmmControl2Dxe.c | 410 +++++++++ Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.c | 175 ++++ Silicon/Intel/SimicsIch10Pkg/Ich10Pkg.dec | 26 + Silicon/Intel/SimicsIch10Pkg/IchCommonLib.dsc | 12 + .../Intel/SimicsIch10Pkg/IchPostMemoryInclude.fdf | 9 + .../Intel/SimicsIch10Pkg/IchPreMemoryInclude.fdf | 9 + .../Intel/SimicsIch10Pkg/IchUefiBootInclude.fdf | 13 + .../Include/Library/SpiFlashCommonLib.h | 98 +++ Silicon/Intel/SimicsIch10Pkg/Include/PchAccess.h | 43 + Silicon/Intel/SimicsIch10Pkg/Include/PchLimits.h | 94 +++ .../SimicsIch10Pkg/Include/PchReservedResources.h | 60 ++ .../Intel/SimicsIch10Pkg/Include/Protocol/Spi.h | 295 +++++++ .../SimicsIch10Pkg/Include/Register/PchRegsPmc.h | 647 ++++++++++++++ .../SimicsIch10Pkg/Include/Register/PchRegsSpi.h | 304 +++++++ .../SimicsIch10Pkg/Include/Register/X58Ich10.h | 114 +++ .../IncludePrivate/Library/PchSpiCommonLib.h | 396 +++++++++ .../Library/ResetSystemLib/ResetSystemLib.inf | 34 + .../SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf | 50 ++ .../BasePchSpiCommonLib/BasePchSpiCommonLib.inf | 31 + .../SmmControl/RuntimeDxe/SmmControl2Dxe.inf | 61 ++ Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.h | 23 + Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpiSmm.inf | 44 + 26 files changed, 4268 insertions(+) create mode 100644 Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/Res= etSystemLib.c create mode 100644 Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonL= ib/SpiFlashCommon.c create mode 100644 Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonL= ib/SpiFlashCommonSmmLib.c create mode 100644 Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiC= ommonLib/SpiCommon.c create mode 100644 Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmC= ontrol2Dxe.c create mode 100644 Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.c create mode 100644 Silicon/Intel/SimicsIch10Pkg/Ich10Pkg.dec create mode 100644 Silicon/Intel/SimicsIch10Pkg/IchCommonLib.dsc create mode 100644 Silicon/Intel/SimicsIch10Pkg/IchPostMemoryInclude.fdf create mode 100644 Silicon/Intel/SimicsIch10Pkg/IchPreMemoryInclude.fdf create mode 100644 Silicon/Intel/SimicsIch10Pkg/IchUefiBootInclude.fdf create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/Library/SpiFlashCo= mmonLib.h create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/PchAccess.h create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/PchLimits.h create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/PchReservedResourc= es.h create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/Protocol/Spi.h create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsPm= c.h create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsSp= i.h create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/Register/X58Ich10.h create mode 100644 Silicon/Intel/SimicsIch10Pkg/IncludePrivate/Library/Pch= SpiCommonLib.h create mode 100644 Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/Res= etSystemLib.inf create mode 100644 Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonL= ib/SmmSpiFlashCommonLib.inf create mode 100644 Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiC= ommonLib/BasePchSpiCommonLib.inf create mode 100644 Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmC= ontrol2Dxe.inf create mode 100644 Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.h create mode 100644 Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpiSmm.inf diff --git a/Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSyste= mLib.c b/Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSystemLib= .c new file mode 100644 index 0000000000..ad3e4f455e --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSystemLib.c @@ -0,0 +1,137 @@ +/** @file + Reset System Library functions for Simics ICH10 + + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include + +#include +#include +#include +#include +#include + + +VOID +AcpiPmControl ( + UINTN SuspendType + ) +{ + ASSERT (SuspendType < 6); + DEBUG((EFI_D_ERROR, "SuspendType =3D 0x%x\n", SuspendType)); + + IoBitFieldWrite16 (ICH10_PMBASE_IO + 4, 10, 13, (UINT16) SuspendType); + IoOr16 (ICH10_PMBASE_IO + 0x04, BIT13); + CpuDeadLoop (); +} + +/** + Calling this function causes a system-wide reset. This sets + all circuitry within the system to its initial state. This type of reset + is asynchronous to system operation and operates without regard to + cycle boundaries. + + System reset should not return, if it returns, it means the system does + not support cold reset. +**/ +VOID +EFIAPI +ResetCold ( + VOID + ) +{ + DEBUG((EFI_D_ERROR, "ResetCold_CF9\n")); + IoWrite8 (0xCF9, BIT3 | BIT2 | BIT1); // 1st choice: PIIX3 RCR, RCPU|SRST + MicroSecondDelay (50); + + DEBUG((EFI_D_ERROR, "ResetCold_Port64\n")); + IoWrite8 (0x64, 0xfe); // 2nd choice: keyboard controller + CpuDeadLoop (); +} + +/** + Calling this function causes a system-wide initialization. The processors + are set to their initial state, and pending cycles are not corrupted. + + System reset should not return, if it returns, it means the system does + not support warm reset. +**/ +VOID +EFIAPI +ResetWarm ( + VOID + ) +{ + DEBUG((EFI_D_ERROR, "ResetWarm\n")); + // + //BUGBUG workaround for warm reset + // + IoWrite8(0xCF9, BIT2 | BIT1); + MicroSecondDelay(50); + + IoWrite8 (0x64, 0xfe); + CpuDeadLoop (); +} + +/** + Calling this function causes the system to enter a power state equivalent + to the ACPI G2/S5 or G3 states. + + System shutdown should not return, if it returns, it means the system do= es + not support shut down reset. +**/ +VOID +EFIAPI +ResetShutdown ( + VOID + ) +{ + DEBUG((EFI_D_ERROR, "ResetShutdown\n")); + AcpiPmControl (0); + ASSERT (FALSE); +} + + +/** + Calling this function causes the system to enter a power state for capsu= le + update. + + Reset update should not return, if it returns, it means the system does + not support capsule update. + +**/ +VOID +EFIAPI +EnterS3WithImmediateWake ( + VOID + ) +{ + DEBUG((EFI_D_ERROR, "EnterS3WithImmediateWake\n")); + AcpiPmControl (1); + ASSERT (FALSE); +} + +/** + This function causes a systemwide reset. The exact type of the reset is + defined by the EFI_GUID that follows the Null-terminated Unicode string = passed + into ResetData. If the platform does not recognize the EFI_GUID in Reset= Data + the platform must pick a supported reset type to perform.The platform may + optionally log the parameters from any non-normal reset that occurs. + + @param[in] DataSize The size, in bytes, of ResetData. + @param[in] ResetData The data buffer starts with a Null-terminated str= ing, + followed by the EFI_GUID. +**/ +VOID +EFIAPI +ResetPlatformSpecific ( + IN UINTN DataSize, + IN VOID *ResetData + ) +{ + DEBUG((EFI_D_ERROR, "ResetPlatformSpecific\n")); + ResetCold (); +} diff --git a/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SpiF= lashCommon.c b/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/Sp= iFlashCommon.c new file mode 100644 index 0000000000..9e3461cbd6 --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCom= mon.c @@ -0,0 +1,194 @@ +/** @file + Wrap EFI_SPI_PROTOCOL to provide some library level interfaces + for module use. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include + + +EFI_SPI_PROTOCOL *mSpiProtocol; + +// +// FlashAreaBaseAddress and Size for boottime and runtime usage. +// +UINTN mFlashAreaBaseAddress =3D 0; +UINTN mFlashAreaSize =3D 0; + +/** + Enable block protection on the Serial Flash device. + + @retval EFI_SUCCESS Opertion is successful. + @retval EFI_DEVICE_ERROR If there is any device errors. + +**/ +EFI_STATUS +EFIAPI +SpiFlashLock ( + VOID + ) +{ + return EFI_SUCCESS; +} + +/** + Read NumBytes bytes of data from the address specified by + PAddress into Buffer. + + @param[in] Address The starting physical address of the read. + @param[in,out] NumBytes On input, the number of bytes to read. On = output, the number + of bytes actually read. + @param[out] Buffer The destination data buffer for the read. + + @retval EFI_SUCCESS Opertion is successful. + @retval EFI_DEVICE_ERROR If there is any device errors. + +**/ +EFI_STATUS +EFIAPI +SpiFlashRead ( + IN UINTN Address, + IN OUT UINT32 *NumBytes, + OUT UINT8 *Buffer + ) +{ + ASSERT ((NumBytes !=3D NULL) && (Buffer !=3D NULL)); + if ((NumBytes =3D=3D NULL) || (Buffer =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + // + // This function is implemented specifically for those platforms + // at which the SPI device is memory mapped for read. So this + // function just do a memory copy for Spi Flash Read. + // + CopyMem (Buffer, (VOID *) Address, *NumBytes); + + return EFI_SUCCESS; +} + +/** + Write NumBytes bytes of data from Buffer to the address specified by + PAddresss. + + @param[in] Address The starting physical address of the wri= te. + @param[in,out] NumBytes On input, the number of bytes to write. = On output, + the actual number of bytes written. + @param[in] Buffer The source data buffer for the write. + + @retval EFI_SUCCESS Opertion is successful. + @retval EFI_DEVICE_ERROR If there is any device errors. + +**/ +EFI_STATUS +EFIAPI +SpiFlashWrite ( + IN UINTN Address, + IN OUT UINT32 *NumBytes, + IN UINT8 *Buffer + ) +{ + EFI_STATUS Status; + UINTN Offset; + UINT32 Length; + UINT32 RemainingBytes; + + ASSERT ((NumBytes !=3D NULL) && (Buffer !=3D NULL)); + if ((NumBytes =3D=3D NULL) || (Buffer =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + ASSERT (Address >=3D mFlashAreaBaseAddress); + + Offset =3D Address - mFlashAreaBaseAddress; + + ASSERT ((*NumBytes + Offset) <=3D mFlashAreaSize); + + Status =3D EFI_SUCCESS; + RemainingBytes =3D *NumBytes; + + + while (RemainingBytes > 0) { + if (RemainingBytes > SECTOR_SIZE_4KB) { + Length =3D SECTOR_SIZE_4KB; + } else { + Length =3D RemainingBytes; + } + Status =3D mSpiProtocol->FlashWrite ( + mSpiProtocol, + FlashRegionBios, + (UINT32) Offset, + Length, + Buffer + ); + if (EFI_ERROR (Status)) { + break; + } + RemainingBytes -=3D Length; + Offset +=3D Length; + Buffer +=3D Length; + } + + // + // Actual number of bytes written + // + *NumBytes -=3D RemainingBytes; + + return Status; +} + +/** + Erase the block starting at Address. + + @param[in] Address The starting physical address of the block t= o be erased. + This library assume that caller garantee tha= t the PAddress + is at the starting address of this block. + @param[in] NumBytes On input, the number of bytes of the logical= block to be erased. + On output, the actual number of bytes erased. + + @retval EFI_SUCCESS. Opertion is successful. + @retval EFI_DEVICE_ERROR If there is any device errors. + +**/ +EFI_STATUS +EFIAPI +SpiFlashBlockErase ( + IN UINTN Address, + IN UINTN *NumBytes + ) +{ + EFI_STATUS Status; + UINTN Offset; + UINTN RemainingBytes; + + ASSERT (NumBytes !=3D NULL); + if (NumBytes =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + ASSERT (Address >=3D mFlashAreaBaseAddress); + + Offset =3D Address - mFlashAreaBaseAddress; + + ASSERT ((*NumBytes % SECTOR_SIZE_4KB) =3D=3D 0); + ASSERT ((*NumBytes + Offset) <=3D mFlashAreaSize); + + Status =3D EFI_SUCCESS; + RemainingBytes =3D *NumBytes; + + + Status =3D mSpiProtocol->FlashErase ( + mSpiProtocol, + FlashRegionBios, + (UINT32) Offset, + (UINT32) RemainingBytes + ); + return Status; +} + diff --git a/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SpiF= lashCommonSmmLib.c b/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommon= Lib/SpiFlashCommonSmmLib.c new file mode 100644 index 0000000000..984b7733c6 --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCom= monSmmLib.c @@ -0,0 +1,54 @@ +/** @file + SMM Library instance of SPI Flash Common Library Class + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include + +extern EFI_SPI_PROTOCOL *mSpiProtocol; + +extern UINTN mFlashAreaBaseAddress; +extern UINTN mFlashAreaSize; + +/** + The library constructuor. + + The function does the necessary initialization work for this library + instance. + + @param[in] ImageHandle The firmware allocated handle for the UEFI= image. + @param[in] SystemTable A pointer to the EFI system table. + + @retval EFI_SUCCESS The function always return EFI_SUCCESS for= now. + It will ASSERT on error for debug version. + @retval EFI_ERROR Please reference LocateProtocol for error = code details. +**/ +EFI_STATUS +EFIAPI +SmmSpiFlashCommonLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + mFlashAreaBaseAddress =3D (UINTN)PcdGet32 (PcdFlashAreaBaseAddress); + mFlashAreaSize =3D (UINTN)PcdGet32 (PcdFlashAreaSize); + + // + // Locate the SMM SPI protocol. + // + Status =3D gSmst->SmmLocateProtocol ( + &gEfiSmmSpiProtocolGuid, + NULL, + (VOID **) &mSpiProtocol + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiCommonLi= b/SpiCommon.c b/Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiCommo= nLib/SpiCommon.c new file mode 100644 index 0000000000..bd08b2453b --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiCommonLib/SpiCo= mmon.c @@ -0,0 +1,935 @@ +/** @file + PCH SPI Common Driver implements the SPI Host Controller Compatibility I= nterface. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + Initialize an SPI protocol instance. + + @param[in] SpiInstance Pointer to SpiInstance to initialize + + @retval EFI_SUCCESS The protocol instance was properly initi= alized + @exception EFI_UNSUPPORTED The PCH is not supported by this module +**/ +EFI_STATUS +SpiProtocolConstructor ( + IN SPI_INSTANCE *SpiInstance + ) +{ + UINTN PchSpiBar0; + + // + // Initialize the SPI protocol instance + // + SpiInstance->Signature =3D PCH_SPI_PRIVATE_DATA_SIGNA= TURE; + SpiInstance->Handle =3D NULL; + SpiInstance->SpiProtocol.Revision =3D PCH_SPI_SERVICES_REVISION; + SpiInstance->SpiProtocol.FlashRead =3D SpiProtocolFlashRead; + SpiInstance->SpiProtocol.FlashWrite =3D SpiProtocolFlashWrite; + SpiInstance->SpiProtocol.FlashErase =3D SpiProtocolFlashErase; + SpiInstance->SpiProtocol.FlashReadSfdp =3D SpiProtocolFlashReadSfdp; + SpiInstance->SpiProtocol.FlashReadJedecId =3D SpiProtocolFlashReadJedecI= d; + SpiInstance->SpiProtocol.FlashWriteStatus =3D SpiProtocolFlashWriteStatu= s; + SpiInstance->SpiProtocol.FlashReadStatus =3D SpiProtocolFlashReadStatus; + SpiInstance->SpiProtocol.GetRegionAddress =3D SpiProtocolGetRegionAddres= s; + SpiInstance->SpiProtocol.ReadPchSoftStrap =3D SpiProtocolReadPchSoftStra= p; + SpiInstance->SpiProtocol.ReadCpuSoftStrap =3D SpiProtocolReadCpuSoftStra= p; + + SpiInstance->PchAcpiBase =3D ICH10_PMBASE_IO; + ASSERT (SpiInstance->PchAcpiBase !=3D 0); + + PchSpiBar0 =3D RCRB + SPIBAR; + + if (PchSpiBar0 =3D=3D 0) { + DEBUG ((DEBUG_ERROR, "ERROR : PchSpiBar0 is invalid!\n")); + ASSERT (FALSE); + } + + if ((MmioRead32 (PchSpiBar0 + R_PCH_SPI_HSFSC) & B_PCH_SPI_HSFSC_FDV) = =3D=3D 0) { + DEBUG ((DEBUG_ERROR, "ERROR : SPI Flash Signature invalid, cannot use = the Hardware Sequencing registers!\n")); + ASSERT (FALSE); + } + SpiInstance->ReadPermission =3D 0xffff; + SpiInstance->WritePermission =3D 0xffff; + DEBUG ((DEBUG_INFO, "Flash Region Permission: Read- 0x%04x; Write=3D 0x%= 04x\n", + SpiInstance->ReadPermissio= n, + SpiInstance->WritePermissi= on)); + + // + SpiInstance->TotalFlashSize =3D PcdGet32(PcdFlashAreaSize); + DEBUG ((DEBUG_INFO, "Total Flash Size : %0x\n", SpiInstance->TotalFlashS= ize)); + return EFI_SUCCESS; +} + +/** + Delay for at least the request number of microseconds for Runtime usage. + + @param[in] ABase Acpi base address + @param[in] Microseconds Number of microseconds to delay. + +**/ +VOID +EFIAPI +PchPmTimerStallRuntimeSafe ( + IN UINT16 ABase, + IN UINTN Microseconds + ) +{ + UINTN Ticks; + UINTN Counts; + UINTN CurrentTick; + UINTN OriginalTick; + UINTN RemainingTick; + + if (Microseconds =3D=3D 0) { + return; + } + + OriginalTick =3D IoRead32 ((UINTN) (ABase + R_PCH_ACPI_PM1_TMR)) & B_P= CH_ACPI_PM1_TMR_VAL; + CurrentTick =3D OriginalTick; + + // + // The timer frequency is 3.579545 MHz, so 1 ms corresponds 3.58 clocks + // + Ticks =3D Microseconds * 358 / 100 + OriginalTick + 1; + + // + // The loops needed by timer overflow + // + Counts =3D Ticks / V_PCH_ACPI_PM1_TMR_MAX_VAL; + + // + // Remaining clocks within one loop + // + RemainingTick =3D Ticks % V_PCH_ACPI_PM1_TMR_MAX_VAL; + + // + // not intend to use TMROF_STS bit of register PM1_STS, because this add= s extra + // one I/O operation, and maybe generate SMI + // + while ((Counts !=3D 0) || (RemainingTick > CurrentTick)) { + CurrentTick =3D IoRead32 ((UINTN) (ABase + R_PCH_ACPI_PM1_TMR)) & B_PC= H_ACPI_PM1_TMR_VAL; + // + // Check if timer overflow + // + if ((CurrentTick < OriginalTick)) { + if (Counts !=3D 0) { + Counts--; + } else { + // + // If timer overflow and Counts equ to 0, that means we already st= alled more than + // RemainingTick, break the loop here + // + break; + } + } + + OriginalTick =3D CurrentTick; + } +} + +/** + Read data from the flash part. + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] FlashRegionType The Flash Region type for flash cycle wh= ich is listed in the Descriptor. + @param[in] Address The Flash Linear Address must fall withi= n a region for which BIOS has access permissions. + @param[in] ByteCount Number of bytes in the data portion of t= he SPI cycle. + @param[out] Buffer The Pointer to caller-allocated buffer c= ontaining the dada received. + It is the caller's responsibility to mak= e sure Buffer is large enough for the total number of bytes read. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashRead ( + IN EFI_SPI_PROTOCOL *This, + IN FLASH_REGION_TYPE FlashRegionType, + IN UINT32 Address, + IN UINT32 ByteCount, + OUT UINT8 *Buffer + ) +{ + EFI_STATUS Status; + + // + // Sends the command to the SPI interface to execute. + // + Status =3D SendSpiCmd ( + This, + FlashRegionType, + FlashCycleRead, + Address, + ByteCount, + Buffer + ); + return Status; +} + +/** + Write data to the flash part. + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] FlashRegionType The Flash Region type for flash cycle wh= ich is listed in the Descriptor. + @param[in] Address The Flash Linear Address must fall withi= n a region for which BIOS has access permissions. + @param[in] ByteCount Number of bytes in the data portion of t= he SPI cycle. + @param[in] Buffer Pointer to caller-allocated buffer conta= ining the data sent during the SPI cycle. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashWrite ( + IN EFI_SPI_PROTOCOL *This, + IN FLASH_REGION_TYPE FlashRegionType, + IN UINT32 Address, + IN UINT32 ByteCount, + IN UINT8 *Buffer + ) +{ + EFI_STATUS Status; + + // + // Sends the command to the SPI interface to execute. + // + Status =3D SendSpiCmd ( + This, + FlashRegionType, + FlashCycleWrite, + Address, + ByteCount, + Buffer + ); + return Status; +} + +/** + Erase some area on the flash part. + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] FlashRegionType The Flash Region type for flash cycle wh= ich is listed in the Descriptor. + @param[in] Address The Flash Linear Address must fall withi= n a region for which BIOS has access permissions. + @param[in] ByteCount Number of bytes in the data portion of t= he SPI cycle. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashErase ( + IN EFI_SPI_PROTOCOL *This, + IN FLASH_REGION_TYPE FlashRegionType, + IN UINT32 Address, + IN UINT32 ByteCount + ) +{ + EFI_STATUS Status; + + // + // Sends the command to the SPI interface to execute. + // + Status =3D SendSpiCmd ( + This, + FlashRegionType, + FlashCycleErase, + Address, + ByteCount, + NULL + ); + return Status; +} + +/** + Read SFDP data from the flash part. + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] ComponentNumber The Componen Number for chip select + @param[in] Address The starting byte address for SFDP data = read. + @param[in] ByteCount Number of bytes in SFDP data portion of = the SPI cycle + @param[out] SfdpData The Pointer to caller-allocated buffer c= ontaining the SFDP data received + It is the caller's responsibility to mak= e sure Buffer is large enough for the total number of bytes read + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashReadSfdp ( + IN EFI_SPI_PROTOCOL *This, + IN UINT8 ComponentNumber, + IN UINT32 Address, + IN UINT32 ByteCount, + OUT UINT8 *SfdpData + ) +{ + SPI_INSTANCE *SpiInstance; + EFI_STATUS Status; + UINT32 FlashAddress; + + SpiInstance =3D SPI_INSTANCE_FROM_SPIPROTOCOL (This); + Status =3D EFI_SUCCESS; + + if (ComponentNumber > SpiInstance->NumberOfComponents) { + ASSERT (FALSE); + return EFI_INVALID_PARAMETER; + } + + FlashAddress =3D 0; + if (ComponentNumber =3D=3D FlashComponent1) { + FlashAddress =3D SpiInstance->Component1StartAddr; + } + FlashAddress +=3D Address; + // + // Sends the command to the SPI interface to execute. + // + Status =3D SendSpiCmd ( + This, + FlashRegionAll, + FlashCycleReadSfdp, + FlashAddress, + ByteCount, + SfdpData + ); + return Status; +} + +/** + Read Jedec Id from the flash part. + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] ComponentNumber The Componen Number for chip select + @param[in] ByteCount Number of bytes in JedecId data portion = of the SPI cycle, the data size is 3 typically + @param[out] JedecId The Pointer to caller-allocated buffer c= ontaining JEDEC ID received + It is the caller's responsibility to mak= e sure Buffer is large enough for the total number of bytes read. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashReadJedecId ( + IN EFI_SPI_PROTOCOL *This, + IN UINT8 ComponentNumber, + IN UINT32 ByteCount, + OUT UINT8 *JedecId + ) +{ + SPI_INSTANCE *SpiInstance; + EFI_STATUS Status; + UINT32 Address; + + SpiInstance =3D SPI_INSTANCE_FROM_SPIPROTOCOL (This); + Status =3D EFI_SUCCESS; + + if (ComponentNumber > SpiInstance->NumberOfComponents) { + ASSERT (FALSE); + return EFI_INVALID_PARAMETER; + } + + Address =3D 0; + if (ComponentNumber =3D=3D FlashComponent1) { + Address =3D SpiInstance->Component1StartAddr; + } + + // + // Sends the command to the SPI interface to execute. + // + Status =3D SendSpiCmd ( + This, + FlashRegionAll, + FlashCycleReadJedecId, + Address, + ByteCount, + JedecId + ); + return Status; +} + +/** + Write the status register in the flash part. + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] ByteCount Number of bytes in Status data portion o= f the SPI cycle, the data size is 1 typically + @param[in] StatusValue The Pointer to caller-allocated buffer c= ontaining the value of Status register writing + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashWriteStatus ( + IN EFI_SPI_PROTOCOL *This, + IN UINT32 ByteCount, + IN UINT8 *StatusValue + ) +{ + EFI_STATUS Status; + + // + // Sends the command to the SPI interface to execute. + // + Status =3D SendSpiCmd ( + This, + FlashRegionAll, + FlashCycleWriteStatus, + 0, + ByteCount, + StatusValue + ); + return Status; +} + +/** + Read status register in the flash part. + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] ByteCount Number of bytes in Status data portion o= f the SPI cycle, the data size is 1 typically + @param[out] StatusValue The Pointer to caller-allocated buffer c= ontaining the value of Status register received. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashReadStatus ( + IN EFI_SPI_PROTOCOL *This, + IN UINT32 ByteCount, + OUT UINT8 *StatusValue + ) +{ + EFI_STATUS Status; + + // + // Sends the command to the SPI interface to execute. + // + Status =3D SendSpiCmd ( + This, + FlashRegionAll, + FlashCycleReadStatus, + 0, + ByteCount, + StatusValue + ); + return Status; +} + +/** + Get the SPI region base and size, based on the enum type + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] FlashRegionType The Flash Region type for for the base a= ddress which is listed in the Descriptor. + @param[out] BaseAddress The Flash Linear Address for the Region = 'n' Base + @param[out] RegionSize The size for the Region 'n' + + @retval EFI_SUCCESS Read success + @retval EFI_INVALID_PARAMETER Invalid region type given + @retval EFI_DEVICE_ERROR The region is not used +**/ +EFI_STATUS +EFIAPI +SpiProtocolGetRegionAddress ( + IN EFI_SPI_PROTOCOL *This, + IN FLASH_REGION_TYPE FlashRegionType, + OUT UINT32 *BaseAddress, + OUT UINT32 *RegionSize + ) +{ + SPI_INSTANCE *SpiInstance; + UINTN PchSpiBar0; + UINT32 ReadValue; + + SpiInstance =3D SPI_INSTANCE_FROM_SPIPROTOCOL (This); + + if (FlashRegionType >=3D FlashRegionMax) { + return EFI_INVALID_PARAMETER; + } + + if (FlashRegionType =3D=3D FlashRegionAll) { + *BaseAddress =3D 0; + *RegionSize =3D SpiInstance->TotalFlashSize; + return EFI_SUCCESS; + } + + PchSpiBar0 =3D AcquireSpiBar0 (SpiInstance); + ReadValue =3D MmioRead32 (PchSpiBar0 + (R_PCH_SPI_FREG0_FLASHD + (S_PCH_= SPI_FREGX * ((UINT32) FlashRegionType)))); + ReleaseSpiBar0 (SpiInstance); + + // + // If the region is not used, the Region Base is 7FFFh and Region Limit = is 0000h + // + if (ReadValue =3D=3D B_PCH_SPI_FREGX_BASE_MASK) { + return EFI_DEVICE_ERROR; + } + *BaseAddress =3D ((ReadValue & B_PCH_SPI_FREGX_BASE_MASK) >> N_PCH_SPI_F= REGX_BASE) << + N_PCH_SPI_FREGX_BASE_REPR; + // + // Region limit address Bits[11:0] are assumed to be FFFh + // + *RegionSize =3D ((((ReadValue & B_PCH_SPI_FREGX_LIMIT_MASK) >> N_PCH_SPI= _FREGX_LIMIT) + 1) << + N_PCH_SPI_FREGX_LIMIT_REPR) - *BaseAddress; + + return EFI_SUCCESS; +} + +/** + Read PCH Soft Strap Values + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] SoftStrapAddr PCH Soft Strap address offset from FPSBA. + @param[in] ByteCount Number of bytes in SoftStrap data portio= n of the SPI cycle + @param[out] SoftStrapValue The Pointer to caller-allocated buffer c= ontaining PCH Soft Strap Value. + If the value of ByteCount is 0, the data= type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Sof= t Strap Length + It is the caller's responsibility to mak= e sure Buffer is large enough for the total number of bytes read. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +EFI_STATUS +EFIAPI +SpiProtocolReadPchSoftStrap ( + IN EFI_SPI_PROTOCOL *This, + IN UINT32 SoftStrapAddr, + IN UINT32 ByteCount, + OUT VOID *SoftStrapValue + ) +{ + SPI_INSTANCE *SpiInstance; + UINT32 StrapFlashAddr; + EFI_STATUS Status; + + SpiInstance =3D SPI_INSTANCE_FROM_SPIPROTOCOL (This); + + if (ByteCount =3D=3D 0) { + *(UINT16 *) SoftStrapValue =3D SpiInstance->PchStrapSize; + return EFI_SUCCESS; + } + + if ((SoftStrapAddr + ByteCount) > (UINT32) SpiInstance->PchStrapSize) { + ASSERT (FALSE); + return EFI_INVALID_PARAMETER; + } + + // + // PCH Strap Flash Address =3D FPSBA + RamAddr + // + StrapFlashAddr =3D SpiInstance->PchStrapBaseAddr + SoftStrapAddr; + + // + // Read PCH Soft straps from using execute command + // + Status =3D SendSpiCmd ( + This, + FlashRegionDescriptor, + FlashCycleRead, + StrapFlashAddr, + ByteCount, + SoftStrapValue + ); + return Status; +} + +/** + Read CPU Soft Strap Values + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] SoftStrapAddr CPU Soft Strap address offset from FCPUS= BA. + @param[in] ByteCount Number of bytes in SoftStrap data portio= n of the SPI cycle. + @param[out] SoftStrapValue The Pointer to caller-allocated buffer c= ontaining CPU Soft Strap Value. + If the value of ByteCount is 0, the data= type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Sof= t Strap Length + It is the caller's responsibility to mak= e sure Buffer is large enough for the total number of bytes read. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +EFI_STATUS +EFIAPI +SpiProtocolReadCpuSoftStrap ( + IN EFI_SPI_PROTOCOL *This, + IN UINT32 SoftStrapAddr, + IN UINT32 ByteCount, + OUT VOID *SoftStrapValue + ) +{ + SPI_INSTANCE *SpiInstance; + UINT32 StrapFlashAddr; + EFI_STATUS Status; + + SpiInstance =3D SPI_INSTANCE_FROM_SPIPROTOCOL (This); + + if (ByteCount =3D=3D 0) { + *(UINT16 *) SoftStrapValue =3D SpiInstance->CpuStrapSize; + return EFI_SUCCESS; + } + + if ((SoftStrapAddr + ByteCount) > (UINT32) SpiInstance->CpuStrapSize) { + ASSERT (FALSE); + return EFI_INVALID_PARAMETER; + } + + // + // CPU Strap Flash Address =3D FCPUSBA + RamAddr + // + StrapFlashAddr =3D SpiInstance->CpuStrapBaseAddr + SoftStrapAddr; + + // + // Read Cpu Soft straps from using execute command + // + Status =3D SendSpiCmd ( + This, + FlashRegionDescriptor, + FlashCycleRead, + StrapFlashAddr, + ByteCount, + SoftStrapValue + ); + return Status; +} + +/** + This function sends the programmed SPI command to the slave device. + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] SpiRegionType The SPI Region type for flash cycle whic= h is listed in the Descriptor + @param[in] FlashCycleType The Flash SPI cycle type list in HSFC (H= ardware Sequencing Flash Control Register) register + @param[in] Address The Flash Linear Address must fall withi= n a region for which BIOS has access permissions. + @param[in] ByteCount Number of bytes in the data portion of t= he SPI cycle. + @param[in,out] Buffer Pointer to caller-allocated buffer conta= ining the dada received or sent during the SPI cycle. + + @retval EFI_SUCCESS SPI command completes successfully. + @retval EFI_DEVICE_ERROR Device error, the command aborts abnorma= lly. + @retval EFI_ACCESS_DENIED Some unrecognized command encountered in= hardware sequencing mode + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. +**/ +EFI_STATUS +SendSpiCmd ( + IN EFI_SPI_PROTOCOL *This, + IN FLASH_REGION_TYPE FlashRegionType, + IN FLASH_CYCLE_TYPE FlashCycleType, + IN UINT32 Address, + IN UINT32 ByteCount, + IN OUT UINT8 *Buffer + ) +{ + EFI_STATUS Status; + UINT32 Index; + SPI_INSTANCE *SpiInstance; + UINTN SpiBaseAddress; + UINTN PchSpiBar0; + UINT32 HardwareSpiAddr; + UINT32 FlashRegionSize; + UINT32 SpiDataCount; + UINT32 FlashCycle; + UINT32 SmiEnSave; + UINT16 ABase; + + Status =3D EFI_SUCCESS; + SpiInstance =3D SPI_INSTANCE_FROM_SPIPROTOCOL (This); + SpiBaseAddress =3D SpiInstance->PchSpiBase; + PchSpiBar0 =3D AcquireSpiBar0 (SpiInstance); + SpiBaseAddress =3D SpiInstance->PchSpiBase; + ABase =3D SpiInstance->PchAcpiBase; + + // + // Disable SMIs to make sure normal mode flash access is not interrupted= by an SMI + // whose SMI handler accesses flash (e.g. for error logging) + // + // *** NOTE: if the SMI_LOCK bit is set (i.e., PMC PCI Offset A0h [4]=3D= '1'), + // clearing B_GBL_SMI_EN will not have effect. In this situation, some o= ther + // synchronization methods must be applied here or in the consumer of the + // SendSpiCmd. An example method is disabling the specific SMI sources + // whose SMI handlers access flash before flash cycle and re-enabling th= e SMI + // sources after the flash cycle . + // + SmiEnSave =3D IoRead32 ((UINTN) (ABase + R_PCH_SMI_EN)); + IoWrite32 ((UINTN) (ABase + R_PCH_SMI_EN), SmiEnSave & (UINT32) (~B_PCH_= SMI_EN_GBL_SMI)); + + // + // If it's write cycle, disable Prefetching, Caching and disable BIOS Wr= ite Protect + // + if ((FlashCycleType =3D=3D FlashCycleWrite) || + (FlashCycleType =3D=3D FlashCycleErase)) { + Status =3D DisableBiosWriteProtect (); + if (EFI_ERROR (Status)) { + goto SendSpiCmdEnd; + } + } + // + // Make sure it's safe to program the command. + // + if (!WaitForSpiCycleComplete (This, PchSpiBar0, FALSE)) { + Status =3D EFI_DEVICE_ERROR; + goto SendSpiCmdEnd; + } + + Status =3D SpiProtocolGetRegionAddress (This, FlashRegionType, &Hardware= SpiAddr, &FlashRegionSize); + if (EFI_ERROR (Status)) { + goto SendSpiCmdEnd; + } + HardwareSpiAddr +=3D Address; + if ((Address + ByteCount) > FlashRegionSize) { + Status =3D EFI_INVALID_PARAMETER; + goto SendSpiCmdEnd; + } + + // + // Check for PCH SPI hardware sequencing required commands + // + FlashCycle =3D 0; + switch (FlashCycleType) { + case FlashCycleRead: + FlashCycle =3D (UINT32) (V_PCH_SPI_HSFSC_CYCLE_READ << N_PCH_SPI_HSF= SC_CYCLE); + break; + case FlashCycleWrite: + FlashCycle =3D (UINT32) (V_PCH_SPI_HSFSC_CYCLE_WRITE << N_PCH_SPI_HS= FSC_CYCLE); + break; + case FlashCycleErase: + if (((ByteCount % SIZE_4KB) !=3D 0) || + ((HardwareSpiAddr % SIZE_4KB) !=3D 0)) { + ASSERT (FALSE); + Status =3D EFI_INVALID_PARAMETER; + goto SendSpiCmdEnd; + } + break; + case FlashCycleReadSfdp: + FlashCycle =3D (UINT32) (V_PCH_SPI_HSFSC_CYCLE_READ_SFDP << N_PCH_SP= I_HSFSC_CYCLE); + break; + case FlashCycleReadJedecId: + FlashCycle =3D (UINT32) (V_PCH_SPI_HSFSC_CYCLE_READ_JEDEC_ID << N_PC= H_SPI_HSFSC_CYCLE); + break; + case FlashCycleWriteStatus: + FlashCycle =3D (UINT32) (V_PCH_SPI_HSFSC_CYCLE_WRITE_STATUS << N_PCH= _SPI_HSFSC_CYCLE); + break; + case FlashCycleReadStatus: + FlashCycle =3D (UINT32) (V_PCH_SPI_HSFSC_CYCLE_READ_STATUS << N_PCH_= SPI_HSFSC_CYCLE); + break; + default: + // + // Unrecognized Operation + // + ASSERT (FALSE); + Status =3D EFI_INVALID_PARAMETER; + goto SendSpiCmdEnd; + break; + } + + do { + SpiDataCount =3D ByteCount; + if ((FlashCycleType =3D=3D FlashCycleRead) || + (FlashCycleType =3D=3D FlashCycleWrite) || + (FlashCycleType =3D=3D FlashCycleReadSfdp)) { + // + // Trim at 256 byte boundary per operation, + // - PCH SPI controller requires trimming at 4KB boundary + // - Some SPI chips require trimming at 256 byte boundary for write = operation + // - Trimming has limited performance impact as we can read / write = atmost 64 byte + // per operation + // + if (HardwareSpiAddr + ByteCount > ((HardwareSpiAddr + BIT8) &~(BIT8 = - 1))) { + SpiDataCount =3D (((UINT32) (HardwareSpiAddr) + BIT8) &~(BIT8 - 1)= ) - (UINT32) (HardwareSpiAddr); + } + // + // Calculate the number of bytes to shift in/out during the SPI data= cycle. + // Valid settings for the number of bytes duing each data portion of= the + // PCH SPI cycles are: 0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 24, 32, 40, 48= , 56, 64 + // + if (SpiDataCount >=3D 64) { + SpiDataCount =3D 64; + } else if ((SpiDataCount &~0x07) !=3D 0) { + SpiDataCount =3D SpiDataCount &~0x07; + } + } + if (FlashCycleType =3D=3D FlashCycleErase) { + if (((ByteCount / SIZE_64KB) !=3D 0) && + ((ByteCount % SIZE_64KB) =3D=3D 0) && + ((HardwareSpiAddr % SIZE_64KB) =3D=3D 0)) { + if (HardwareSpiAddr < SpiInstance->Component1StartAddr) { + // + // Check whether Component0 support 64k Erase + // + if ((SpiInstance->SfdpVscc0Value & B_PCH_SPI_SFDPX_VSCCX_EO_64K)= !=3D 0) { + SpiDataCount =3D SIZE_64KB; + } else { + SpiDataCount =3D SIZE_4KB; + } + } else { + // + // Check whether Component1 support 64k Erase + // + if ((SpiInstance->SfdpVscc1Value & B_PCH_SPI_SFDPX_VSCCX_EO_64K)= !=3D 0) { + SpiDataCount =3D SIZE_64KB; + } else { + SpiDataCount =3D SIZE_4KB; + } + } + } else { + SpiDataCount =3D SIZE_4KB; + } + if (SpiDataCount =3D=3D SIZE_4KB) { + FlashCycle =3D (UINT32) (V_PCH_SPI_HSFSC_CYCLE_4K_ERASE << N_PCH_S= PI_HSFSC_CYCLE); + } else { + FlashCycle =3D (UINT32) (V_PCH_SPI_HSFSC_CYCLE_64K_ERASE << N_PCH_= SPI_HSFSC_CYCLE); + } + } + // + // If it's write cycle, load data into the SPI data buffer. + // + if ((FlashCycleType =3D=3D FlashCycleWrite) || (FlashCycleType =3D=3D = FlashCycleWriteStatus)) { + if ((SpiDataCount & 0x07) !=3D 0) { + // + // Use Byte write if Data Count is 0, 1, 2, 3, 4, 5, 6, 7 + // + for (Index =3D 0; Index < SpiDataCount; Index++) { + MmioWrite8 (PchSpiBar0 + R_PCH_SPI_FDATA00 + Index, Buffer[Index= ]); + } + } else { + // + // Use Dword write if Data Count is 8, 16, 24, 32, 40, 48, 56, 64 + // + for (Index =3D 0; Index < SpiDataCount; Index +=3D sizeof (UINT32)= ) { + MmioWrite32 (PchSpiBar0 + R_PCH_SPI_FDATA00 + Index, *(UINT32 *)= (Buffer + Index)); + } + } + } + + // + // Set the Flash Address + // + MmioWrite32 ( + (PchSpiBar0 + R_PCH_SPI_FADDR), + (UINT32) (HardwareSpiAddr & B_PCH_SPI_FADDR_MASK) + ); + + // + // Set Data count, Flash cycle, and Set Go bit to start a cycle + // + MmioAndThenOr32 ( + PchSpiBar0 + R_PCH_SPI_HSFSC, + (UINT32) (~(B_PCH_SPI_HSFSC_FDBC_MASK | B_PCH_SPI_HSFSC_CYCLE_MASK)), + (UINT32) ((((SpiDataCount - 1) << N_PCH_SPI_HSFSC_FDBC) & B_PCH_SPI_= HSFSC_FDBC_MASK) | FlashCycle | B_PCH_SPI_HSFSC_CYCLE_FGO) + ); + // + // end of command execution + // + // Wait the SPI cycle to complete. + // + if (!WaitForSpiCycleComplete (This, PchSpiBar0, TRUE)) { + ASSERT (FALSE); + Status =3D EFI_DEVICE_ERROR; + goto SendSpiCmdEnd; + } + // + // If it's read cycle, load data into the call's buffer. + // + if ((FlashCycleType =3D=3D FlashCycleRead) || + (FlashCycleType =3D=3D FlashCycleReadSfdp) || + (FlashCycleType =3D=3D FlashCycleReadJedecId) || + (FlashCycleType =3D=3D FlashCycleReadStatus)) { + if ((SpiDataCount & 0x07) !=3D 0) { + // + // Use Byte read if Data Count is 0, 1, 2, 3, 4, 5, 6, 7 + // + for (Index =3D 0; Index < SpiDataCount; Index++) { + Buffer[Index] =3D MmioRead8 (PchSpiBar0 + R_PCH_SPI_FDATA00 + In= dex); + } + } else { + // + // Use Dword read if Data Count is 8, 16, 24, 32, 40, 48, 56, 64 + // + for (Index =3D 0; Index < SpiDataCount; Index +=3D sizeof (UINT32)= ) { + *(UINT32 *) (Buffer + Index) =3D MmioRead32 (PchSpiBar0 + R_PCH_= SPI_FDATA00 + Index); + } + } + } + + HardwareSpiAddr +=3D SpiDataCount; + Buffer +=3D SpiDataCount; + ByteCount -=3D SpiDataCount; + } while (ByteCount > 0); + +SendSpiCmdEnd: + // + // Restore the settings for SPI Prefetching and Caching and enable BIOS = Write Protect + // + if ((FlashCycleType =3D=3D FlashCycleWrite) || + (FlashCycleType =3D=3D FlashCycleErase)) { + EnableBiosWriteProtect (); + } + // + // Restore SMIs. + // + IoWrite32 ((UINTN) (ABase + R_PCH_SMI_EN), SmiEnSave); + + ReleaseSpiBar0 (SpiInstance); + return Status; +} + +/** + Wait execution cycle to complete on the SPI interface. + + @param[in] This The SPI protocol instance + @param[in] PchSpiBar0 Spi MMIO base address + @param[in] ErrorCheck TRUE if the SpiCycle needs to do the err= or check + + @retval TRUE SPI cycle completed on the interface. + @retval FALSE Time out while waiting the SPI cycle to = complete. + It's not safe to program the next comman= d on the SPI interface. +**/ +BOOLEAN +WaitForSpiCycleComplete ( + IN EFI_SPI_PROTOCOL *This, + IN UINTN PchSpiBar0, + IN BOOLEAN ErrorCheck + ) +{ + UINT64 WaitTicks; + UINT64 WaitCount; + UINT32 Data32; + SPI_INSTANCE *SpiInstance; + + SpiInstance =3D SPI_INSTANCE_FROM_SPIPROTOCOL (This); + + // + // Convert the wait period allowed into to tick count + // + WaitCount =3D SPI_WAIT_TIME / SPI_WAIT_PERIOD; + // + // Wait for the SPI cycle to complete. + // + for (WaitTicks =3D 0; WaitTicks < WaitCount; WaitTicks++) { + Data32 =3D MmioRead32 (PchSpiBar0 + R_PCH_SPI_HSFSC); + if ((Data32 & B_PCH_SPI_HSFSC_SCIP) =3D=3D 0) { + MmioWrite32 (PchSpiBar0 + R_PCH_SPI_HSFSC, B_PCH_SPI_HSFSC_FCERR | B= _PCH_SPI_HSFSC_FDONE); + if (((Data32 & B_PCH_SPI_HSFSC_FCERR) !=3D 0) && (ErrorCheck =3D=3D = TRUE)) { + return FALSE; + } else { + return TRUE; + } + } + PchPmTimerStallRuntimeSafe (SpiInstance->PchAcpiBase, SPI_WAIT_PERIOD); + } + return FALSE; +} diff --git a/Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2= Dxe.c b/Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.c new file mode 100644 index 0000000000..268b04d25a --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.c @@ -0,0 +1,410 @@ +/** @file + A DXE_RUNTIME_DRIVER providing synchronous SMI activations via the + EFI_SMM_CONTROL2_PROTOCOL. + + We expect the PEI phase to have covered the following: + - ensure that the underlying QEMU machine type be X58 + (responsible: OvmfPkg/SmmAccess/SmmAccessPei.inf) + - ensure that the ACPI PM IO space be configured + (responsible: OvmfPkg/PlatformPei/PlatformPei.inf) + + Our own entry point is responsible for confirming the SMI feature and for + configuring it. + + Copyright (C) 2013, 2015, Red Hat, Inc.
+ Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// Forward declaration. +// +STATIC +VOID +EFIAPI +OnS3SaveStateInstalled ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +// +// The absolute IO port address of the SMI Control and Enable Register. It= is +// only used to carry information from the entry point function to the +// S3SaveState protocol installation callback, strictly before the runtime +// phase. +// +STATIC UINTN mSmiEnable; + +// +// Event signaled when an S3SaveState protocol interface is installed. +// +STATIC EFI_EVENT mS3SaveStateInstalled; + +/** + Clear the SMI status + + @retval EFI_SUCCESS The function completes successfully + @retval EFI_DEVICE_ERROR Something error occurred + +**/ +EFI_STATUS +EFIAPI +SmmClear( + VOID +) +{ + EFI_STATUS Status; + UINT32 OutputData; + UINT32 OutputPort; + UINT32 PmBase; + + Status =3D EFI_SUCCESS; + PmBase =3D ICH10_PMBASE_IO; + + OutputPort =3D PmBase + ICH10_PMBASE_OFS_SMI_STS; + OutputData =3D ICH10_SMI_STS_APM; + IoWrite32( + (UINTN)OutputPort, + (UINT32)(OutputData) + ); + + /// + /// Set the EOS Bit + /// + OutputPort =3D PmBase + ICH10_PMBASE_OFS_SMI_EN; + OutputData =3D IoRead32((UINTN)OutputPort); + OutputData |=3D ICH10_SMI_EN_EOS; + IoWrite32( + (UINTN)OutputPort, + (UINT32)(OutputData) + ); + + /// + /// There is no need to read EOS back and check if it is set. + /// This can lead to a reading of zero if an SMI occurs right after the = SMI_EN port read + /// but before the data is returned to the CPU. + /// SMM Dispatcher should make sure that EOS is set after all SMI source= s are processed. + /// + return Status; +} + +/** + Invokes SMI activation from either the preboot or runtime environment. + + This function generates an SMI. + + @param[in] This The EFI_SMM_CONTROL2_PROTOCOL instanc= e. + @param[in,out] CommandPort The value written to the command port. + @param[in,out] DataPort The value written to the data port. + @param[in] Periodic Optional mechanism to engender a peri= odic + stream. + @param[in] ActivationInterval Optional parameter to repeat at this + period one time or, if the Periodic + Boolean is set, periodically. + + @retval EFI_SUCCESS The SMI/PMI has been engendered. + @retval EFI_DEVICE_ERROR The timing is unsupported. + @retval EFI_INVALID_PARAMETER The activation period is unsupported. + @retval EFI_INVALID_PARAMETER The last periodic activation has not been + cleared. + @retval EFI_NOT_STARTED The SMM base service has not been initial= ized. +**/ +STATIC +EFI_STATUS +EFIAPI +SmmControl2DxeTrigger ( + IN CONST EFI_SMM_CONTROL2_PROTOCOL *This, + IN OUT UINT8 *CommandPort OPTIONAL, + IN OUT UINT8 *DataPort OPTIONAL, + IN BOOLEAN Periodic OPTIONAL, + IN UINTN ActivationInterval OPTIONAL + ) +{ + EFI_STATUS Status; + // + // No support for queued or periodic activation. + // + if (Periodic || ActivationInterval > 0) { + return EFI_DEVICE_ERROR; + } + /// + /// Clear any pending the APM SMI + /// + Status =3D SmmClear(); + // + // The so-called "Advanced Power Management Status Port Register" is in = fact + // a generic data passing register, between the caller and the SMI + // dispatcher. The ICH9 spec calls it "scratchpad register" -- calling = it + // "status" elsewhere seems quite the misnomer. Status registers usually + // report about hardware status, while this register is fully governed by + // software. + // + // Write to the status register first, as this won't trigger the SMI just + // yet. Then write to the control register. + // + IoWrite8 (ICH10_APM_STS, DataPort =3D=3D NULL ? 0 : *DataPort); + IoWrite8 (ICH10_APM_CNT, CommandPort =3D=3D NULL ? 0 : *CommandPort); + return EFI_SUCCESS; +} + +/** + Clears any system state that was created in response to the Trigger() ca= ll. + + This function acknowledges and causes the deassertion of the SMI activat= ion + source. + + @param[in] This The EFI_SMM_CONTROL2_PROTOCOL instance. + @param[in] Periodic Optional parameter to repeat at this peri= od + one time + + @retval EFI_SUCCESS The SMI/PMI has been engendered. + @retval EFI_DEVICE_ERROR The source could not be cleared. + @retval EFI_INVALID_PARAMETER The service did not support the Periodic = input + argument. +**/ +STATIC +EFI_STATUS +EFIAPI +SmmControl2DxeClear ( + IN CONST EFI_SMM_CONTROL2_PROTOCOL *This, + IN BOOLEAN Periodic OPTIONAL + ) +{ + EFI_STATUS Status; + + if (Periodic) { + return EFI_INVALID_PARAMETER; + } + + // + // The PI spec v1.4 explains that Clear() is only supposed to clear soft= ware + // status; it is not in fact responsible for deasserting the SMI. It giv= es + // two reasons for this: (a) many boards clear the SMI automatically when + // entering SMM, (b) if Clear() actually deasserted the SMI, then it cou= ld + // incorrectly suppress an SMI that was asynchronously asserted between = the + // last return of the SMI handler and the call made to Clear(). + // + // In fact QEMU automatically deasserts CPU_INTERRUPT_SMI in: + // - x86_cpu_exec_interrupt() [target-i386/seg_helper.c], and + // - kvm_arch_pre_run() [target-i386/kvm.c]. + // + // So, nothing to do here. + // + Status =3D SmmClear(); + + return EFI_SUCCESS; +} + +STATIC EFI_SMM_CONTROL2_PROTOCOL mControl2 =3D { + &SmmControl2DxeTrigger, + &SmmControl2DxeClear, + MAX_UINTN // MinimumTriggerPeriod -- we don't support periodic SMIs +}; + +// +// Entry point of this driver. +// +EFI_STATUS +EFIAPI +SmmControl2DxeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + UINT32 PmBase; + UINT32 SmiEnableVal; + EFI_STATUS Status; + + // + // This module should only be included if SMRAM support is required. + // + ASSERT (FeaturePcdGet (PcdSmmSmramRequire)); + + // + // Calculate the absolute IO port address of the SMI Control and Enable + // Register. (As noted at the top, the PEI phase has left us with a work= ing + // ACPI PM IO space.) + // + PmBase =3D PciRead32 (POWER_MGMT_REGISTER_ICH10 (ICH10_PMBASE)) & + ICH10_PMBASE_MASK; + mSmiEnable =3D PmBase + ICH10_PMBASE_OFS_SMI_EN; + + // + // If APMC_EN is pre-set in SMI_EN, that's QEMU's way to tell us that SMI + // support is not available. (For example due to KVM lacking it.) Otherw= ise, + // this bit is clear after each reset. + // + SmiEnableVal =3D IoRead32 (mSmiEnable); + if ((SmiEnableVal & ICH10_SMI_EN_APMC_EN) !=3D 0) { + DEBUG ((EFI_D_ERROR, "%a: this X58 implementation lacks SMI\n", + __FUNCTION__)); + } + + // + // Otherwise, configure the board to inject an SMI when ICH10_APM_CNT is + // written to. (See the Trigger() method above.) + // + SmiEnableVal |=3D ICH10_SMI_EN_APMC_EN | ICH10_SMI_EN_GBL_SMI_EN; + IoWrite32 (mSmiEnable, SmiEnableVal); + + // + // Prevent software from undoing the above (until platform reset). + // + PciOr16 (POWER_MGMT_REGISTER_ICH10 (ICH10_GEN_PMCON_1), + ICH10_GEN_PMCON_1_SMI_LOCK); + + // + // If we can clear GBL_SMI_EN now, that means QEMU's SMI support is not + // appropriate. + // + IoWrite32 (mSmiEnable, SmiEnableVal & ~(UINT32)ICH10_SMI_EN_GBL_SMI_EN); + if (IoRead32 (mSmiEnable) !=3D SmiEnableVal) { + DEBUG ((EFI_D_ERROR, "%a: failed to lock down GBL_SMI_EN\n", + __FUNCTION__)); + goto FatalError; + } + + VOID *Registration; + + // + // On S3 resume the above register settings have to be repeated. Registe= r a + // protocol notify callback that, when boot script saving becomes + // available, saves operations equivalent to the above to the boot scrip= t. + // + Status =3D gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK, + OnS3SaveStateInstalled, NULL /* Context */, + &mS3SaveStateInstalled); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "%a: CreateEvent: %r\n", __FUNCTION__, Status)); + goto FatalError; + } + + Status =3D gBS->RegisterProtocolNotify (&gEfiS3SaveStateProtocolGuid, + mS3SaveStateInstalled, &Registration); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "%a: RegisterProtocolNotify: %r\n", __FUNCTION__, + Status)); + goto ReleaseEvent; + } + + // + // Kick the event right now -- maybe the boot script is already saveable. + // + Status =3D gBS->SignalEvent (mS3SaveStateInstalled); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "%a: SignalEvent: %r\n", __FUNCTION__, Status)); + goto ReleaseEvent; + } + + // + // We have no pointers to convert to virtual addresses. The handle itself + // doesn't matter, as protocol services are not accessible at runtime. + // + Status =3D gBS->InstallMultipleProtocolInterfaces (&ImageHandle, + &gEfiSmmControl2ProtocolGuid, &mControl2, + NULL); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "%a: InstallMultipleProtocolInterfaces: %r\n", + __FUNCTION__, Status)); + goto ReleaseEvent; + } + + return EFI_SUCCESS; + +ReleaseEvent: + if (mS3SaveStateInstalled !=3D NULL) { + gBS->CloseEvent (mS3SaveStateInstalled); + } + +FatalError: + // + // We really don't want to continue in this case. + // + ASSERT (FALSE); + CpuDeadLoop (); + return EFI_UNSUPPORTED; +} + +/** + Notification callback for S3SaveState installation. + + @param[in] Event Event whose notification function is being invoked. + + @param[in] Context The pointer to the notification function's context, = which + is implementation-dependent. +**/ +STATIC +VOID +EFIAPI +OnS3SaveStateInstalled ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EFI_S3_SAVE_STATE_PROTOCOL *S3SaveState; + UINT32 SmiEnOrMask, SmiEnAndMask; + UINT16 GenPmCon1OrMask, GenPmCon1AndMask; + + ASSERT (Event =3D=3D mS3SaveStateInstalled); + + Status =3D gBS->LocateProtocol (&gEfiS3SaveStateProtocolGuid, + NULL /* Registration */, (VOID **)&S3SaveState); + if (EFI_ERROR (Status)) { + return; + } + + // + // These operations were originally done, verified and explained in the = entry + // point function of the driver. + // + SmiEnOrMask =3D ICH10_SMI_EN_APMC_EN | ICH10_SMI_EN_GBL_SMI_EN; + SmiEnAndMask =3D MAX_UINT32; + Status =3D S3SaveState->Write ( + S3SaveState, + EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE, + EfiBootScriptWidthUint32, + (UINT64)mSmiEnable, + &SmiEnOrMask, + &SmiEnAndMask + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "%a: EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE: %r\n", + __FUNCTION__, Status)); + ASSERT (FALSE); + CpuDeadLoop (); + } + + GenPmCon1OrMask =3D ICH10_GEN_PMCON_1_SMI_LOCK; + GenPmCon1AndMask =3D MAX_UINT16; + Status =3D S3SaveState->Write ( + S3SaveState, + EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE, + EfiBootScriptWidthUint16, + (UINT64)POWER_MGMT_REGISTER_ICH10 (ICH10_GEN_PMC= ON_1), + &GenPmCon1OrMask, + &GenPmCon1AndMask + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, + "%a: EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE: %r\n", __FUNCTION= __, + Status)); + ASSERT (FALSE); + CpuDeadLoop (); + } + + DEBUG ((EFI_D_VERBOSE, "%a: boot script fragment saved\n", __FUNCTION__)= ); + gBS->CloseEvent (Event); + mS3SaveStateInstalled =3D NULL; +} diff --git a/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.c b/Silicon/Intel/= SimicsIch10Pkg/Spi/Smm/PchSpi.c new file mode 100644 index 0000000000..0baf730a48 --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.c @@ -0,0 +1,175 @@ +/** @file + PCH SPI SMM Driver implements the SPI Host Controller Compatibility Inte= rface. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "PchSpi.h" + +// +// Global variables +// +GLOBAL_REMOVE_IF_UNREFERENCED SPI_INSTANCE *mSpiInstance; +// +// mPchSpiResvMmioAddr keeps the reserved MMIO range assiged to SPI. +// In SMM it always set back the reserved MMIO address to SPI BAR0 to ensu= re the MMIO range +// won't overlap with SMRAM range, and trusted. +// +GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mSpiResvMmioAddr; + +/** + SPI Runtime SMM Module Entry Point\n + - Introduction\n + The SPI SMM module provide a standard way for other modules to use the= PCH SPI Interface in SMM. + + - @pre + - EFI_SMM_BASE2_PROTOCOL + - Documented in System Management Mode Core Interface Specification . + + - @result + The SPI SMM driver produces @link _PCH_SPI_PROTOCOL PCH_SPI_PROTOCOL @= endlink with GUID + gPchSmmSpiProtocolGuid which is different from SPI RUNTIME driver. + + - Integration Check List\n + - This driver supports Descriptor Mode only. + - This driver supports Hardware Sequence only. + - When using SMM SPI Protocol to perform flash access in an SMI handle= r, + and the SMI occurrence is asynchronous to normal mode code execution, + proper synchronization mechanism must be applied, e.g. disable SMI b= efore + the normal mode SendSpiCmd() starts and re-enable SMI after + the normal mode SendSpiCmd() completes. + @note The implementation of SendSpiCmd() uses GBL_SMI_EN in + SMI_EN register (ABase + 30h) to disable and enable SMIs. But this m= ay + not be effective as platform may well set the SMI_LOCK bit (i.e., PM= C PCI Offset A0h [4]). + So the synchronization at caller level is likely needed. + + @param[in] ImageHandle Image handle of this driver. + @param[in] SystemTable Global system service table. + + @retval EFI_SUCCESS Initialization complete. + @exception EFI_UNSUPPORTED The chipset is unsupported by this drive= r. + @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initiali= ze the driver. + @retval EFI_DEVICE_ERROR Device error, driver exits abnormally. +**/ +EFI_STATUS +EFIAPI +InstallPchSpi ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + // + // Init PCH spi reserved MMIO address. + // + mSpiResvMmioAddr =3D PCH_SPI_BASE_ADDRESS; + + /// + /// Allocate pool for SPI protocol instance + /// + Status =3D gSmst->SmmAllocatePool ( + EfiRuntimeServicesData, /// MemoryType don't care + sizeof (SPI_INSTANCE), + (VOID **) &mSpiInstance + ); + if (EFI_ERROR (Status)) { + return Status; + } + + if (mSpiInstance =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ZeroMem ((VOID *) mSpiInstance, sizeof (SPI_INSTANCE)); + /// + /// Initialize the SPI protocol instance + /// + Status =3D SpiProtocolConstructor (mSpiInstance); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Install the SMM EFI_SPI_PROTOCOL interface + // + Status =3D gSmst->SmmInstallProtocolInterface ( + &(mSpiInstance->Handle), + &gEfiSmmSpiProtocolGuid, + EFI_NATIVE_INTERFACE, + &(mSpiInstance->SpiProtocol) + ); + if (EFI_ERROR (Status)) { + gSmst->SmmFreePool (mSpiInstance); + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Acquire PCH spi mmio address. + It is not expected for this BAR0 to change because the SPI device is hid= den + from the OS for SKL PCH LP/H B stepping and above (refer to section 3.5.= 1), + but if it is ever different from the preallocated address, reassign it b= ack. + In SMM, it always override the BAR0 and returns the reserved MMIO range = for SPI. + + @param[in] SpiInstance Pointer to SpiInstance to initialize + + @retval PchSpiBar0 return SPI MMIO address +**/ +UINTN +AcquireSpiBar0 ( + IN SPI_INSTANCE *SpiInstance + ) +{ + // + // SPIBAR0 will be different before and after PCI enum so need to get it= from SPI BAR0 reg. + // + return mSpiResvMmioAddr; +} + +/** + Release pch spi mmio address. Do nothing. + + @param[in] SpiInstance Pointer to SpiInstance to initialize + + @retval None +**/ +VOID +ReleaseSpiBar0 ( + IN SPI_INSTANCE *SpiInstance + ) +{ +} + +/** + This function is a hook for Spi to disable BIOS Write Protect + + @retval EFI_SUCCESS The protocol instance was properly initi= alized + @retval EFI_ACCESS_DENIED The BIOS Region can only be updated in S= MM phase + +**/ +EFI_STATUS +EFIAPI +DisableBiosWriteProtect ( + VOID + ) +{ + + return EFI_SUCCESS; +} + +/** + This function is a hook for Spi to enable BIOS Write Protect + + +**/ +VOID +EFIAPI +EnableBiosWriteProtect ( + VOID + ) +{ +} diff --git a/Silicon/Intel/SimicsIch10Pkg/Ich10Pkg.dec b/Silicon/Intel/Simi= csIch10Pkg/Ich10Pkg.dec new file mode 100644 index 0000000000..ad0a599fc5 --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/Ich10Pkg.dec @@ -0,0 +1,26 @@ +## @file +# Copyright (c) 2014 - 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + DEC_SPECIFICATION =3D 0x00010005 + PACKAGE_NAME =3D Ich10Pkg + PACKAGE_GUID =3D 4E97AC4B-F64C-4008-BBDE-01CC3B0BAA6B + PACKAGE_VERSION =3D 0.91 + +[Includes] + Include + +[Ppis] + +[Guids] + gEfiPchTokenSpaceGuid =3D { 0x89a1b278, 0xa1a1, 0x4df7, { 0xb1, 0x37, 0x= de, 0x5a, 0xd7, 0xc4, 0x79, 0x13 } } +[Protocols] + gEfiSmmSpiProtocolGuid =3D {0xbd75fe35, 0xfdce, 0x49d7, {0xa9, 0xdd, 0xb= 2, 0x6f, 0x1f, 0xc6, 0xb4, 0x37}} + +[PcdsFixedAtBuild] + gEfiPchTokenSpaceGuid.PcdFlashAreaBaseAddress|0xFFE00000|UINT32|0x100000= 01 + gEfiPchTokenSpaceGuid.PcdFlashAreaSize|0x00200000|UINT32|0x10000002 \ No newline at end of file diff --git a/Silicon/Intel/SimicsIch10Pkg/IchCommonLib.dsc b/Silicon/Intel/= SimicsIch10Pkg/IchCommonLib.dsc new file mode 100644 index 0000000000..f788fb89d9 --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/IchCommonLib.dsc @@ -0,0 +1,12 @@ +## @file +# Component description file for the Simics Ich10 SiPkg DXE libraries. +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[LibraryClasses.common] + ResetSystemLib|$(PCH_PKG)/Library/ResetSystemLib/ResetSystemLib.inf + PchSpiCommonLib|$(PCH_PKG)/LibraryPrivate/BasePchSpiCommonLib/BasePchSpi= CommonLib.inf diff --git a/Silicon/Intel/SimicsIch10Pkg/IchPostMemoryInclude.fdf b/Silico= n/Intel/SimicsIch10Pkg/IchPostMemoryInclude.fdf new file mode 100644 index 0000000000..8c9d3c4421 --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/IchPostMemoryInclude.fdf @@ -0,0 +1,9 @@ +## @file +# Component description file for the Simics Ich10 SiPkg DXE drivers. +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + diff --git a/Silicon/Intel/SimicsIch10Pkg/IchPreMemoryInclude.fdf b/Silicon= /Intel/SimicsIch10Pkg/IchPreMemoryInclude.fdf new file mode 100644 index 0000000000..079b81574b --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/IchPreMemoryInclude.fdf @@ -0,0 +1,9 @@ +## @file +# Component description file for the Ich10 SiPkg PEI drivers. +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + diff --git a/Silicon/Intel/SimicsIch10Pkg/IchUefiBootInclude.fdf b/Silicon/= Intel/SimicsIch10Pkg/IchUefiBootInclude.fdf new file mode 100644 index 0000000000..8211a8a627 --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/IchUefiBootInclude.fdf @@ -0,0 +1,13 @@ +## @file +# Component description file for the Simics Ich10 SiPkg DXE drivers. +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly =3D=3D FALSE + INF $(PCH_PKG)/SmmControl/RuntimeDxe/SmmControl2Dxe.inf + INF $(PCH_PKG)/Spi/Smm/PchSpiSmm.inf +!endif diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/Library/SpiFlashCommonLib= .h b/Silicon/Intel/SimicsIch10Pkg/Include/Library/SpiFlashCommonLib.h new file mode 100644 index 0000000000..53c11bb59a --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/Include/Library/SpiFlashCommonLib.h @@ -0,0 +1,98 @@ +/** @file + The header file includes the common header files, defines + internal structure and functions used by SpiFlashCommonLib. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __SPI_FLASH_COMMON_LIB_H__ +#define __SPI_FLASH_COMMON_LIB_H__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define SECTOR_SIZE_4KB 0x1000 // Common 4kBytes sector size +/** + Enable block protection on the Serial Flash device. + + @retval EFI_SUCCESS Opertion is successful. + @retval EFI_DEVICE_ERROR If there is any device errors. + +**/ +EFI_STATUS +EFIAPI +SpiFlashLock ( + VOID + ); + +/** + Read NumBytes bytes of data from the address specified by + PAddress into Buffer. + + @param[in] Address The starting physical address of the read. + @param[in,out] NumBytes On input, the number of bytes to read. On = output, the number + of bytes actually read. + @param[out] Buffer The destination data buffer for the read. + + @retval EFI_SUCCESS Opertion is successful. + @retval EFI_DEVICE_ERROR If there is any device errors. + +**/ +EFI_STATUS +EFIAPI +SpiFlashRead ( + IN UINTN Address, + IN OUT UINT32 *NumBytes, + OUT UINT8 *Buffer + ); + +/** + Write NumBytes bytes of data from Buffer to the address specified by + PAddresss. + + @param[in] Address The starting physical address of the wri= te. + @param[in,out] NumBytes On input, the number of bytes to write. = On output, + the actual number of bytes written. + @param[in] Buffer The source data buffer for the write. + + @retval EFI_SUCCESS Opertion is successful. + @retval EFI_DEVICE_ERROR If there is any device errors. + +**/ +EFI_STATUS +EFIAPI +SpiFlashWrite ( + IN UINTN Address, + IN OUT UINT32 *NumBytes, + IN UINT8 *Buffer + ); + +/** + Erase the block starting at Address. + + @param[in] Address The starting physical address of the block t= o be erased. + This library assume that caller garantee tha= t the PAddress + is at the starting address of this block. + @param[in] NumBytes On input, the number of bytes of the logical= block to be erased. + On output, the actual number of bytes erased. + + @retval EFI_SUCCESS. Opertion is successful. + @retval EFI_DEVICE_ERROR If there is any device errors. + +**/ +EFI_STATUS +EFIAPI +SpiFlashBlockErase ( + IN UINTN Address, + IN UINTN *NumBytes + ); + +#endif diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/PchAccess.h b/Silicon/Int= el/SimicsIch10Pkg/Include/PchAccess.h new file mode 100644 index 0000000000..8be6ecd83b --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/Include/PchAccess.h @@ -0,0 +1,43 @@ +/** @file + Macros that simplify accessing PCH devices's PCI registers. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _PCH_ACCESS_H_ +#define _PCH_ACCESS_H_ + +#include "PchReservedResources.h" + +#ifndef STALL_ONE_MICRO_SECOND +#define STALL_ONE_MICRO_SECOND 1 +#endif +#ifndef STALL_ONE_SECOND +#define STALL_ONE_SECOND 1000000 +#endif + + +/// +/// The default PCH PCI bus number +/// +#define DEFAULT_PCI_BUS_NUMBER_PCH 0 + +// +// Default Vendor ID and Subsystem ID +// +#define V_PCH_INTEL_VENDOR_ID 0x8086 ///< Default Intel PCH Vendor = ID +#define V_PCH_DEFAULT_SID 0x7270 ///< Default Intel PCH Subsyst= em ID +#define V_PCH_DEFAULT_SVID_SID (V_INTEL_VENDOR_ID + (V_PCH_DEFAULT_SID <<= 16)) ///< Default INTEL PCH Vendor ID and Subsystem ID + +// +// Include device register definitions +// + +#include "Register/PchRegsPmc.h" + +#include "Register/PchRegsSpi.h" + +#endif + diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/PchLimits.h b/Silicon/Int= el/SimicsIch10Pkg/Include/PchLimits.h new file mode 100644 index 0000000000..35bb5741a8 --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/Include/PchLimits.h @@ -0,0 +1,94 @@ +/** @file + Build time limits of PCH resources. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _PCH_LIMITS_H_ +#define _PCH_LIMITS_H_ + +// +// PCIe limits +// +#define PCH_MAX_PCIE_ROOT_PORTS PCH_H_PCIE_MAX_ROOT_PORTS +#define PCH_H_PCIE_MAX_ROOT_PORTS 20 +#define PCH_LP_PCIE_MAX_ROOT_PORTS 12 + +#define PCH_MAX_PCIE_CONTROLLERS PCH_H_PCIE_MAX_CONTROLLERS +#define PCH_PCIE_CONTROLLER_PORTS 4 +#define PCH_H_PCIE_MAX_CONTROLLERS (PCH_H_PCIE_MAX_ROOT_PORTS / P= CH_PCIE_CONTROLLER_PORTS) +#define PCH_LP_PCIE_MAX_CONTROLLERS (PCH_LP_PCIE_MAX_ROOT_PORTS / = PCH_PCIE_CONTROLLER_PORTS) + +// +// PCIe clocks limits +// +#define PCH_LP_PCIE_MAX_CLK_REQ 6 +#define PCH_H_PCIE_MAX_CLK_REQ 16 + +// +// RST PCIe Storage Cycle Router limits +// +#define PCH_MAX_RST_PCIE_STORAGE_CR 3 + +// +// SATA limits +// +#define PCH_MAX_SATA_PORTS PCH_H_AHCI_MAX_PORTS +#define PCH_H_AHCI_MAX_PORTS 8 ///< Max number of sat= a ports in SKL PCH H +#define PCH_LP_AHCI_MAX_PORTS 3 ///< Max number of sat= a ports in SKL PCH LP +#define PCH_SATA_MAX_DEVICES_PER_PORT 1 ///< Max support devic= e numner per port, Port Multiplier is not support. + +// +// USB limits +// +#define PCH_MAX_USB2_PORTS PCH_H_XHCI_MAX_USB2_PORTS + +#define PCH_H_XHCI_MAX_USB2_PHYSICAL_PORTS 14 ///< Max Physical Conn= ector XHCI, not counting virtual ports like USB-R. +#define PCH_LP_XHCI_MAX_USB2_PHYSICAL_PORTS 10 ///< Max Physical Conn= ector XHCI, not counting virtual ports like USB-R. + +#define PCH_H_XHCI_MAX_USB2_PORTS 16 ///< 14 High Speed lan= es + Including two ports reserved for USBr +#define PCH_LP_XHCI_MAX_USB2_PORTS 12 ///< 10 High Speed lan= es + Including two ports reserved for USBr + +#define PCH_MAX_USB3_PORTS PCH_H_XHCI_MAX_USB3_PORTS + +#define PCH_H_XHCI_MAX_USB3_PORTS 10 ///< 10 Super Speed la= nes +#define PCH_LP_XHCI_MAX_USB3_PORTS 6 ///< 6 Super Speed lan= es + +#define PCH_XHCI_MAX_SSIC_PORT_COUNT 2 ///< 2 SSIC ports in S= KL PCH-LP and SKL PCH-H + +// +// SerialIo limits +// +#define PCH_SERIALIO_MAX_CONTROLLERS 11 ///< Number of SerialIo c= ontrollers, this includes I2C, SPI and UART +#define PCH_SERIALIO_MAX_I2C_CONTROLLERS 6 ///< Number of SerialIo I= 2C controllers +#define PCH_LP_SERIALIO_MAX_I2C_CONTROLLERS 6 ///< Number of SerialIo I= 2C controllers for PCH-LP +#define PCH_H_SERIALIO_MAX_I2C_CONTROLLERS 4 ///< Number of SerialIo I= 2C controllers for PCH-H +#define PCH_SERIALIO_MAX_SPI_CONTROLLERS 2 ///< Number of SerialIo S= PI controllers +#define PCH_SERIALIO_MAX_UART_CONTROLLERS 3 ///< Number of SerialIo U= ART controllers + +// +// ISH limits +// +#define PCH_ISH_MAX_GP_PINS 8 +#define PCH_ISH_MAX_UART_CONTROLLERS 2 +#define PCH_ISH_MAX_I2C_CONTROLLERS 3 +#define PCH_ISH_MAX_SPI_CONTROLLERS 1 + +// +// SCS limits +// +#define PCH_SCS_MAX_CONTROLLERS 3 ///< Number of Storage and C= ommunication Subsystem controllers, this includes eMMC, SDIO, SDCARD + +// +// Flash Protection Range Register +// +#define PCH_FLASH_PROTECTED_RANGES 5 + +// +// Number of eSPI slaves +// +#define PCH_ESPI_MAX_SLAVE_ID 2 +#endif // _PCH_LIMITS_H_ + diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/PchReservedResources.h b/= Silicon/Intel/SimicsIch10Pkg/Include/PchReservedResources.h new file mode 100644 index 0000000000..5e978237dd --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/Include/PchReservedResources.h @@ -0,0 +1,60 @@ +/** @file + PCH preserved MMIO resource definitions. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _PCH_PRESERVED_RESOURCES_H_ +#define _PCH_PRESERVED_RESOURCES_H_ + +/** + PCH preserved MMIO range, 24 MB, from 0xFD000000 to 0xFE7FFFFF + + Detailed recommended static allocation + +-----------------------------------------------------------------------= --+ + | Size | Start | End | Usage = | + | 16 MB | 0xFD000000 | 0xFDFFFFFF | SBREG = | + | 64 KB | 0xFE000000 | 0xFE00FFFF | PMC MBAR = | + | 4 KB | 0xFE010000 | 0xFE010FFF | SPI BAR0 = | + | 88 KB | 0xFE020000 | 0xFE035FFF | SerialIo BAR in ACPI mode = | + | 24 KB | 0xFE036000 | 0xFE03BFFF | Unused = | + | 4 KB | 0xFE03C000 | 0xFE03CFFF | Thermal Device in ACPI mode = | + | 524 KB | 0xFE03D000 | 0xFE0BFFFF | Unused = | + | 256 KB | 0xFE0C0000 | 0xFE0FFFFF | TraceHub FW BAR = | + | 1 MB | 0xFE100000 | 0xFE1FFFFF | TraceHub MTB BAR = | + | 2 MB | 0xFE200000 | 0xFE3FFFFF | TraceHub SW BAR = | + | 64 KB | 0xFE400000 | 0xFE40FFFF | CIO2 MMIO BAR in ACPI mode = | + | 2 MB - 64KB | 0xFE410000 | 0xFE5FFFFF | Unused = | + | 2 MB | 0xFE600000 | 0xFE7FFFFF | Temp address = | + +-----------------------------------------------------------------------= --+ +**/ +#define PCH_PRESERVED_BASE_ADDRESS 0xFD000000 ///< Pch preserved = MMIO base address +#define PCH_PRESERVED_MMIO_SIZE 0x01800000 ///< 24MB +#define PCH_PCR_BASE_ADDRESS 0xFD000000 ///< SBREG MMIO bas= e address +#define PCH_PCR_MMIO_SIZE 0x01000000 ///< 16MB +#define PCH_PWRM_BASE_ADDRESS 0xFE000000 ///< PMC MBAR MMIO = base address +#define PCH_PWRM_MMIO_SIZE 0x00010000 ///< 64KB +#define PCH_SPI_BASE_ADDRESS 0xFED1C000 + 0x3800 ///< SPI M= BAR MMIO base address +#define PCH_SPI_MMIO_SIZE 0x00001000 ///< 4KB +#define PCH_SERIAL_IO_BASE_ADDRESS 0xFE020000 ///< SerialIo MMIO = base address +#define PCH_SERIAL_IO_MMIO_SIZE 0x00016000 ///< 88KB +#define PCH_THERMAL_BASE_ADDRESS 0xFE03C000 ///< Thermal Device= in ACPI mode +#define PCH_THERMAL_MMIO_SIZE 0x00001000 ///< 4KB +#define PCH_TRACE_HUB_FW_BASE_ADDRESS 0xFE0C0000 ///< TraceHub FW MM= IO base address +#define PCH_TRACE_HUB_FW_MMIO_SIZE 0x00040000 ///< 256KB +#define PCH_TRACE_HUB_MTB_BASE_ADDRESS 0xFE100000 ///< TraceHub MTB M= MIO base address +#define PCH_TRACE_HUB_MTB_MMIO_SIZE 0x00100000 ///< 1MB +#define PCH_TRACE_HUB_SW_BASE_ADDRESS 0xFE200000 ///< TraceHub SW MM= IO base address +#define PCH_TRACE_HUB_SW_MMIO_SIZE 0x00200000 ///< 2MB +#define PCH_CIO2_BASE_ADDRESS 0xFE400000 ///< CIO2 MMIO BAR = in ACPI mode +#define PCH_CIO2_MMIO_SIZE 0x00010000 ///< 64KB +#define PCH_TEMP_BASE_ADDRESS 0xFE600000 ///< preserved temp= address for misc usage +#define PCH_TEMP_MMIO_SIZE 0x00200000 ///< 2MB + +#define RCRB 0xFED1C000 +#define SPIBAR 0x3800 + +#endif // _PCH_PRESERVED_RESOURCES_H_ + diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/Protocol/Spi.h b/Silicon/= Intel/SimicsIch10Pkg/Include/Protocol/Spi.h new file mode 100644 index 0000000000..b0c5b3d0e6 --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/Include/Protocol/Spi.h @@ -0,0 +1,295 @@ +/** @file + This file defines the PCH SPI Protocol which implements the + Intel(R) PCH SPI Host Controller Compatibility Interface. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _PCH_SPI_PROTOCOL_H_ +#define _PCH_SPI_PROTOCOL_H_ + +// +// Extern the GUID for protocol users. +// +extern EFI_GUID gEfiSpiProtocolGuid; +extern EFI_GUID gEfiSmmSpiProtocolGuid; + +// +// Forward reference for ANSI C compatibility +// +typedef struct _PCH_SPI_PROTOCOL EFI_SPI_PROTOCOL; + +// +// SPI protocol data structures and definitions +// + +/** + Flash Region Type +**/ +typedef enum { + FlashRegionDescriptor, + FlashRegionBios, + FlashRegionMe, + FlashRegionGbE, + FlashRegionPlatformData, + FlashRegionDer, + FlashRegionAll, + FlashRegionMax +} FLASH_REGION_TYPE; + + +// +// Protocol member functions +// + +/** + Read data from the flash part. + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] FlashRegionType The Flash Region type for flash cycle wh= ich is listed in the Descriptor. + @param[in] Address The Flash Linear Address must fall withi= n a region for which BIOS has access permissions. + @param[in] ByteCount Number of bytes in the data portion of t= he SPI cycle. + @param[out] Buffer The Pointer to caller-allocated buffer c= ontaining the dada received. + It is the caller's responsibility to mak= e sure Buffer is large enough for the total number of bytes read. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +typedef +EFI_STATUS +(EFIAPI *PCH_SPI_FLASH_READ) ( + IN EFI_SPI_PROTOCOL *This, + IN FLASH_REGION_TYPE FlashRegionType, + IN UINT32 Address, + IN UINT32 ByteCount, + OUT UINT8 *Buffer + ); + +/** + Write data to the flash part. Remark: Erase may be needed before write t= o the flash part. + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] FlashRegionType The Flash Region type for flash cycle wh= ich is listed in the Descriptor. + @param[in] Address The Flash Linear Address must fall withi= n a region for which BIOS has access permissions. + @param[in] ByteCount Number of bytes in the data portion of t= he SPI cycle. + @param[in] Buffer Pointer to caller-allocated buffer conta= ining the data sent during the SPI cycle. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +typedef +EFI_STATUS +(EFIAPI *PCH_SPI_FLASH_WRITE) ( + IN EFI_SPI_PROTOCOL *This, + IN FLASH_REGION_TYPE FlashRegionType, + IN UINT32 Address, + IN UINT32 ByteCount, + IN UINT8 *Buffer + ); + +/** + Erase some area on the flash part. + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] FlashRegionType The Flash Region type for flash cycle wh= ich is listed in the Descriptor. + @param[in] Address The Flash Linear Address must fall withi= n a region for which BIOS has access permissions. + @param[in] ByteCount Number of bytes in the data portion of t= he SPI cycle. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +typedef +EFI_STATUS +(EFIAPI *PCH_SPI_FLASH_ERASE) ( + IN EFI_SPI_PROTOCOL *This, + IN FLASH_REGION_TYPE FlashRegionType, + IN UINT32 Address, + IN UINT32 ByteCount + ); + +/** + Read SFDP data from the flash part. + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] ComponentNumber The Componen Number for chip select + @param[in] Address The starting byte address for SFDP data = read. + @param[in] ByteCount Number of bytes in SFDP data portion of = the SPI cycle + @param[out] SfdpData The Pointer to caller-allocated buffer c= ontaining the SFDP data received + It is the caller's responsibility to mak= e sure Buffer is large enough for the total number of bytes read + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +typedef +EFI_STATUS +(EFIAPI *PCH_SPI_FLASH_READ_SFDP) ( + IN EFI_SPI_PROTOCOL *This, + IN UINT8 ComponentNumber, + IN UINT32 Address, + IN UINT32 ByteCount, + OUT UINT8 *SfdpData + ); + +/** + Read Jedec Id from the flash part. + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] ComponentNumber The Componen Number for chip select + @param[in] ByteCount Number of bytes in JedecId data portion = of the SPI cycle, the data size is 3 typically + @param[out] JedecId The Pointer to caller-allocated buffer c= ontaining JEDEC ID received + It is the caller's responsibility to mak= e sure Buffer is large enough for the total number of bytes read. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +typedef +EFI_STATUS +(EFIAPI *PCH_SPI_FLASH_READ_JEDEC_ID) ( + IN EFI_SPI_PROTOCOL *This, + IN UINT8 ComponentNumber, + IN UINT32 ByteCount, + OUT UINT8 *JedecId + ); + +/** + Write the status register in the flash part. + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] ByteCount Number of bytes in Status data portion o= f the SPI cycle, the data size is 1 typically + @param[in] StatusValue The Pointer to caller-allocated buffer c= ontaining the value of Status register writing + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +typedef +EFI_STATUS +(EFIAPI *PCH_SPI_FLASH_WRITE_STATUS) ( + IN EFI_SPI_PROTOCOL *This, + IN UINT32 ByteCount, + IN UINT8 *StatusValue + ); + +/** + Read status register in the flash part. + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] ByteCount Number of bytes in Status data portion o= f the SPI cycle, the data size is 1 typically + @param[out] StatusValue The Pointer to caller-allocated buffer c= ontaining the value of Status register received. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +typedef +EFI_STATUS +(EFIAPI *PCH_SPI_FLASH_READ_STATUS) ( + IN EFI_SPI_PROTOCOL *This, + IN UINT32 ByteCount, + OUT UINT8 *StatusValue + ); + +/** + Get the SPI region base and size, based on the enum type + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] FlashRegionType The Flash Region type for for the base a= ddress which is listed in the Descriptor. + @param[out] BaseAddress The Flash Linear Address for the Region = 'n' Base + @param[out] RegionSize The size for the Region 'n' + + @retval EFI_SUCCESS Read success + @retval EFI_INVALID_PARAMETER Invalid region type given + @retval EFI_DEVICE_ERROR The region is not used +**/ +typedef +EFI_STATUS +(EFIAPI *PCH_SPI_GET_REGION_ADDRESS) ( + IN EFI_SPI_PROTOCOL *This, + IN FLASH_REGION_TYPE FlashRegionType, + OUT UINT32 *BaseAddress, + OUT UINT32 *RegionSize + ); + +/** + Read PCH Soft Strap Values + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] SoftStrapAddr PCH Soft Strap address offset from FPSBA. + @param[in] ByteCount Number of bytes in SoftStrap data portio= n of the SPI cycle + @param[out] SoftStrapValue The Pointer to caller-allocated buffer c= ontaining PCH Soft Strap Value. + If the value of ByteCount is 0, the data= type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Sof= t Strap Length + It is the caller's responsibility to mak= e sure Buffer is large enough for the total number of bytes read. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +typedef +EFI_STATUS +(EFIAPI *PCH_SPI_READ_PCH_SOFTSTRAP) ( + IN EFI_SPI_PROTOCOL *This, + IN UINT32 SoftStrapAddr, + IN UINT32 ByteCount, + OUT VOID *SoftStrapValue + ); + +/** + Read CPU Soft Strap Values + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] SoftStrapAddr CPU Soft Strap address offset from FCPUS= BA. + @param[in] ByteCount Number of bytes in SoftStrap data portio= n of the SPI cycle. + @param[out] SoftStrapValue The Pointer to caller-allocated buffer c= ontaining CPU Soft Strap Value. + If the value of ByteCount is 0, the data= type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Sof= t Strap Length + It is the caller's responsibility to mak= e sure Buffer is large enough for the total number of bytes read. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +typedef +EFI_STATUS +(EFIAPI *PCH_SPI_READ_CPU_SOFTSTRAP) ( + IN EFI_SPI_PROTOCOL *This, + IN UINT32 SoftStrapAddr, + IN UINT32 ByteCount, + OUT VOID *SoftStrapValue + ); + +/** + These protocols/PPI allows a platform module to perform SPI operations t= hrough the + Intel PCH SPI Host Controller Interface. +**/ +struct _PCH_SPI_PROTOCOL { + /** + This member specifies the revision of this structure. This field is us= ed to + indicate backwards compatible changes to the protocol. + **/ + UINT8 Revision; + PCH_SPI_FLASH_READ FlashRead; ///< Read data fro= m the flash part. + PCH_SPI_FLASH_WRITE FlashWrite; ///< Write data to= the flash part. Remark: Erase may be needed before write to the flash part. + PCH_SPI_FLASH_ERASE FlashErase; ///< Erase some ar= ea on the flash part. + PCH_SPI_FLASH_READ_SFDP FlashReadSfdp; ///< Read SFDP dat= a from the flash part. + PCH_SPI_FLASH_READ_JEDEC_ID FlashReadJedecId; ///< Read Jedec Id= from the flash part. + PCH_SPI_FLASH_WRITE_STATUS FlashWriteStatus; ///< Write the sta= tus register in the flash part. + PCH_SPI_FLASH_READ_STATUS FlashReadStatus; ///< Read status r= egister in the flash part. + PCH_SPI_GET_REGION_ADDRESS GetRegionAddress; ///< Get the SPI r= egion base and size + PCH_SPI_READ_PCH_SOFTSTRAP ReadPchSoftStrap; ///< Read PCH Soft= Strap Values + PCH_SPI_READ_CPU_SOFTSTRAP ReadCpuSoftStrap; ///< Read CPU Soft= Strap Values +}; + +/** + PCH SPI PPI/PROTOCOL revision number + + Revision 1: Initial version +**/ +#define PCH_SPI_SERVICES_REVISION 1 + +#endif diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsPmc.h b/S= ilicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsPmc.h new file mode 100644 index 0000000000..4c495475cb --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsPmc.h @@ -0,0 +1,647 @@ +/** @file + Register names for PCH PMC device + + Conventions: + + - Prefixes: + Definitions beginning with "R_" are registers + Definitions beginning with "B_" are bits within registers + Definitions beginning with "V_" are meaningful values within the bits + Definitions beginning with "S_" are register sizes + Definitions beginning with "N_" are the bit position + - In general, PCH registers are denoted by "_PCH_" in register names + - Registers / bits that are different between PCH generations are denote= d by + "_PCH_[generation_name]_" in register/bit names. + - Registers / bits that are specific to PCH-H denoted by "_H_" in regist= er/bit names. + Registers / bits that are specific to PCH-LP denoted by "_LP_" in regi= ster/bit names. + e.g., "_PCH_H_", "_PCH_LP_" + Registers / bits names without _H_ or _LP_ apply for both H and LP. + - Registers / bits that are different between SKUs are denoted by "_[SKU= _name]" + at the end of the register/bit names + - Registers / bits of new devices introduced in a PCH generation will be= just named + as "_PCH_" without [generation_name] inserted. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _PCH_REGS_PMC_H_ +#define _PCH_REGS_PMC_H_ + +// +// PMC Registers (D31:F2) +// +#define PCI_DEVICE_NUMBER_PCH_PMC 31 +#define PCI_FUNCTION_NUMBER_PCH_PMC 2 + +#define R_PCH_PMC_PM_DATA_BAR 0x10 +#define B_PCH_PMC_PM_DATA_BAR 0xFFFFC000 +#define R_PCH_PMC_ACPI_BASE 0x40 +#define B_PCH_PMC_ACPI_BASE_BAR 0xFFFC +#define R_PCH_PMC_ACPI_CNT 0x44 +#define B_PCH_PMC_ACPI_CNT_PWRM_EN BIT8 = ///< PWRM enable +#define B_PCH_PMC_ACPI_CNT_ACPI_EN BIT7 = ///< ACPI eanble +#define B_PCH_PMC_ACPI_CNT_SCIS (BIT2 | BIT1 |= BIT0) ///< SCI IRQ select +#define V_PCH_PMC_ACPI_CNT_SCIS_IRQ9 0 +#define V_PCH_PMC_ACPI_CNT_SCIS_IRQ10 1 +#define V_PCH_PMC_ACPI_CNT_SCIS_IRQ11 2 +#define V_PCH_PMC_ACPI_CNT_SCIS_IRQ20 4 +#define V_PCH_PMC_ACPI_CNT_SCIS_IRQ21 5 +#define V_PCH_PMC_ACPI_CNT_SCIS_IRQ22 6 +#define V_PCH_PMC_ACPI_CNT_SCIS_IRQ23 7 +#define R_PCH_PMC_PWRM_BASE 0x48 +#define B_PCH_PMC_PWRM_BASE_BAR 0xFFFF0000 = ///< PWRM must be 64KB alignment to align the source decode. +#define R_PCH_PMC_GEN_PMCON_A 0xA0 +#define B_PCH_PMC_GEN_PMCON_A_DC_PP_DIS BIT30 +#define B_PCH_PMC_GEN_PMCON_A_DSX_PP_DIS BIT29 +#define B_PCH_PMC_GEN_PMCON_A_AG3_PP_EN BIT28 +#define B_PCH_PMC_GEN_PMCON_A_SX_PP_EN BIT27 +#define B_PCH_PMC_GEN_PMCON_A_DISB BIT23 +#define B_PCH_PMC_GEN_PMCON_A_MEM_SR BIT21 +#define B_PCH_PMC_GEN_PMCON_A_MS4V BIT18 +#define B_PCH_PMC_GEN_PMCON_A_GBL_RST_STS BIT16 +#define B_PCH_PMC_GEN_PMCON_A_ALLOW_OPI_PLL_SD_INC0 BIT13 +#define B_PCH_PMC_GEN_PMCON_A_ALLOW_SPXB_CG_INC0 BIT12 +#define B_PCH_PMC_GEN_PMCON_A_BIOS_PCI_EXP_EN BIT10 +#define B_PCH_PMC_GEN_PMCON_A_PWRBTN_LVL BIT9 +#define B_PCH_PMC_GEN_PMCON_A_ALLOW_L1LOW_C0 BIT7 +#define B_PCH_PMC_GEN_PMCON_A_ALLOW_L1LOW_OPI_ON BIT6 +#define B_PCH_PMC_GEN_PMCON_A_ALLOW_L1LOW_BCLKREQ_ON BIT5 +#define B_PCH_PMC_GEN_PMCON_A_SMI_LOCK BIT4 +#define B_PCH_PMC_GEN_PMCON_A_ESPI_SMI_LOCK BIT3 = ///< ESPI SMI lock +#define B_PCH_PMC_GEN_PMCON_A_PER_SMI_SEL 0x0003 +#define V_PCH_PMC_GEN_PMCON_A_PER_SMI_64S 0x0000 +#define V_PCH_PMC_GEN_PMCON_A_PER_SMI_32S 0x0001 +#define V_PCH_PMC_GEN_PMCON_A_PER_SMI_16S 0x0002 +#define V_PCH_PMC_GEN_PMCON_A_PER_SMI_8S 0x0003 +#define R_PCH_PMC_GEN_PMCON_B 0xA4 +#define B_PCH_PMC_GEN_PMCON_B_SLPSX_STR_POL_LOCK BIT18 = ///< Lock down SLP_S3/SLP_S4 Minimum Assertion width +#define B_PCH_PMC_GEN_PMCON_B_ACPI_BASE_LOCK BIT17 = ///< Lock ACPI BASE at 0x40, only cleared by reset when set +#define B_PCH_PMC_GEN_PMCON_B_PM_DATA_BAR_DIS BIT16 +#define B_PCH_PMC_GEN_PMCON_B_PME_B0_S5_DIS BIT15 +#define B_PCH_PMC_GEN_PMCON_B_SUS_PWR_FLR BIT14 +#define B_PCH_PMC_GEN_PMCON_B_WOL_EN_OVRD BIT13 +#define B_PCH_PMC_GEN_PMCON_B_DISABLE_SX_STRETCH BIT12 +#define B_PCH_PMC_GEN_PMCON_B_SLP_S3_MAW 0xC00 +#define V_PCH_PMC_GEN_PMCON_B_SLP_S3_MAW_60US 0x000 +#define V_PCH_PMC_GEN_PMCON_B_SLP_S3_MAW_1MS 0x400 +#define V_PCH_PMC_GEN_PMCON_B_SLP_S3_MAW_50MS 0x800 +#define V_PCH_PMC_GEN_PMCON_B_SLP_S3_MAW_2S 0xC00 +#define B_PCH_PMC_GEN_PMCON_B_HOST_RST_STS BIT9 +#define B_PCH_PMC_GEN_PMCON_B_SWSMI_RTSL 0xC0 +#define V_PCH_PMC_GEN_PMCON_B_SWSMI_RTSL_64MS 0xC0 +#define V_PCH_PMC_GEN_PMCON_B_SWSMI_RTSL_32MS 0x80 +#define V_PCH_PMC_GEN_PMCON_B_SWSMI_RTSL_16MS 0x40 +#define V_PCH_PMC_GEN_PMCON_B_SWSMI_RTSL_1_5MS 0x00 +#define B_PCH_PMC_GEN_PMCON_B_SLP_S4_MAW 0x30 +#define V_PCH_PMC_GEN_PMCON_B_SLP_S4_MAW_1S 0x30 +#define V_PCH_PMC_GEN_PMCON_B_SLP_S4_MAW_2S 0x20 +#define V_PCH_PMC_GEN_PMCON_B_SLP_S4_MAW_3S 0x10 +#define V_PCH_PMC_GEN_PMCON_B_SLP_S4_MAW_4S 0x00 +#define B_PCH_PMC_GEN_PMCON_B_SLP_S4_ASE BIT3 +#define B_PCH_PMC_GEN_PMCON_B_RTC_PWR_STS BIT2 +#define B_PCH_PMC_GEN_PMCON_B_PWR_FLR BIT1 +#define B_PCH_PMC_GEN_PMCON_B_AFTERG3_EN BIT0 +#define R_PCH_PMC_BM_CX_CNF 0xA8 +#define B_PCH_PMC_BM_CX_CNF_STORAGE_BREAK_EN BIT31 +#define B_PCH_PMC_BM_CX_CNF_PCIE_BREAK_EN BIT30 +#define B_PCH_PMC_BM_CX_CNF_AZ_BREAK_EN BIT24 +#define B_PCH_PMC_BM_CX_CNF_DPSN_BREAK_EN BIT19 +#define B_PCH_PMC_BM_CX_CNF_XHCI_BREAK_EN BIT17 +#define B_PCH_PMC_BM_CX_CNF_SATA3_BREAK_EN BIT16 +#define B_PCH_PMC_BM_CX_CNF_SCRATCHPAD BIT15 +#define B_PCH_PMC_BM_CX_CNF_PHOLD_BM_STS_BLOCK BIT14 +#define B_PCH_PMC_BM_CX_CNF_MASK_CF BIT11 +#define B_PCH_PMC_BM_CX_CNF_BM_STS_ZERO_EN BIT10 +#define B_PCH_PMC_BM_CX_CNF_PM_SYNC_MSG_MODE BIT9 +#define R_PCH_PMC_ETR3 0xAC +#define B_PCH_PMC_ETR3_CF9LOCK BIT31 = ///< CF9h Lockdown +#define B_PCH_PMC_ETR3_USB_CACHE_DIS BIT21 +#define B_PCH_PMC_ETR3_CF9GR BIT20 = ///< CF9h Global Reset +#define B_PCH_PMC_ETR3_SKIP_HOST_RST_HS BIT19 +#define B_PCH_PMC_ETR3_CWORWRE BIT18 + +// +// ACPI and legacy I/O register offsets from ACPIBASE +// +#define R_PCH_ACPI_PM1_STS 0x00 +#define S_PCH_ACPI_PM1_STS 2 +#define B_PCH_ACPI_PM1_STS_WAK BIT15 +#define B_PCH_ACPI_PM1_STS_PCIEXP_WAKE_STS BIT14 +#define B_PCH_ACPI_PM1_STS_PRBTNOR BIT11 +#define B_PCH_ACPI_PM1_STS_RTC BIT10 +#define B_PCH_ACPI_PM1_STS_PWRBTN BIT8 +#define B_PCH_ACPI_PM1_STS_GBL BIT5 +#define B_PCH_ACPI_PM1_STS_BM BIT4 +#define B_PCH_ACPI_PM1_STS_TMROF BIT0 +#define N_PCH_ACPI_PM1_STS_WAK 15 +#define N_PCH_ACPI_PM1_STS_PCIEXP_WAKE_STS 14 +#define N_PCH_ACPI_PM1_STS_PRBTNOR 11 +#define N_PCH_ACPI_PM1_STS_RTC 10 +#define N_PCH_ACPI_PM1_STS_PWRBTN 8 +#define N_PCH_ACPI_PM1_STS_GBL 5 +#define N_PCH_ACPI_PM1_STS_BM 4 +#define N_PCH_ACPI_PM1_STS_TMROF 0 + +#define R_PCH_ACPI_PM1_EN 0x02 +#define S_PCH_ACPI_PM1_EN 2 +#define B_PCH_ACPI_PM1_EN_PCIEXP_WAKE_DIS BIT14 +#define B_PCH_ACPI_PM1_EN_RTC BIT10 +#define B_PCH_ACPI_PM1_EN_PWRBTN BIT8 +#define B_PCH_ACPI_PM1_EN_GBL BIT5 +#define B_PCH_ACPI_PM1_EN_TMROF BIT0 +#define N_PCH_ACPI_PM1_EN_PCIEXP_WAKE_DIS 14 +#define N_PCH_ACPI_PM1_EN_RTC 10 +#define N_PCH_ACPI_PM1_EN_PWRBTN 8 +#define N_PCH_ACPI_PM1_EN_GBL 5 +#define N_PCH_ACPI_PM1_EN_TMROF 0 + +#define R_PCH_ACPI_PM1_CNT 0x04 +#define S_PCH_ACPI_PM1_CNT 4 +#define B_PCH_ACPI_PM1_CNT_SLP_EN BIT13 +#define B_PCH_ACPI_PM1_CNT_SLP_TYP (BIT12 | BIT11 | BIT10) +#define V_PCH_ACPI_PM1_CNT_S0 0 +#define V_PCH_ACPI_PM1_CNT_S1 BIT10 +#define V_PCH_ACPI_PM1_CNT_S3 (BIT12 | BIT10) +#define V_PCH_ACPI_PM1_CNT_S4 (BIT12 | BIT11) +#define V_PCH_ACPI_PM1_CNT_S5 (BIT12 | BIT11 | BIT10) +#define B_PCH_ACPI_PM1_CNT_GBL_RLS BIT2 +#define B_PCH_ACPI_PM1_CNT_BM_RLD BIT1 +#define B_PCH_ACPI_PM1_CNT_SCI_EN BIT0 + +#define R_PCH_ACPI_PM1_TMR 0x08 +#define V_PCH_ACPI_TMR_FREQUENCY 3579545 +#define B_PCH_ACPI_PM1_TMR_VAL 0xFFFFFF +#define V_PCH_ACPI_PM1_TMR_MAX_VAL 0x1000000 ///< The= timer is 24 bit overflow + +#define R_PCH_SMI_EN 0x30 +#define S_PCH_SMI_EN 4 +#define B_PCH_SMI_EN_LEGACY_USB3 BIT31 +#define B_PCH_SMI_EN_GPIO_UNLOCK_SMI BIT27 +#define B_PCH_SMI_EN_LEGACY_USB2 BIT17 +#define B_PCH_SMI_EN_PERIODIC BIT14 +#define B_PCH_SMI_EN_TCO BIT13 +#define B_PCH_SMI_EN_MCSMI BIT11 +#define B_PCH_SMI_EN_BIOS_RLS BIT7 +#define B_PCH_SMI_EN_SWSMI_TMR BIT6 +#define B_PCH_SMI_EN_APMC BIT5 +#define B_PCH_SMI_EN_ON_SLP_EN BIT4 +#define B_PCH_SMI_EN_LEGACY_USB BIT3 +#define B_PCH_SMI_EN_BIOS BIT2 +#define B_PCH_SMI_EN_EOS BIT1 +#define B_PCH_SMI_EN_GBL_SMI BIT0 +#define N_PCH_SMI_EN_LEGACY_USB3 31 +#define N_PCH_SMI_EN_ESPI 28 +#define N_PCH_SMI_EN_GPIO_UNLOCK 27 +#define N_PCH_SMI_EN_INTEL_USB2 18 +#define N_PCH_SMI_EN_LEGACY_USB2 17 +#define N_PCH_SMI_EN_PERIODIC 14 +#define N_PCH_SMI_EN_TCO 13 +#define N_PCH_SMI_EN_MCSMI 11 +#define N_PCH_SMI_EN_BIOS_RLS 7 +#define N_PCH_SMI_EN_SWSMI_TMR 6 +#define N_PCH_SMI_EN_APMC 5 +#define N_PCH_SMI_EN_ON_SLP_EN 4 +#define N_PCH_SMI_EN_LEGACY_USB 3 +#define N_PCH_SMI_EN_BIOS 2 +#define N_PCH_SMI_EN_EOS 1 +#define N_PCH_SMI_EN_GBL_SMI 0 + +#define R_PCH_SMI_STS 0x34 +#define S_PCH_SMI_STS 4 +#define B_PCH_SMI_STS_LEGACY_USB3 BIT31 +#define B_PCH_SMI_STS_GPIO_UNLOCK BIT27 +#define B_PCH_SMI_STS_SPI BIT26 +#define B_PCH_SMI_STS_MONITOR BIT21 +#define B_PCH_SMI_STS_PCI_EXP BIT20 +#define B_PCH_SMI_STS_PATCH BIT19 +#define B_PCH_SMI_STS_INTEL_USB2 BIT18 +#define B_PCH_SMI_STS_LEGACY_USB2 BIT17 +#define B_PCH_SMI_STS_SMBUS BIT16 +#define B_PCH_SMI_STS_SERIRQ BIT15 +#define B_PCH_SMI_STS_PERIODIC BIT14 +#define B_PCH_SMI_STS_TCO BIT13 +#define B_PCH_SMI_STS_DEVMON BIT12 +#define B_PCH_SMI_STS_MCSMI BIT11 +#define B_PCH_SMI_STS_GPIO_SMI BIT10 +#define B_PCH_SMI_STS_GPE0 BIT9 +#define B_PCH_SMI_STS_PM1_STS_REG BIT8 +#define B_PCH_SMI_STS_SWSMI_TMR BIT6 +#define B_PCH_SMI_STS_APM BIT5 +#define B_PCH_SMI_STS_ON_SLP_EN BIT4 +#define B_PCH_SMI_STS_LEGACY_USB BIT3 +#define B_PCH_SMI_STS_BIOS BIT2 +#define N_PCH_SMI_STS_LEGACY_USB3 31 +#define N_PCH_SMI_STS_ESPI 28 +#define N_PCH_SMI_STS_GPIO_UNLOCK 27 +#define N_PCH_SMI_STS_SPI 26 +#define N_PCH_SMI_STS_MONITOR 21 +#define N_PCH_SMI_STS_PCI_EXP 20 +#define N_PCH_SMI_STS_PATCH 19 +#define N_PCH_SMI_STS_INTEL_USB2 18 +#define N_PCH_SMI_STS_LEGACY_USB2 17 +#define N_PCH_SMI_STS_SMBUS 16 +#define N_PCH_SMI_STS_SERIRQ 15 +#define N_PCH_SMI_STS_PERIODIC 14 +#define N_PCH_SMI_STS_TCO 13 +#define N_PCH_SMI_STS_DEVMON 12 +#define N_PCH_SMI_STS_MCSMI 11 +#define N_PCH_SMI_STS_GPIO_SMI 10 +#define N_PCH_SMI_STS_GPE0 9 +#define N_PCH_SMI_STS_PM1_STS_REG 8 +#define N_PCH_SMI_STS_SWSMI_TMR 6 +#define N_PCH_SMI_STS_APM 5 +#define N_PCH_SMI_STS_ON_SLP_EN 4 +#define N_PCH_SMI_STS_LEGACY_USB 3 +#define N_PCH_SMI_STS_BIOS 2 + +#define R_PCH_ACPI_GPE_CNTL 0x40 +#define B_PCH_ACPI_GPE_CNTL_SWGPE_CTRL BIT17 + +#define R_PCH_DEVACT_STS 0x44 +#define S_PCH_DEVACT_STS 2 +#define B_PCH_DEVACT_STS_MASK 0x13E1 +#define B_PCH_DEVACT_STS_KBC BIT12 +#define B_PCH_DEVACT_STS_PIRQDH BIT9 +#define B_PCH_DEVACT_STS_PIRQCG BIT8 +#define B_PCH_DEVACT_STS_PIRQBF BIT7 +#define B_PCH_DEVACT_STS_PIRQAE BIT6 +#define B_PCH_DEVACT_STS_D0_TRP BIT0 +#define N_PCH_DEVACT_STS_KBC 12 +#define N_PCH_DEVACT_STS_PIRQDH 9 +#define N_PCH_DEVACT_STS_PIRQCG 8 +#define N_PCH_DEVACT_STS_PIRQBF 7 +#define N_PCH_DEVACT_STS_PIRQAE 6 + +#define R_PCH_ACPI_PM2_CNT 0x50 +#define B_PCH_ACPI_PM2_CNT_ARB_DIS BIT0 + +#define R_PCH_OC_WDT_CTL 0x54 +#define B_PCH_OC_WDT_CTL_RLD BIT31 +#define B_PCH_OC_WDT_CTL_ICCSURV_STS BIT25 +#define B_PCH_OC_WDT_CTL_NO_ICCSURV_STS BIT24 +#define B_PCH_OC_WDT_CTL_FORCE_ALL BIT15 +#define B_PCH_OC_WDT_CTL_EN BIT14 +#define B_PCH_OC_WDT_CTL_ICCSURV BIT13 +#define B_PCH_OC_WDT_CTL_LCK BIT12 +#define B_PCH_OC_WDT_CTL_TOV_MASK 0x3FF +#define B_PCH_OC_WDT_CTL_FAILURE_STS BIT23 +#define B_PCH_OC_WDT_CTL_UNXP_RESET_STS BIT22 +#define B_PCH_OC_WDT_CTL_AFTER_POST 0x3F0000 +#define V_PCH_OC_WDT_CTL_STATUS_FAILURE 1 +#define V_PCH_OC_WDT_CTL_STATUS_OK 0 + +#define R_PCH_ACPI_GPE0_STS_31_0 0x80 +#define R_PCH_ACPI_GPE0_STS_63_32 0x84 +#define R_PCH_ACPI_GPE0_STS_95_64 0x88 +#define R_PCH_ACPI_GPE0_STS_127_96 0x8C +#define S_PCH_ACPI_GPE0_STS_127_96 4 +#define B_PCH_ACPI_GPE0_STS_127_96_WADT BIT18 +#define B_PCH_ACPI_GPE0_STS_127_96_LAN_WAKE BIT16 +#define B_PCH_ACPI_GPE0_STS_127_96_PME_B0 BIT13 +#define B_PCH_ACPI_GPE0_STS_127_96_ME_SCI BIT12 +#define B_PCH_ACPI_GPE0_STS_127_96_PME BIT11 +#define B_PCH_ACPI_GPE0_STS_127_96_BATLOW BIT10 +#define B_PCH_ACPI_GPE0_STS_127_96_PCI_EXP BIT9 +#define B_PCH_ACPI_GPE0_STS_127_96_RI BIT8 +#define B_PCH_ACPI_GPE0_STS_127_96_SMB_WAK BIT7 +#define B_PCH_ACPI_GPE0_STS_127_96_TC0SCI BIT6 +#define B_PCH_ACPI_GPE0_STS_127_96_SWGPE BIT2 +#define B_PCH_ACPI_GPE0_STS_127_96_HOT_PLUG BIT1 +#define N_PCH_ACPI_GPE0_STS_127_96_PME_B0 13 +#define N_PCH_ACPI_GPE0_STS_127_96_PME 11 +#define N_PCH_ACPI_GPE0_STS_127_96_BATLOW 10 +#define N_PCH_ACPI_GPE0_STS_127_96_PCI_EXP 9 +#define N_PCH_ACPI_GPE0_STS_127_96_RI 8 +#define N_PCH_ACPI_GPE0_STS_127_96_SMB_WAK 7 +#define N_PCH_ACPI_GPE0_STS_127_96_TC0SCI 6 +#define N_PCH_ACPI_GPE0_STS_127_96_SWGPE 2 +#define N_PCH_ACPI_GPE0_STS_127_96_HOT_PLUG 1 + +#define R_PCH_ACPI_GPE0_EN_31_0 0x90 +#define R_PCH_ACPI_GPE0_EN_63_32 0x94 +#define R_PCH_ACPI_GPE0_EN_95_64 0x98 +#define R_PCH_ACPI_GPE0_EN_127_96 0x9C +#define S_PCH_ACPI_GPE0_EN_127_96 4 +#define B_PCH_ACPI_GPE0_EN_127_96_WADT BIT18 +#define B_PCH_ACPI_GPE0_EN_127_96_LAN_WAKE BIT16 +#define B_PCH_ACPI_GPE0_EN_127_96_PME_B0 BIT13 +#define B_PCH_ACPI_GPE0_EN_127_96_ME_SCI BIT12 +#define B_PCH_ACPI_GPE0_EN_127_96_PME BIT11 +#define B_PCH_ACPI_GPE0_EN_127_96_BATLOW BIT10 +#define B_PCH_ACPI_GPE0_EN_127_96_PCI_EXP BIT9 +#define B_PCH_ACPI_GPE0_EN_127_96_RI BIT8 +#define B_PCH_ACPI_GPE0_EN_127_96_TC0SCI BIT6 +#define B_PCH_ACPI_GPE0_EN_127_96_SWGPE BIT2 +#define B_PCH_ACPI_GPE0_EN_127_96_HOT_PLUG BIT1 +#define N_PCH_ACPI_GPE0_EN_127_96_PME_B0 13 +#define N_PCH_ACPI_GPE0_EN_127_96_USB3 12 +#define N_PCH_ACPI_GPE0_EN_127_96_PME 11 +#define N_PCH_ACPI_GPE0_EN_127_96_BATLOW 10 +#define N_PCH_ACPI_GPE0_EN_127_96_PCI_EXP 9 +#define N_PCH_ACPI_GPE0_EN_127_96_RI 8 +#define N_PCH_ACPI_GPE0_EN_127_96_TC0SCI 6 +#define N_PCH_ACPI_GPE0_EN_127_96_SWGPE 2 +#define N_PCH_ACPI_GPE0_EN_127_96_HOT_PLUG 1 + + +// +// TCO register I/O map +// +#define R_PCH_TCO_RLD 0x0 +#define R_PCH_TCO_DAT_IN 0x2 +#define R_PCH_TCO_DAT_OUT 0x3 +#define R_PCH_TCO1_STS 0x04 +#define S_PCH_TCO1_STS 2 +#define B_PCH_TCO1_STS_DMISERR BIT12 +#define B_PCH_TCO1_STS_DMISMI BIT10 +#define B_PCH_TCO1_STS_DMISCI BIT9 +#define B_PCH_TCO1_STS_BIOSWR BIT8 +#define B_PCH_TCO1_STS_NEWCENTURY BIT7 +#define B_PCH_TCO1_STS_TIMEOUT BIT3 +#define B_PCH_TCO1_STS_TCO_INT BIT2 +#define B_PCH_TCO1_STS_SW_TCO_SMI BIT1 +#define B_PCH_TCO1_STS_NMI2SMI BIT0 +#define N_PCH_TCO1_STS_DMISMI 10 +#define N_PCH_TCO1_STS_BIOSWR 8 +#define N_PCH_TCO1_STS_NEWCENTURY 7 +#define N_PCH_TCO1_STS_TIMEOUT 3 +#define N_PCH_TCO1_STS_SW_TCO_SMI 1 +#define N_PCH_TCO1_STS_NMI2SMI 0 + +#define R_PCH_TCO2_STS 0x06 +#define S_PCH_TCO2_STS 2 +#define B_PCH_TCO2_STS_SMLINK_SLV_SMI BIT4 +#define B_PCH_TCO2_STS_BAD_BIOS BIT3 +#define B_PCH_TCO2_STS_BOOT BIT2 +#define B_PCH_TCO2_STS_SECOND_TO BIT1 +#define B_PCH_TCO2_STS_INTRD_DET BIT0 +#define N_PCH_TCO2_STS_INTRD_DET 0 + +#define R_PCH_TCO1_CNT 0x08 +#define S_PCH_TCO1_CNT 2 +#define B_PCH_TCO_CNT_LOCK BIT12 +#define B_PCH_TCO_CNT_TMR_HLT BIT11 +#define B_PCH_TCO_CNT_NMI2SMI_EN BIT9 +#define B_PCH_TCO_CNT_NMI_NOW BIT8 +#define N_PCH_TCO_CNT_NMI2SMI_EN 9 + +#define R_PCH_TCO2_CNT 0x0A +#define S_PCH_TCO2_CNT 2 +#define B_PCH_TCO2_CNT_OS_POLICY 0x0030 +#define B_PCH_TCO2_CNT_GPI11_ALERT_DISABLE 0x0008 +#define B_PCH_TCO2_CNT_INTRD_SEL 0x0006 +#define N_PCH_TCO2_CNT_INTRD_SEL 2 + +#define R_PCH_TCO_MESSAGE1 0x0C +#define R_PCH_TCO_MESSAGE2 0x0D +#define R_PCH_TCO_WDCNT 0x0E +#define R_PCH_TCO_SW_IRQ_GEN 0x10 +#define B_PCH_TCO_IRQ12_CAUSE BIT1 +#define B_PCH_TCO_IRQ1_CAUSE BIT0 +#define R_PCH_TCO_TMR 0x12 + +// +// PWRM Registers +// +#define R_PCH_WADT_AC 0x0 = ///< Wake Alarm Device Timer: AC +#define R_PCH_WADT_DC 0x4 = ///< Wake Alarm Device Timer: DC +#define R_PCH_WADT_EXP_AC 0x8 = ///< Wake Alarm Device Expired Timer: AC +#define R_PCH_WADT_EXP_DC 0xC = ///< Wake Alarm Device Expired Timer: DC +#define R_PCH_PWRM_PRSTS 0x10 = ///< Power and Reset Status +#define B_PCH_PWRM_PRSTS_VE_WD_TMR_STS BIT7 = ///< VE Watchdog Timer Status +#define B_PCH_PWRM_PRSTS_WOL_OVR_WK_STS BIT5 +#define B_PCH_PWRM_PRSTS_FIELD_1 BIT4 +#define B_PCH_PWRM_PRSTS_ME_WAKE_STS BIT0 +#define R_PCH_PWRM_14 0x14 +#define R_PCH_PWRM_CFG 0x18 = ///< Power Management Configuration +#define B_PCH_PWRM_CFG_ALLOW_24_OSC_SD BIT29 = ///< Allow 24MHz Crystal Oscillator Shutdown +#define B_PCH_PWRM_CFG_ALLOW_USB2_CORE_PG BIT25 = ///< Allow USB2 Core Power Gating +#define B_PCH_PWRM_CFG_RTC_DS_WAKE_DIS BIT21 = ///< RTC Wake from Deep S4/S5 Disable +#define B_PCH_PWRM_CFG_SSMAW_MASK (BIT19 | BIT18= ) ///< SLP_SUS# Min Assertion Width +#define V_PCH_PWRM_CFG_SSMAW_4S (BIT19 | BIT18= ) ///< 4 seconds +#define V_PCH_PWRM_CFG_SSMAW_1S BIT19 = ///< 1 second +#define V_PCH_PWRM_CFG_SSMAW_0_5S BIT18 = ///< 0.5 second (500ms) +#define V_PCH_PWRM_CFG_SSMAW_0S 0 = ///< 0 second +#define B_PCH_PWRM_CFG_SAMAW_MASK (BIT17 | BIT16= ) ///< SLP_A# Min Assertion Width +#define V_PCH_PWRM_CFG_SAMAW_2S (BIT17 | BIT16= ) ///< 2 seconds +#define V_PCH_PWRM_CFG_SAMAW_98ms BIT17 = ///< 98ms +#define V_PCH_PWRM_CFG_SAMAW_4S BIT16 = ///< 4 seconds +#define V_PCH_PWRM_CFG_SAMAW_0S 0 = ///< 0 second +#define B_PCH_PWRM_CFG_RPCD_MASK (BIT9 | BIT8) = ///< Reset Power Cycle Duration +#define V_PCH_PWRM_CFG_RPCD_1S (BIT9 | BIT8) = ///< 1-2 seconds +#define V_PCH_PWRM_CFG_RPCD_2S BIT9 = ///< 2-3 seconds +#define V_PCH_PWRM_CFG_RPCD_3S BIT8 = ///< 3-4 seconds +#define V_PCH_PWRM_CFG_RPCD_4S 0 = ///< 4-5 seconds (Default) +#define R_PCH_PWRM_PCH_PM_STS 0x1C = ///< Contains misc. fields used to record PCH power managemen= t events +#define B_PCH_PWRM_PCH_PM_STS_PMC_MSG_FULL_STS BIT24 = ///< MTPMC transport mechanism full indication +#define R_PCH_PWRM_MTPMC 0x20 = ///< Message to PMC +#define V_PCH_PWRM_MTPMC_COMMAND_PG_LANE_0_15 0xE = ///< Command to override lanes 0-15 power gating +#define V_PCH_PWRM_MTPMC_COMMAND_PG_LANE_16_31 0xF = ///< Command to override lanes 16-31 power gating +#define B_PCH_PWRM_MTPMC_PG_CMD_DATA 0xFFFF0000 = ///< Data part of PowerGate Message to PMC +#define N_PCH_PWRM_MTPMC_PG_CMD_DATA 16 +#define R_PCH_PWRM_PCH_PM_STS2 0x24 = ///< PCH Power Management Status +#define R_PCH_PWRM_S3_PWRGATE_POL 0x28 = ///< S3 Power Gating Policies +#define B_PCH_PWRM_S3DC_GATE_SUS BIT1 = ///< Deep S3 Enable in DC Mode +#define B_PCH_PWRM_S3AC_GATE_SUS BIT0 = ///< Deep S3 Enable in AC Mode +#define R_PCH_PWRM_S4_PWRGATE_POL 0x2C = ///< Deep S4 Power Policies +#define B_PCH_PWRM_S4DC_GATE_SUS BIT1 = ///< Deep S4 Enable in DC Mode +#define B_PCH_PWRM_S4AC_GATE_SUS BIT0 = ///< Deep S4 Enable in AC Mode +#define R_PCH_PWRM_S5_PWRGATE_POL 0x30 = ///< Deep S5 Power Policies +#define B_PCH_PWRM_S5DC_GATE_SUS BIT15 = ///< Deep S5 Enable in DC Mode +#define B_PCH_PWRM_S5AC_GATE_SUS BIT14 = ///< Deep S5 Enable in AC Mode +#define R_PCH_PWRM_DSX_CFG 0x34 = ///< Deep SX Configuration +#define B_PCH_PWRM_DSX_CFG_WAKE_PIN_DSX_EN BIT2 = ///< WAKE# Pin DeepSx Enable +#define B_PCH_PWRM_DSX_CFG_ACPRES_PD_DSX_DIS BIT1 = ///< AC_PRESENT pin pulldown in DeepSx disable +#define B_PCH_PWRM_DSX_CFG_LAN_WAKE_EN BIT0 = ///< LAN_WAKE Pin DeepSx Enable +#define R_PCH_PWRM_CFG2 0x3C = ///< Power Management Configuration Reg 2 +#define B_PCH_PWRM_CFG2_PBOP (BIT31 | BIT30= | BIT29) ///< Power Button Override Period (PBOP) +#define N_PCH_PWRM_CFG2_PBOP 29 = ///< Power Button Override Period (PBOP) +#define B_PCH_PWRM_CFG2_PB_DIS BIT28 = ///< Power Button Native Mode Disable (PB_DIS) +#define B_PCH_PWRM_CFG2_DRAM_RESET_CTL BIT26 = ///< DRAM RESET# control +#define R_PCH_PWRM_EN_SN_SLOW_RING 0x48 = ///< Enable Snoop Request to SLOW_RING +#define R_PCH_PWRM_EN_SN_SLOW_RING2 0x4C = ///< Enable Snoop Request to SLOW_RING 2nd Reg +#define R_PCH_PWRM_EN_SN_SA 0x50 = ///< Enable Snoop Request to SA +#define R_PCH_PWRM_EN_SN_SA2 0x54 = ///< Enable Snoop Request to SA 2nd Reg +#define R_PCH_PWRM_EN_SN_SLOW_RING_CF 0x58 = ///< Enable Snoop Request to SLOW_RING_CF +#define R_PCH_PWRM_EN_NS_SA 0x68 = ///< Enable Non-Snoop Request to SA +#define R_PCH_PWRM_EN_CW_SLOW_RING 0x80 = ///< Enable Clock Wake to SLOW_RING +#define R_PCH_PWRM_EN_CW_SLOW_RING2 0x84 = ///< Enable Clock Wake to SLOW_RING 2nd Reg +#define R_PCH_PWRM_EN_CW_SA 0x88 = ///< Enable Clock Wake to SA +#define R_PCH_PWRM_EN_CW_SA2 0x8C = ///< Enable Clock Wake to SA 2nd Reg +#define R_PCH_PWRM_EN_CW_SLOW_RING_CF 0x98 = ///< Enable Clock Wake to SLOW_RING_CF +#define R_PCH_PWRM_EN_PA_SLOW_RING 0xA8 = ///< Enable Pegged Active to SLOW_RING +#define R_PCH_PWRM_EN_PA_SLOW_RING2 0xAC = ///< Enable Pegged Active to SLOW_RING 2nd Reg +#define R_PCH_PWRM_EN_PA_SA 0xB0 = ///< Enable Pegged Active to SA +#define R_PCH_PWRM_EN_PA_SA2 0xB4 = ///< Enable Pegged Active to SA 2nd Reg +#define R_PCH_PWRM_EN_MISC_EVENT 0xC0 = ///< Enable Misc PM_SYNC Events +#define R_PCH_PWRM_PMSYNC_TPR_CONFIG 0xC4 +#define B_PCH_PWRM_PMSYNC_TPR_CONFIG_LOCK BIT31 +#define B_PCH_PWRM_PMSYNC_PCH2CPU_TT_EN BIT26 +#define B_PCH_PWRM_PMSYNC_PCH2CPU_TT_STATE (BIT25 | BIT24) +#define N_PCH_PWRM_PMSYNC_PCH2CPU_TT_STATE 24 +#define V_PCH_PWRM_PMSYNC_PCH2CPU_TT_STATE_1 1 +#define R_PCH_PWRM_PMSYNC_MISC_CFG 0xC8 +#define B_PCH_PWRM_PMSYNC_PM_SYNC_LOCK BIT15 = ///< PM_SYNC Configuration Lock +#define B_PCH_PWRM_PMSYNC_GPIO_D_SEL BIT11 +#define B_PCH_PWRM_PMSYNC_GPIO_C_SEL BIT10 +#define R_PCH_PWRM_PM_SYNC_STATE_HYS 0xD0 = ///< PM_SYNC State Hysteresis +#define R_PCH_PWRM_PM_SYNC_MODE 0xD4 = ///< PM_SYNC Pin Mode +#define R_PCH_PWRM_CFG3 0xE0 = ///< Power Management Configuration Reg 3 +#define B_PCH_PWRM_CFG3_DSX_WLAN_PP_EN BIT16 = ///< Deep-Sx WLAN Phy Power Enable +#define B_PCH_PWRM_CFG3_HOST_WLAN_PP_EN BIT17 = ///< Host Wireless LAN Phy Power Enable +#define B_PCH_PWRM_CFG3_PWRG_LOCK BIT2 = ///< Lock power gating override messages +#define R_PCH_PWRM_PM_DOWN_PPB_CFG 0xE4 = ///< PM_DOWN PCH_POWER_BUDGET CONFIGURATION +#define R_PCH_PWRM_CFG4 0xE8 = ///< Power Management Configuration Reg 4 +#define B_PCH_PWRM_CFG4_U2_PHY_PG_EN BIT30 = ///< USB2 PHY SUS Well Power Gating Enable +#define B_PCH_PWRM_CFG4_CPU_IOVR_RAMP_DUR (0x000001FF) = ///< CPU I/O VR Ramp Duration, [8:0] +#define N_PCH_PWRM_CFG4_CPU_IOVR_RAMP_DUR 0 +#define V_PCH_PWRM_CFG4_CPU_IOVR_RAMP_DUR_70US 0x007 +#define V_PCH_PWRM_CFG4_CPU_IOVR_RAMP_DUR_240US 0x018 +#define R_PCH_PWRM_CPU_EPOC 0xEC +#define R_PCH_PWRM_VR_MISC_CTL 0x100 +#define B_PCH_PWRM_VR_MISC_CTL_VIDSOVEN BIT3 +#define R_PCH_PWRM_GPIO_CFG 0x120 +#define B_PCH_PWRM_GPIO_CFG_GPE0_DW2 (BIT11 | BIT10= | BIT9 | BIT8) +#define N_PCH_PWRM_GPIO_CFG_GPE0_DW2 8 +#define B_PCH_PWRM_GPIO_CFG_GPE0_DW1 (BIT7 | BIT6 |= BIT5 | BIT4) +#define N_PCH_PWRM_GPIO_CFG_GPE0_DW1 4 +#define B_PCH_PWRM_GPIO_CFG_GPE0_DW0 (BIT3 | BIT2 |= BIT1 | BIT0) +#define N_PCH_PWRM_GPIO_CFG_GPE0_DW0 0 +#define R_PCH_PWRM_PM_SYNC_MODE_C0 0xF4 = ///< PM_SYNC Pin Mode in C0 +#define R_PCH_PWRM_ACPI_TMR_CTL 0xFC +#define B_PCH_PWRM_ACPI_TMR_DIS BIT1 +#define R_PCH_PWRM_124 0x124 +#define R_PCH_PWRM_SLP_S0_RESIDENCY_COUNTER 0x13C +#define R_PCH_PWRM_MODPHY_PM_CFG1 0x200 +#define R_PCH_PWRM_MODPHY_PM_CFG1_MLSXSWPGP 0xFFFF +#define R_PCH_PWRM_MODPHY_PM_CFG2 0x204 ///< = ModPHY Power Management Configuration Reg 2 +#define B_PCH_PWRM_MODPHY_PM_CFG2_MLSPDDGE BIT30 ///< = ModPHY Lane SUS Power Domain Dynamic Gating Enable +#define B_PCH_PWRM_MODPHY_PM_CFG2_EMFC BIT29 ///< = Enable ModPHY FET Control +#define B_PCH_PWRM_MODPHY_PM_CFG2_EFRT (BIT28 | BIT27= | BIT26 | BIT25 | BIT24) ///< External FET Ramp Time +#define N_PCH_PWRM_MODPHY_PM_CFG2_EFRT 24 +#define V_PCH_PWRM_MODPHY_PM_CFG2_EFRT_200US 0x0A +#define B_PCH_PWRM_MODPHY_PM_CFG2_ASLOR_UFS BIT16 ///< = UFS ModPHY SPD SPD Override +#define R_PCH_PWRM_MODPHY_PM_CFG3 0x208 ///< = ModPHY Power Management Configuration Reg 3 +#define B_PCH_PWRM_MODPHY_PM_CFG3_MSPDRTREQ_UFS BIT16 ///< = UFS ModPHY SPD RT Request +#define B_PCH_PWRM_MODPHY_PM_CFG3_MSPDRTREQ_XDCI BIT15 ///< = xDCI ModPHY SPD RT Request +#define B_PCH_PWRM_MODPHY_PM_CFG3_MSPDRTREQ_XHCI BIT14 ///< = xHCI ModPHY SPD RT Request +#define B_PCH_PWRM_MODPHY_PM_CFG3_MSPDRTREQ_GBE BIT13 ///< = GbE ModPHY SPD RT Request +#define B_PCH_PWRM_MODPHY_PM_CFG3_MSPDRTREQ_SATA BIT12 ///< = SATA ModPHY SPD RT Request +#define R_PCH_PWRM_30C 0x30C +#define R_PCH_PWRM_OBFF_CFG 0x314 = ///< OBFF Configuration +#define R_PCH_PWRM_31C 0x31C +#define R_PCH_PWRM_CPPM_MISC_CFG 0x320 = ///< CPPM Miscellaneous Configuration +#define R_PCH_PWRM_CPPM_CG_POL1A 0x324 = ///< CPPM Clock Gating Policy Reg 1 +#define R_PCH_PWRM_CPPM_CG_POL2A 0x340 = ///< CPPM Clock Gating Policy Reg 3 +#define R_PCH_PWRM_34C 0x34C +#define R_PCH_PWRM_CPPM_CG_POL3A 0x3A8 = ///< CPPM Clock Gating Policy Reg 5 +#define B_PCH_PWRM_CPPM_CG_POLXA_CPPM_GX_QUAL BIT30 = ///< CPPM Shutdown Qualifier Enable for Clock Source Group X +#define B_PCH_PWRM_CPPM_CG_POLXA_LTR_GX_THRESH (0x000001FF) = ///< LTR Threshold for Clock Source Group X, [8:0] +#define R_PCH_PWRM_3D0 0x3D0 +#define R_PCH_PWRM_CPPM_MPG_POL1A 0x3E0 = ///< CPPM ModPHY Gating Policy Reg 1A +#define B_PCH_PWRM_CPPM_MPG_POL1A_CPPM_MODPHY_QUAL BIT30 = ///< CPPM Shutdown Qualifier Enable for ModPHY +#define B_PCH_PWRM_CPPM_MPG_POL1A_LT_MODPHY_SEL BIT29 = ///< ASLT/PLT Selection for ModPHY +#define B_PCH_PWRM_CPPM_MPG_POL1A_LTR_MODPHY_THRESH (0x000001FF) = ///< LTR Threshold for ModPHY, [8:0] +#define R_PCH_PWRM_CS_SD_CTL1 0x3E8 = ///< Clock Source Shutdown Control Reg 1 +#define B_PCH_PWRM_CS_SD_CTL1_CS5_CTL_CFG (BIT22 | BIT21= | BIT20) ///< Clock Source 5 Control Configuration +#define N_PCH_PWRM_CS_SD_CTL1_CS5_CTL_CFG 20 +#define B_PCH_PWRM_CS_SD_CTL1_CS1_CTL_CFG (BIT2 | BIT1 |= BIT0) ///< Clock Source 1 Control Configuration +#define N_PCH_PWRM_CS_SD_CTL1_CS1_CTL_CFG 0 +#define R_PCH_PWRM_CS_SD_CTL2 0x3EC = ///< Clock Source Shutdown Control Reg 2 +#define R_PCH_PWRM_HSWPGCR1 0x5D0 +#define B_PCH_PWRM_SW_PG_CTRL_LOCK BIT31 +#define B_PCH_PWRM_DFX_SW_PG_CTRL BIT0 +#define R_PCH_PWRM_600 0x600 +#define R_PCH_PWRM_604 0x604 +#define R_PCH_PWRM_ST_PG_FDIS_PMC_1 0x620 ///< Sta= tic PG Related Function Disable Register 1 +#define B_PCH_PWRM_ST_PG_FDIS_PMC_1_ST_FDIS_LK BIT31 ///< Sta= tic Function Disable Lock (ST_FDIS_LK) +#define B_PCH_PWRM_ST_PG_FDIS_PMC_1_CAM_FDIS_PMC BIT6 ///< Cam= era Function Disable (PMC Version) (CAM_FDIS_PMC) +#define B_PCH_PWRM_ST_PG_FDIS_PMC_1_ISH_FDIS_PMC BIT5 ///< SH = Function Disable (PMC Version) (ISH_FDIS_PMC) +#define B_PCH_PWRM_ST_PG_FDIS_PMC_1_GBE_FDIS_PMC BIT0 ///< GBE= Function Disable (PMC Version) (GBE_FDIS_PMC) +#define R_PCH_PWRM_ST_PG_FDIS_PMC_2 0x624 ///< Sta= tic Function Disable Control Register 2 +#define V_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_FDIS_PMC 0x7FF ///< Sta= tic Function Disable Control Register 2 +#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_GSPI1_FDIS_PMC BIT10 ///< Ser= ialIo Controller GSPI Device 1 Function Disable +#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_GSPI0_FDIS_PMC BIT9 ///< Ser= ialIo Controller GSPI Device 0 Function Disable +#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_UART2_FDIS_PMC BIT8 ///< Ser= ialIo Controller UART Device 2 Function Disable +#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_UART1_FDIS_PMC BIT7 ///< Ser= ialIo Controller UART Device 1 Function Disable +#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_UART0_FDIS_PMC BIT6 ///< Ser= ialIo Controller UART Device 0 Function Disable +#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C5_FDIS_PMC BIT5 ///< Ser= ialIo Controller I2C Device 5 Function Disable +#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C4_FDIS_PMC BIT4 ///< Ser= ialIo Controller I2C Device 4 Function Disable +#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C3_FDIS_PMC BIT3 ///< Ser= ialIo Controller I2C Device 3 Function Disable +#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C2_FDIS_PMC BIT2 ///< Ser= ialIo Controller I2C Device 2 Function Disable +#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C1_FDIS_PMC BIT1 ///< Ser= ialIo Controller I2C Device 1 Function Disable +#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C0_FDIS_PMC BIT0 ///< Ser= ialIo Controller I2C Device 0 Function Disable +#define R_PCH_PWRM_NST_PG_FDIS_1 0x628 +#define B_PCH_PWRM_NST_PG_FDIS_1_SCC_FDIS_PMC BIT25 ///< SCC= Function Disable. This is only avaiable in B0 onward. +#define B_PCH_PWRM_NST_PG_FDIS_1_XDCI_FDIS_PMC BIT24 ///< XDC= I Function Disable. This is only avaiable in B0 onward. +#define B_PCH_PWRM_NST_PG_FDIS_1_ADSP_FDIS_PMC BIT23 ///< ADS= P Function Disable +#define B_PCH_PWRM_NST_PG_FDIS_1_SATA_FDIS_PMC BIT22 ///< SAT= A Function Disable +#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_C3_FDIS_PMC BIT13 ///< PCI= e Controller C Port 3 Function Disable +#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_C2_FDIS_PMC BIT12 ///< PCI= e Controller C Port 2 Function Disable +#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_C1_FDIS_PMC BIT11 ///< PCI= e Controller C Port 1 Function Disable +#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_C0_FDIS_PMC BIT10 ///< PCI= e Controller C Port 0 Function Disable +#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_B3_FDIS_PMC BIT9 ///< PCI= e Controller B Port 3 Function Disable +#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_B2_FDIS_PMC BIT8 ///< PCI= e Controller B Port 2 Function Disable +#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_B1_FDIS_PMC BIT7 ///< PCI= e Controller B Port 1 Function Disable +#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_B0_FDIS_PMC BIT6 ///< PCI= e Controller B Port 0 Function Disable +#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_A3_FDIS_PMC BIT5 ///< PCI= e Controller A Port 3 Function Disable +#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_A2_FDIS_PMC BIT4 ///< PCI= e Controller A Port 2 Function Disable +#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_A1_FDIS_PMC BIT3 ///< PCI= e Controller A Port 1 Function Disable +#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_A0_FDIS_PMC BIT2 ///< PCI= e Controller A Port 0 Function Disable +#define B_PCH_PWRM_NST_PG_FDIS_1_XHCI_FDIS_PMC BIT0 ///< XHC= I Function Disable +#define R_PCH_PWRM_FUSE_DIS_RD_1 0x640 ///< Fus= e Disable Read 1 Register +#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_E3_FUSE_DIS BIT21 ///< PCI= e Controller E Port 3 Fuse Disable +#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_E2_FUSE_DIS BIT20 ///< PCI= e Controller E Port 2 Fuse Disable +#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_E1_FUSE_DIS BIT19 ///< PCI= e Controller E Port 1 Fuse Disable +#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_E0_FUSE_DIS BIT18 ///< PCI= e Controller E Port 0 Fuse Disable +#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_D3_FUSE_DIS BIT17 ///< PCI= e Controller D Port 3 Fuse Disable +#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_D2_FUSE_DIS BIT16 ///< PCI= e Controller D Port 2 Fuse Disable +#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_D1_FUSE_DIS BIT15 ///< PCI= e Controller D Port 1 Fuse Disable +#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_D0_FUSE_DIS BIT14 ///< PCI= e Controller D Port 0 Fuse Disable +#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_C3_FUSE_DIS BIT13 ///< PCI= e Controller C Port 3 Fuse Disable +#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_C2_FUSE_DIS BIT12 ///< PCI= e Controller C Port 2 Fuse Disable +#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_C1_FUSE_DIS BIT11 ///< PCI= e Controller C Port 1 Fuse Disable +#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_C0_FUSE_DIS BIT10 ///< PCI= e Controller C Port 0 Fuse Disable +#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_B3_FUSE_DIS BIT9 ///< PCI= e Controller B Port 3 Fuse Disable +#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_B2_FUSE_DIS BIT8 ///< PCI= e Controller B Port 2 Fuse Disable +#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_B1_FUSE_DIS BIT7 ///< PCI= e Controller B Port 1 Fuse Disable +#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_B0_FUSE_DIS BIT6 ///< PCI= e Controller B Port 0 Fuse Disable +#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_A3_FUSE_DIS BIT5 ///< PCI= e Controller A Port 3 Fuse Disable +#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_A2_FUSE_DIS BIT4 ///< PCI= e Controller A Port 2 Fuse Disable +#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_A1_FUSE_DIS BIT3 ///< PCI= e Controller A Port 1 Fuse Disable +#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_A0_FUSE_DIS BIT2 ///< PCI= e Controller A Port 0 Fuse Disable +#define B_PCH_PWRM_FUSE_DIS_RD_1_XHCI_FUSE_DIS BIT0 ///< XHC= I Fuse Disable +#define R_PCH_PWRM_FUSE_DIS_RD_2 0x644 ///< Fus= e Disable Read 2 Register +#define B_PCH_PWRM_FUSE_DIS_RD_2_SPC_SS_DIS BIT25 ///< SPC= Fuse Disable +#define B_PCH_PWRM_FUSE_DIS_RD_2_SPB_SS_DIS BIT24 ///< SPB= Fuse Disable +#define B_PCH_PWRM_FUSE_DIS_RD_2_SPA_SS_DIS BIT23 ///< SPA= Fuse Disable +#define B_PCH_PWRM_FUSE_DIS_RD_2_PSTH_FUSE_SS_DIS BIT21 ///< PST= H Fuse or Soft Strap Disable +#define B_PCH_PWRM_FUSE_DIS_RD_2_DMI_FUSE_SS_DIS BIT20 ///< DMI= Fuse or Soft Strap Disable +#define B_PCH_PWRM_FUSE_DIS_RD_2_OTG_FUSE_SS_DIS BIT19 ///< OTG= Fuse or Soft Strap Disable +#define B_PCH_PWRM_FUSE_DIS_RD_2_XHCI_SS_DIS BIT18 ///< XHC= I Soft Strap Disable +#define B_PCH_PWRM_FUSE_DIS_RD_2_FIA_FUSE_SS_DIS BIT17 ///< FIA= Fuse or Soft Strap Disable +#define B_PCH_PWRM_FUSE_DIS_RD_2_DSP_FUSE_SS_DIS BIT16 ///< DSP= Fuse or Soft Strap Disable +#define B_PCH_PWRM_FUSE_DIS_RD_2_SATA_FUSE_SS_DIS BIT15 ///< SAT= A Fuse or Soft Strap Disable +#define B_PCH_PWRM_FUSE_DIS_RD_2_ICC_FUSE_SS_DIS BIT14 ///< ICC= Fuse or Soft Strap Disable +#define B_PCH_PWRM_FUSE_DIS_RD_2_LPC_FUSE_SS_DIS BIT13 ///< LPC= Fuse or Soft Strap Disable +#define B_PCH_PWRM_FUSE_DIS_RD_2_RTC_FUSE_SS_DIS BIT12 ///< RTC= Fuse or Soft Strap Disable +#define B_PCH_PWRM_FUSE_DIS_RD_2_P2S_FUSE_SS_DIS BIT11 ///< P2S= Fuse or Soft Strap Disable +#define B_PCH_PWRM_FUSE_DIS_RD_2_TRSB_FUSE_SS_DIS BIT10 ///< TRS= B Fuse or Soft Strap Disable +#define B_PCH_PWRM_FUSE_DIS_RD_2_SMB_FUSE_SS_DIS BIT9 ///< SMB= Fuse or Soft Strap Disable +#define B_PCH_PWRM_FUSE_DIS_RD_2_ITSS_FUSE_SS_DIS BIT8 ///< ITS= S Fuse or Soft Strap Disable +#define B_PCH_PWRM_FUSE_DIS_RD_2_SERIALIO_FUSE_SS_DIS BIT6 ///< Ser= ialIo Fuse or Soft Strap Disable +#define B_PCH_PWRM_FUSE_DIS_RD_2_SCC_FUSE_SS_DIS BIT4 ///< SCC= Fuse or Soft Strap Disable +#define B_PCH_PWRM_FUSE_DIS_RD_2_P2D_FUSE_SS_DIS BIT3 ///< P2D= Fuse or Soft Strap Disable +#define B_PCH_PWRM_FUSE_DIS_RD_2_CAM_FUSE_SS_DIS BIT2 ///< Cam= era Fuse or Soft Strap Disable +#define B_PCH_PWRM_FUSE_DIS_RD_2_ISH_FUSE_SS_DIS BIT1 ///< ISH= Fuse or Soft Strap Disable +#define B_PCH_PWRM_FUSE_DIS_RD_2_GBE_FUSE_SS_DIS BIT0 ///< GBE= Fuse or Soft Strap Disable +#define R_PCH_PWRM_FUSE_DIS_RD_3 0x648 ///< Sta= tic PG Fuse and Soft Strap Disable Read Register 3 +#define B_PCH_PWRM_FUSE_DIS_RD_3_PNCRA3_FUSE_SS_DIS BIT3 ///< PNC= RA3 Fuse or Soft Strap Disable +#define B_PCH_PWRM_FUSE_DIS_RD_3_PNCRA2_FUSE_SS_DIS BIT2 ///< PNC= RA2 Fuse or Soft Strap Disable +#define B_PCH_PWRM_FUSE_DIS_RD_3_PNCRA1_FUSE_SS_DIS BIT1 ///< PNC= RA1 Fuse or Soft Strap Disable +#define B_PCH_PWRM_FUSE_DIS_RD_3_PNCRA_FUSE_SS_DIS BIT0 ///< PNC= RA Fuse or Soft Strap Disable + + +#endif diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsSpi.h b/S= ilicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsSpi.h new file mode 100644 index 0000000000..56831b6afe --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsSpi.h @@ -0,0 +1,304 @@ +/** @file + Register names for PCH SPI device. + + Conventions: + + - Prefixes: + Definitions beginning with "R_" are registers + Definitions beginning with "B_" are bits within registers + Definitions beginning with "V_" are meaningful values within the bits + Definitions beginning with "S_" are register sizes + Definitions beginning with "N_" are the bit position + - In general, PCH registers are denoted by "_PCH_" in register names + - Registers / bits that are different between PCH generations are denote= d by + "_PCH_[generation_name]_" in register/bit names. + - Registers / bits that are specific to PCH-H denoted by "_H_" in regist= er/bit names. + Registers / bits that are specific to PCH-LP denoted by "_LP_" in regi= ster/bit names. + e.g., "_PCH_H_", "_PCH_LP_" + Registers / bits names without _H_ or _LP_ apply for both H and LP. + - Registers / bits that are different between SKUs are denoted by "_[SKU= _name]" + at the end of the register/bit names + - Registers / bits of new devices introduced in a PCH generation will be= just named + as "_PCH_" without [generation_name] inserted. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _PCH_REGS_SPI_H_ +#define _PCH_REGS_SPI_H_ + +// +// SPI Registers (D31:F5) +// + +#define PCI_DEVICE_NUMBER_PCH_SPI 31 +#define PCI_FUNCTION_NUMBER_PCH_SPI 5 + +#define R_PCH_SPI_BAR0 0x10 +#define B_PCH_SPI_BAR0_MASK 0x0FFF + +#define R_PCH_SPI_BDE 0xD8 +#define B_PCH_SPI_BDE_F8 0x8000 +#define B_PCH_SPI_BDE_F0 0x4000 +#define B_PCH_SPI_BDE_E8 0x2000 +#define B_PCH_SPI_BDE_E0 0x1000 +#define B_PCH_SPI_BDE_D8 0x0800 +#define B_PCH_SPI_BDE_D0 0x0400 +#define B_PCH_SPI_BDE_C8 0x0200 +#define B_PCH_SPI_BDE_C0 0x0100 +#define B_PCH_SPI_BDE_LEG_F 0x0080 +#define B_PCH_SPI_BDE_LEG_E 0x0040 +#define B_PCH_SPI_BDE_70 0x0008 +#define B_PCH_SPI_BDE_60 0x0004 +#define B_PCH_SPI_BDE_50 0x0002 +#define B_PCH_SPI_BDE_40 0x0001 + +#define R_PCH_SPI_BC 0xDC +#define S_PCH_SPI_BC 4 +#define N_PCH_SPI_BC_ASE_BWP 11 +#define B_PCH_SPI_BC_ASE_BWP BIT11 +#define N_PCH_SPI_BC_ASYNC_SS 10 +#define B_PCH_SPI_BC_ASYNC_SS BIT10 +#define B_PCH_SPI_BC_OSFH BIT9 ///< OS Functi= on Hide +#define N_PCH_SPI_BC_SYNC_SS 8 +#define B_PCH_SPI_BC_SYNC_SS BIT8 +#define B_PCH_SPI_BC_BILD BIT7 +#define B_PCH_SPI_BC_BBS BIT6 ///< Boot BIOS= strap +#define N_PCH_SPI_BC_BBS 6 +#define V_PCH_SPI_BC_BBS_SPI 0 ///< Boot BIOS= strapped to SPI +#define V_PCH_SPI_BC_BBS_LPC 1 ///< Boot BIOS= strapped to LPC +#define B_PCH_SPI_BC_EISS BIT5 ///< Enable In= SMM.STS +#define B_PCH_SPI_BC_TSS BIT4 +#define B_PCH_SPI_BC_SRC (BIT3 | BIT2) +#define N_PCH_SPI_BC_SRC 2 +#define V_PCH_SPI_BC_SRC_PREF_EN_CACHE_EN 0x02 ///< Prefetchi= ng and Caching enabled +#define V_PCH_SPI_BC_SRC_PREF_DIS_CACHE_DIS 0x01 ///< No prefet= ching and no caching +#define V_PCH_SPI_BC_SRC_PREF_DIS_CACHE_EN 0x00 ///< No prefet= ching, but caching enabled +#define B_PCH_SPI_BC_LE BIT1 ///< Lock Enab= le +#define N_PCH_SPI_BC_BLE 1 +#define B_PCH_SPI_BC_WPD BIT0 ///< Write Pro= tect Disable + +// +// BIOS Flash Program Registers (based on SPI_BAR0) +// +#define R_PCH_SPI_BFPR 0x00 = ///< BIOS Flash Primary Region Register(32bits), which is RO and contains t= he same value from FREG1 +#define B_PCH_SPI_BFPR_PRL 0x7FFF0000 = ///< BIOS Flash Primary Region Limit mask +#define N_PCH_SPI_BFPR_PRL 16 = ///< BIOS Flash Primary Region Limit bit position +#define B_PCH_SPI_BFPR_PRB 0x00007FFF = ///< BIOS Flash Primary Region Base mask +#define N_PCH_SPI_BFPR_PRB 0 = ///< BIOS Flash Primary Region Base bit position +#define R_PCH_SPI_HSFSC 0x04 = ///< Hardware Sequencing Flash Status and Control Register(32bits) +#define B_PCH_SPI_HSFSC_FSMIE BIT31 = ///< Flash SPI SMI# Enable +#define B_PCH_SPI_HSFSC_FDBC_MASK 0x3F000000 = ///< Flash Data Byte Count ( <=3D 64), Count =3D (Value in this field) + 1. +#define N_PCH_SPI_HSFSC_FDBC 24 +#define B_PCH_SPI_HSFSC_CYCLE_MASK 0x001E0000 = ///< Flash Cycle. +#define N_PCH_SPI_HSFSC_CYCLE 17 +#define V_PCH_SPI_HSFSC_CYCLE_READ 0 = ///< Flash Cycle Read +#define V_PCH_SPI_HSFSC_CYCLE_WRITE 2 = ///< Flash Cycle Write +#define V_PCH_SPI_HSFSC_CYCLE_4K_ERASE 3 = ///< Flash Cycle 4K Block Erase +#define V_PCH_SPI_HSFSC_CYCLE_64K_ERASE 4 = ///< Flash Cycle 64K Sector Erase +#define V_PCH_SPI_HSFSC_CYCLE_READ_SFDP 5 = ///< Flash Cycle Read SFDP +#define V_PCH_SPI_HSFSC_CYCLE_READ_JEDEC_ID 6 = ///< Flash Cycle Read JEDEC ID +#define V_PCH_SPI_HSFSC_CYCLE_WRITE_STATUS 7 = ///< Flash Cycle Write Status +#define V_PCH_SPI_HSFSC_CYCLE_READ_STATUS 8 = ///< Flash Cycle Read Status +#define B_PCH_SPI_HSFSC_CYCLE_FGO BIT16 = ///< Flash Cycle Go. +#define B_PCH_SPI_HSFSC_FLOCKDN BIT15 = ///< Flash Configuration Lock-Down +#define B_PCH_SPI_HSFSC_FDV BIT14 = ///< Flash Descriptor Valid, once valid software can use hareware sequencin= g regs +#define B_PCH_SPI_HSFSC_FDOPSS BIT13 = ///< Flash Descriptor Override Pin-Strap Status +#define B_PCH_SPI_HSFSC_PRR34_LOCKDN BIT12 = ///< PRR3 PRR4 Lock-Down +#define B_PCH_SPI_HSFSC_SAF_CE BIT8 = ///< SAF ctype error +#define B_PCH_SPI_HSFSC_SAF_MODE_ACTIVE BIT7 = ///< Indicates flash is attached either directly to the PCH via the SPI bus= or EC/BMC +#define B_PCH_SPI_HSFSC_SAF_LE BIT6 = ///< SAF link error +#define B_PCH_SPI_HSFSC_SCIP BIT5 = ///< SPI cycle in progress +#define B_PCH_SPI_HSFSC_SAF_DLE BIT4 = ///< SAF Data length error +#define B_PCH_SPI_HSFSC_SAF_ERROR BIT3 = ///< SAF Error +#define B_PCH_SPI_HSFSC_AEL BIT2 = ///< Access Error Log +#define B_PCH_SPI_HSFSC_FCERR BIT1 = ///< Flash Cycle Error +#define B_PCH_SPI_HSFSC_FDONE BIT0 = ///< Flash Cycle Done +#define R_PCH_SPI_FADDR 0x08 = ///< SPI Flash Address +#define B_PCH_SPI_FADDR_MASK 0x01FFFFFF = ///< SPI Flash Address Mask (0~24bit) +#define R_PCH_SPI_DLOCK 0x0C = ///< Discrete Lock Bits +#define B_PCH_SPI_DLOCK_PR0LOCKDN BIT8 = ///< PR0LOCKDN +#define R_PCH_SPI_FDATA00 0x10 = ///< SPI Data 00 (32 bits) +#define R_PCH_SPI_FDATA01 0x14 = ///< SPI Data 01 +#define R_PCH_SPI_FDATA02 0x18 = ///< SPI Data 02 +#define R_PCH_SPI_FDATA03 0x1C = ///< SPI Data 03 +#define R_PCH_SPI_FDATA04 0x20 = ///< SPI Data 04 +#define R_PCH_SPI_FDATA05 0x24 = ///< SPI Data 05 +#define R_PCH_SPI_FDATA06 0x28 = ///< SPI Data 06 +#define R_PCH_SPI_FDATA07 0x2C = ///< SPI Data 07 +#define R_PCH_SPI_FDATA08 0x30 = ///< SPI Data 08 +#define R_PCH_SPI_FDATA09 0x34 = ///< SPI Data 09 +#define R_PCH_SPI_FDATA10 0x38 = ///< SPI Data 10 +#define R_PCH_SPI_FDATA11 0x3C = ///< SPI Data 11 +#define R_PCH_SPI_FDATA12 0x40 = ///< SPI Data 12 +#define R_PCH_SPI_FDATA13 0x44 = ///< SPI Data 13 +#define R_PCH_SPI_FDATA14 0x48 = ///< SPI Data 14 +#define R_PCH_SPI_FDATA15 0x4C = ///< SPI Data 15 +#define R_PCH_SPI_FRAP 0x50 = ///< Flash Region Access Permisions Register +#define B_PCH_SPI_FRAP_BRWA_MASK 0x0000FF00 = ///< BIOS Region Write Access MASK, Region0~7 - 0: Flash Descriptor; 1: BIO= S; 2: ME; 3: GbE; 4: PlatformData +#define N_PCH_SPI_FRAP_BRWA 8 = ///< BIOS Region Write Access bit position +#define B_PCH_SPI_FRAP_BRRA_MASK 0x000000FF = ///< BIOS Region Read Access MASK, Region0~7 - 0: Flash Descriptor; 1: BIOS= ; 2: ME; 3: GbE; 4: PlatformData +#define B_PCH_SPI_FRAP_BMRAG_MASK 0x00FF0000 = ///< BIOS Master Read Access Grant +#define B_PCH_SPI_FRAP_BMWAG_MASK 0xFF000000 = ///< BIOS Master Write Access Grant +#define R_PCH_SPI_FREG0_FLASHD 0x54 = ///< Flash Region 0(Flash Descriptor)(32bits) +#define R_PCH_SPI_FREG1_BIOS 0x58 = ///< Flash Region 1(BIOS)(32bits) +#define R_PCH_SPI_FREG2_ME 0x5C = ///< Flash Region 2(ME)(32bits) +#define R_PCH_SPI_FREG3_GBE 0x60 = ///< Flash Region 3(GbE)(32bits) +#define R_PCH_SPI_FREG4_PLATFORM_DATA 0x64 = ///< Flash Region 4(Platform Data)(32bits) +#define R_PCH_SPI_FREG5_DER 0x68 = ///< Flash Region 5(Device Expansion Region)(32bits) +#define S_PCH_SPI_FREGX 4 = ///< Size of Flash Region register +#define B_PCH_SPI_FREGX_LIMIT_MASK 0x7FFF0000 = ///< Flash Region Limit [30:16] represents [26:12], [11:0] are assumed to b= e FFFh +#define N_PCH_SPI_FREGX_LIMIT 16 = ///< Region limit bit position +#define N_PCH_SPI_FREGX_LIMIT_REPR 12 = ///< Region limit bit represents position +#define B_PCH_SPI_FREGX_BASE_MASK 0x00007FFF = ///< Flash Region Base, [14:0] represents [26:12] +#define N_PCH_SPI_FREGX_BASE 0 = ///< Region base bit position +#define N_PCH_SPI_FREGX_BASE_REPR 12 = ///< Region base bit represents position +#define R_PCH_SPI_PR0 0x84 = ///< Protected Region 0 Register +#define R_PCH_SPI_PR1 0x88 = ///< Protected Region 1 Register +#define R_PCH_SPI_PR2 0x8C = ///< Protected Region 2 Register +#define R_PCH_SPI_PR3 0x90 = ///< Protected Region 3 Register +#define R_PCH_SPI_PR4 0x94 = ///< Protected Region 4 Register +#define S_PCH_SPI_PRX 4 = ///< Protected Region X Register size +#define B_PCH_SPI_PRX_WPE BIT31 = ///< Write Protection Enable +#define B_PCH_SPI_PRX_PRL_MASK 0x7FFF0000 = ///< Protected Range Limit Mask, [30:16] here represents upper limit of add= ress [26:12] +#define N_PCH_SPI_PRX_PRL 16 = ///< Protected Range Limit bit position +#define B_PCH_SPI_PRX_RPE BIT15 = ///< Read Protection Enable +#define B_PCH_SPI_PRX_PRB_MASK 0x00007FFF = ///< Protected Range Base Mask, [14:0] here represents base limit of addres= s [26:12] +#define N_PCH_SPI_PRX_PRB 0 = ///< Protected Range Base bit position +#define R_PCH_SPI_SFRAP 0xB0 = ///< Secondary Flash Regions Access Permisions Register +#define R_PCH_SPI_FDOC 0xB4 = ///< Flash Descriptor Observability Control Register(32 bits) +#define B_PCH_SPI_FDOC_FDSS_MASK (BIT14 | BIT13 | BIT12) = ///< Flash Descritor Section Select +#define V_PCH_SPI_FDOC_FDSS_FSDM 0x0000 = ///< Flash Signature and Descriptor Map +#define V_PCH_SPI_FDOC_FDSS_COMP 0x1000 = ///< Component +#define V_PCH_SPI_FDOC_FDSS_REGN 0x2000 = ///< Region +#define V_PCH_SPI_FDOC_FDSS_MSTR 0x3000 = ///< Master +#define V_PCH_SPI_FDOC_FDSS_PCHS 0x4000 = ///< PCH soft straps +#define V_PCH_SPI_FDOC_FDSS_SFDP 0x5000 = ///< SFDP Parameter Table +#define B_PCH_SPI_FDOC_FDSI_MASK 0x0FFC = ///< Flash Descriptor Section Index +#define R_PCH_SPI_FDOD 0xB8 = ///< Flash Descriptor Observability Data Register(32 bits) +#define R_PCH_SPI_SFDP0_VSCC0 0xC4 = ///< Vendor Specific Component Capabilities Register(32 bits) +#define B_PCH_SPI_SFDPX_VSCCX_CPPTV BIT31 = ///< Component Property Parameter Table Valid +#define B_PCH_SPI_SFDP0_VSCC0_VCL BIT30 = ///< Vendor Component Lock +#define B_PCH_SPI_SFDPX_VSCCX_EO_64K BIT29 = ///< 64k Erase valid (EO_64k_valid) +#define B_PCH_SPI_SFDPX_VSCCX_EO_4K BIT28 = ///< 4k Erase valid (EO_4k_valid) +#define B_PCH_SPI_SFDPX_VSCCX_RPMC BIT27 = ///< RPMC Supported +#define B_PCH_SPI_SFDPX_VSCCX_DPD BIT26 = ///< Deep Powerdown Supported +#define B_PCH_SPI_SFDPX_VSCCX_SUSRES BIT25 = ///< Suspend/Resume Supported +#define B_PCH_SPI_SFDPX_VSCCX_SOFTRES BIT24 = ///< Soft Reset Supported +#define B_PCH_SPI_SFDPX_VSCCX_64k_EO_MASK 0x00FF0000 = ///< 64k Erase Opcode (EO_64k) +#define B_PCH_SPI_SFDPX_VSCCX_4k_EO_MASK 0x0000FF00 = ///< 4k Erase Opcode (EO_4k) +#define B_PCH_SPI_SFDPX_VSCCX_QER (BIT7 | BIT6 | BIT5) = ///< Quad Enable Requirements +#define B_PCH_SPI_SFDPX_VSCCX_WEWS BIT4 = ///< Write Enable on Write Status +#define B_PCH_SPI_SFDPX_VSCCX_WSR BIT3 = ///< Write Status Required +#define B_PCH_SPI_SFDPX_VSCCX_WG_64B BIT2 = ///< Write Granularity, 0: 1 Byte; 1: 64 Bytes +#define R_PCH_SPI_SFDP1_VSCC1 0xC8 = ///< Vendor Specific Component Capabilities Register(32 bits) +#define R_PCH_SPI_PINTX 0xCC = ///< Parameter Table Index +#define N_PCH_SPI_PINTX_SPT 14 +#define V_PCH_SPI_PINTX_SPT_CPT0 0x0 = ///< Component 0 Property Parameter Table +#define V_PCH_SPI_PINTX_SPT_CPT1 0x1 = ///< Component 1 Property Parameter Table +#define N_PCH_SPI_PINTX_HORD 12 +#define V_PCH_SPI_PINTX_HORD_SFDP 0x0 = ///< SFDP Header +#define V_PCH_SPI_PINTX_HORD_PT 0x1 = ///< Parameter Table Header +#define V_PCH_SPI_PINTX_HORD_DATA 0x2 = ///< Data +#define R_PCH_SPI_PTDATA 0xD0 = ///< Parameter Table Data +#define R_PCH_SPI_SBRS 0xD4 = ///< SPI Bus Requester Status +#define R_PCH_SPI_SSML 0xF0 = ///< Set Strap Msg Lock +#define B_PCH_SPI_SSML_SSL BIT0 = ///< Set_Strap Lock +#define R_PCH_SPI_SSMC 0xF4 = ///< Set Strap Msg Control +#define B_PCH_SPI_SSMC_SSMS BIT0 = ///< Set_Strap Mux Select +#define R_PCH_SPI_SSMD 0xF8 = ///< Set Strap Msg Data +// +// @todo Follow up with EDS owner if it should be 3FFF or FFFF. +// +#define B_PCH_SPI_SRD_SSD 0x0000FFFF = ///< Set_Strap Data +// +// Flash Descriptor Base Address Region (FDBAR) from Flash Region 0 +// +#define R_PCH_SPI_FDBAR_FLVALSIG 0x00 = ///< Flash Valid Signature +#define V_PCH_SPI_FDBAR_FLVALSIG 0x0FF0A55A +#define R_PCH_SPI_FDBAR_FLASH_MAP0 0x04 +#define B_PCH_SPI_FDBAR_FCBA 0x000000FF = ///< Flash Component Base Address +#define B_PCH_SPI_FDBAR_NC 0x00000300 = ///< Number Of Components +#define N_PCH_SPI_FDBAR_NC 8 = ///< Number Of Components +#define V_PCH_SPI_FDBAR_NC_1 0x00000000 +#define V_PCH_SPI_FDBAR_NC_2 0x00000100 +#define B_PCH_SPI_FDBAR_FRBA 0x00FF0000 = ///< Flash Region Base Address +#define B_PCH_SPI_FDBAR_NR 0x07000000 = ///< Number Of Regions +#define R_PCH_SPI_FDBAR_FLASH_MAP1 0x08 +#define B_PCH_SPI_FDBAR_FMBA 0x000000FF = ///< Flash Master Base Address +#define B_PCH_SPI_FDBAR_NM 0x00000700 = ///< Number Of Masters +#define B_PCH_SPI_FDBAR_FPSBA 0x00FF0000 = ///< PCH Strap Base Address, [23:16] represents [11:4] +#define N_PCH_SPI_FDBAR_FPSBA 16 = ///< PCH Strap base Address bit position +#define N_PCH_SPI_FDBAR_FPSBA_REPR 4 = ///< PCH Strap base Address bit represents position +#define B_PCH_SPI_FDBAR_PCHSL 0xFF000000 = ///< PCH Strap Length, [31:24] represents number of Dwords +#define N_PCH_SPI_FDBAR_PCHSL 24 = ///< PCH Strap Length bit position +#define R_PCH_SPI_FDBAR_FLASH_MAP2 0x0C +#define B_PCH_SPI_FDBAR_FCPUSBA 0x000000FF = ///< CPU Strap Base Address, [7:0] represents [11:4] +#define N_PCH_SPI_FDBAR_FCPUSBA 0 = ///< CPU Strap Base Address bit position +#define N_PCH_SPI_FDBAR_FCPUSBA_REPR 4 = ///< CPU Strap Base Address bit represents position +#define B_PCH_SPI_FDBAR_CPUSL 0x0000FF00 = ///< CPU Strap Length, [15:8] represents number of Dwords +#define N_PCH_SPI_FDBAR_CPUSL 8 = ///< CPU Strap Length bit position +// +// Flash Component Base Address (FCBA) from Flash Region 0 +// +#define R_PCH_SPI_FCBA_FLCOMP 0x00 = ///< Flash Components Register +#define B_PCH_SPI_FLCOMP_RIDS_FREQ (BIT29 | BIT28 | BIT27) = ///< Read ID and Read Status Clock Frequency +#define B_PCH_SPI_FLCOMP_WE_FREQ (BIT26 | BIT25 | BIT24) = ///< Write and Erase Clock Frequency +#define B_PCH_SPI_FLCOMP_FRCF_FREQ (BIT23 | BIT22 | BIT21) = ///< Fast Read Clock Frequency +#define B_PCH_SPI_FLCOMP_FR_SUP BIT20 = ///< Fast Read Support. +#define B_PCH_SPI_FLCOMP_RC_FREQ (BIT19 | BIT18 | BIT17) = ///< Read Clock Frequency. +#define V_PCH_SPI_FLCOMP_FREQ_48MHZ 0x02 +#define V_PCH_SPI_FLCOMP_FREQ_30MHZ 0x04 +#define V_PCH_SPI_FLCOMP_FREQ_17MHZ 0x06 +#define B_PCH_SPI_FLCOMP_COMP1_MASK 0xF0 = ///< Flash Component 1 Size MASK +#define N_PCH_SPI_FLCOMP_COMP1 4 = ///< Flash Component 1 Size bit position +#define B_PCH_SPI_FLCOMP_COMP0_MASK 0x0F = ///< Flash Component 0 Size MASK +#define V_PCH_SPI_FLCOMP_COMP_512KB 0x80000 +// +// Descriptor Upper Map Section from Flash Region 0 +// +#define R_PCH_SPI_FLASH_UMAP1 0xEFC = ///< Flash Upper Map 1 +#define B_PCH_SPI_FLASH_UMAP1_VTBA 0x000000FF = ///< VSCC Table Base Address +#define B_PCH_SPI_FLASH_UMAP1_VTL 0x0000FF00 = ///< VSCC Table Length + +#define R_PCH_SPI_VTBA_JID0 0x00 = ///< JEDEC-ID 0 Register +#define S_PCH_SPI_VTBA_JID0 0x04 +#define B_PCH_SPI_VTBA_JID0_VID 0x000000FF +#define B_PCH_SPI_VTBA_JID0_DID0 0x0000FF00 +#define B_PCH_SPI_VTBA_JID0_DID1 0x00FF0000 +#define N_PCH_SPI_VTBA_JID0_DID0 0x08 +#define N_PCH_SPI_VTBA_JID0_DID1 0x10 +#define R_PCH_SPI_VTBA_VSCC0 0x04 +#define S_PCH_SPI_VTBA_VSCC0 0x04 + + +// +// SPI Private Configuration Space Registers +// +#define R_PCH_PCR_SPI_CLK_CTL 0xC004 +#define R_PCH_PCR_SPI_PWR_CTL 0xC008 +#define R_PCH_PCR_SPI_ESPI_SOFTSTRAPS 0xC210 +#define B_PCH_PCR_SPI_ESPI_SOFTSTRAPS_SLAVE BIT12 + +// +// MMP0 +// +#define R_PCH_SPI_STRP_MMP0 0xC4 ///< MMP0 Soft strap o= ffset +#define B_PCH_SPI_STRP_MMP0 0x10 ///< MMP0 Soft strap b= it + + +#define R_PCH_SPI_STRP_SFDP 0xF0 ///< PCH Soft Strap SF= DP +#define B_PCH_SPI_STRP_SFDP_QIORE BIT3 ///< Quad IO Read Enab= le +#define B_PCH_SPI_STRP_SFDP_QORE BIT2 ///< Quad Output Read = Enable +#define B_PCH_SPI_STRP_SFDP_DIORE BIT1 ///< Dual IO Read Enab= le +#define B_PCH_SPI_STRP_SFDP_DORE BIT0 ///< Dual Output Read = Enable + +// +// Descriptor Record 0 +// +#define R_PCH_SPI_STRP_DSCR_0 0x00 ///< PCH Soft Strap 0 +#define B_PCH_SPI_STRP_DSCR_0_PTT_SUPP BIT22 ///< PTT Supported + +#endif diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/Register/X58Ich10.h b/Sil= icon/Intel/SimicsIch10Pkg/Include/Register/X58Ich10.h new file mode 100644 index 0000000000..eac46955e0 --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/Include/Register/X58Ich10.h @@ -0,0 +1,114 @@ +/** @file + Various register numbers and value bits based on the following publicati= ons: + - Intel(R) datasheet 319973-003 + - Intel(R) datasheet 319974-017US + + Copyright (C) 2015, Red Hat, Inc. + Copyright (c) 2014, Gabriel L. Somlo + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __X58_ICH10_H__ +#define __X58_ICH10_H__ + +#include +#include + +// +// Simics Host Bridge DID Address +// +#define SIMICS_HOSTBRIDGE_DID \ + PCI_LIB_ADDRESS (0, 0, 0, PCI_DEVICE_ID_OFFSET) + +// +// Host Bridge Device ID (DID) value for ICH10 +// +#define INTEL_ICH10_DEVICE_ID 0x3400 + +// +// B/D/F/Type: 0/0/0/PCI +// +#define DRAMC_REGISTER_Q35(Offset) PCI_LIB_ADDRESS (0, 0, 0, (Offset)) +#define DRAMC_REGISTER_X58(Offset) PCI_LIB_ADDRESS (0, 20, 0, (Offset)) +#define MCH_GGC 0x52 +#define MCH_GGC_IVD BIT1 + +#define MCH_PCIEXBAR_LOW 0x10C +#define MCH_PCIEXBAR_LID 0x10E +#define MCH_PCIEXBAR_SHIFT 16 +#define MCH_PCIEXBAR_LOWMASK 0x0FFFFFFF +#define MCH_PCIEXBAR_BUS_FF 0 +#define MCH_PCIEXBAR_EN BIT0 + +#define MCH_PCIEXBAR_HIGH 0x64 +#define MCH_PCIEXBAR_HIGHMASK 0xFFFFFFF0 + +#define MCH_SMRAM 0x9D +#define MCH_SMRAM_D_LCK BIT4 +#define MCH_SMRAM_G_SMRAME BIT3 + +#define MCH_ESMRAMC 0x9E +#define MCH_ESMRAMC_H_SMRAME BIT7 +#define MCH_ESMRAMC_E_SMERR BIT6 +#define MCH_ESMRAMC_SM_CACHE BIT5 +#define MCH_ESMRAMC_SM_L1 BIT4 +#define MCH_ESMRAMC_SM_L2 BIT3 +#define MCH_ESMRAMC_TSEG_8MB BIT3 +#define MCH_ESMRAMC_TSEG_2MB BIT2 +#define MCH_ESMRAMC_TSEG_1MB BIT1 +#define MCH_ESMRAMC_TSEG_MASK (BIT3 | BIT2 | BIT1) +#define MCH_ESMRAMC_T_EN BIT0 + +#define MCH_GBSM 0xA4 +#define MCH_GBSM_MB_SHIFT 20 + +#define MCH_BGSM 0xA8 +#define MCH_BGSM_MB_SHIFT 20 + +#define MCH_TSEGMB 0xA8 +#define MCH_TSEGMB_MB_SHIFT 20 + +#define MCH_TOLUD 0xD0 + +// +// B/D/F/Type: 0/0x1f/0/PCI +// +#define POWER_MGMT_REGISTER_ICH10(Offset) \ + PCI_LIB_ADDRESS (0, 0x1f, 0, (Offset)) + +#define ICH10_PMBASE 0x40 +#define ICH10_PMBASE_MASK (BIT15 | BIT14 | BIT13 | BIT12 | BIT1= 1 | \ + BIT10 | BIT9 | BIT8 | BIT7) + +#define ICH10_ACPI_CNTL 0x44 +#define ICH10_ACPI_CNTL_ACPI_EN BIT7 + +#define ICH10_GEN_PMCON_1 0xA0 +#define ICH10_GEN_PMCON_1_SMI_LOCK BIT4 + +#define ICH10_RCBA 0xF0 +#define ICH10_RCBA_EN BIT0 + +#define ICH10_PMBASE_IO 0x400 +// +// IO ports +// +#define ICH10_APM_CNT 0xB2 +#define ICH10_APM_STS 0xB3 + +// +// IO ports relative to PMBASE +// +#define ICH10_PMBASE_OFS_SMI_EN 0x30 +#define ICH10_SMI_EN_APMC_EN BIT5 +#define ICH10_SMI_EN_GBL_SMI_EN BIT0 +#define ICH10_SMI_EN_EOS BIT1 // End of SMI + +#define ICH10_PMBASE_OFS_SMI_STS 0x34 +#define ICH10_SMI_STS_APM BIT5 // APM Status + +#define ICH10_ROOT_COMPLEX_BASE 0xFED1C000 + +#endif diff --git a/Silicon/Intel/SimicsIch10Pkg/IncludePrivate/Library/PchSpiComm= onLib.h b/Silicon/Intel/SimicsIch10Pkg/IncludePrivate/Library/PchSpiCommonL= ib.h new file mode 100644 index 0000000000..cf60f1fd58 --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/IncludePrivate/Library/PchSpiCommonLib.h @@ -0,0 +1,396 @@ +/** @file + Header file for the PCH SPI Common Driver. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _PCH_SPI_COMMON_LIB_H_ +#define _PCH_SPI_COMMON_LIB_H_ + +// +// Maximum time allowed while waiting the SPI cycle to complete +// Wait Time =3D 6 seconds =3D 6000000 microseconds +// Wait Period =3D 10 microseconds +// +#define SPI_WAIT_TIME 6000000 ///< Wait Time =3D 6 seconds =3D 60000= 00 microseconds +#define SPI_WAIT_PERIOD 10 ///< Wait Period =3D 10 microseconds + +/// +/// Flash cycle Type +/// +typedef enum { + FlashCycleRead, + FlashCycleWrite, + FlashCycleErase, + FlashCycleReadSfdp, + FlashCycleReadJedecId, + FlashCycleWriteStatus, + FlashCycleReadStatus, + FlashCycleMax +} FLASH_CYCLE_TYPE; + +/// +/// Flash Component Number +/// +typedef enum { + FlashComponent0, + FlashComponent1, + FlashComponentMax +} FLASH_COMPONENT_NUM; + +/// +/// Private data structure definitions for the driver +/// +#define PCH_SPI_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('P', 'S', 'P', 'I') + +typedef struct { + UINT32 Signature; + EFI_HANDLE Handle; + EFI_SPI_PROTOCOL SpiProtocol; + UINT16 PchAcpiBase; + UINTN PchSpiBase; + UINT16 ReadPermission; + UINT16 WritePermission; + UINT32 SfdpVscc0Value; + UINT32 SfdpVscc1Value; + UINT16 PchStrapBaseAddr; + UINT16 PchStrapSize; + UINT16 CpuStrapBaseAddr; + UINT16 CpuStrapSize; + UINT8 NumberOfComponents; + UINT32 Component1StartAddr; + UINT32 TotalFlashSize; +} SPI_INSTANCE; + +#define SPI_INSTANCE_FROM_SPIPROTOCOL(a) CR (a, SPI_INSTANCE, SpiProtocol= , PCH_SPI_PRIVATE_DATA_SIGNATURE) + +// +// Function prototypes used by the SPI protocol. +// + +/** + Initialize an SPI protocol instance. + + @param[in] SpiInstance Pointer to SpiInstance to initialize + + @retval EFI_SUCCESS The protocol instance was properly initi= alized + @exception EFI_UNSUPPORTED The PCH is not supported by this module +**/ +EFI_STATUS +SpiProtocolConstructor ( + IN SPI_INSTANCE *SpiInstance + ); + +/** + This function is a hook for Spi to disable BIOS Write Protect + + @retval EFI_SUCCESS The protocol instance was properly initi= alized + @retval EFI_ACCESS_DENIED The BIOS Region can only be updated in S= MM phase + +**/ +EFI_STATUS +EFIAPI +DisableBiosWriteProtect ( + VOID + ); + +/** + This function is a hook for Spi to enable BIOS Write Protect + + +**/ +VOID +EFIAPI +EnableBiosWriteProtect ( + VOID + ); + +/** + Acquire pch spi mmio address. + + @param[in] SpiInstance Pointer to SpiInstance to initialize + + @retval PchSpiBar0 return SPI MMIO address +**/ +UINTN +AcquireSpiBar0 ( + IN SPI_INSTANCE *SpiInstance + ); + +/** + Release pch spi mmio address. + + @param[in] SpiInstance Pointer to SpiInstance to initialize + + @retval None +**/ +VOID +ReleaseSpiBar0 ( + IN SPI_INSTANCE *SpiInstance + ); + +/** + Read data from the flash part. + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] FlashRegionType The Flash Region type for flash cycle wh= ich is listed in the Descriptor. + @param[in] Address The Flash Linear Address must fall withi= n a region for which BIOS has access permissions. + @param[in] ByteCount Number of bytes in the data portion of t= he SPI cycle. + @param[out] Buffer The Pointer to caller-allocated buffer c= ontaining the dada received. + It is the caller's responsibility to mak= e sure Buffer is large enough for the total number of bytes read. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashRead ( + IN EFI_SPI_PROTOCOL *This, + IN FLASH_REGION_TYPE FlashRegionType, + IN UINT32 Address, + IN UINT32 ByteCount, + OUT UINT8 *Buffer + ); + +/** + Write data to the flash part. + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] FlashRegionType The Flash Region type for flash cycle wh= ich is listed in the Descriptor. + @param[in] Address The Flash Linear Address must fall withi= n a region for which BIOS has access permissions. + @param[in] ByteCount Number of bytes in the data portion of t= he SPI cycle. + @param[in] Buffer Pointer to caller-allocated buffer conta= ining the data sent during the SPI cycle. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashWrite ( + IN EFI_SPI_PROTOCOL *This, + IN FLASH_REGION_TYPE FlashRegionType, + IN UINT32 Address, + IN UINT32 ByteCount, + IN UINT8 *Buffer + ); + +/** + Erase some area on the flash part. + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] FlashRegionType The Flash Region type for flash cycle wh= ich is listed in the Descriptor. + @param[in] Address The Flash Linear Address must fall withi= n a region for which BIOS has access permissions. + @param[in] ByteCount Number of bytes in the data portion of t= he SPI cycle. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashErase ( + IN EFI_SPI_PROTOCOL *This, + IN FLASH_REGION_TYPE FlashRegionType, + IN UINT32 Address, + IN UINT32 ByteCount + ); + +/** + Read SFDP data from the flash part. + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] ComponentNumber The Componen Number for chip select + @param[in] Address The starting byte address for SFDP data = read. + @param[in] ByteCount Number of bytes in SFDP data portion of = the SPI cycle + @param[out] SfdpData The Pointer to caller-allocated buffer c= ontaining the SFDP data received + It is the caller's responsibility to mak= e sure Buffer is large enough for the total number of bytes read + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashReadSfdp ( + IN EFI_SPI_PROTOCOL *This, + IN UINT8 ComponentNumber, + IN UINT32 Address, + IN UINT32 ByteCount, + OUT UINT8 *SfdpData + ); + +/** + Read Jedec Id from the flash part. + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] ComponentNumber The Componen Number for chip select + @param[in] ByteCount Number of bytes in JedecId data portion = of the SPI cycle, the data size is 3 typically + @param[out] JedecId The Pointer to caller-allocated buffer c= ontaining JEDEC ID received + It is the caller's responsibility to mak= e sure Buffer is large enough for the total number of bytes read. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashReadJedecId ( + IN EFI_SPI_PROTOCOL *This, + IN UINT8 ComponentNumber, + IN UINT32 ByteCount, + OUT UINT8 *JedecId + ); + +/** + Write the status register in the flash part. + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] ByteCount Number of bytes in Status data portion o= f the SPI cycle, the data size is 1 typically + @param[in] StatusValue The Pointer to caller-allocated buffer c= ontaining the value of Status register writing + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashWriteStatus ( + IN EFI_SPI_PROTOCOL *This, + IN UINT32 ByteCount, + IN UINT8 *StatusValue + ); + +/** + Read status register in the flash part. + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] ByteCount Number of bytes in Status data portion o= f the SPI cycle, the data size is 1 typically + @param[out] StatusValue The Pointer to caller-allocated buffer c= ontaining the value of Status register received. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +EFI_STATUS +EFIAPI +SpiProtocolFlashReadStatus ( + IN EFI_SPI_PROTOCOL *This, + IN UINT32 ByteCount, + OUT UINT8 *StatusValue + ); + +/** + Get the SPI region base and size, based on the enum type + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] FlashRegionType The Flash Region type for for the base a= ddress which is listed in the Descriptor. + @param[out] BaseAddress The Flash Linear Address for the Region = 'n' Base + @param[out] RegionSize The size for the Region 'n' + + @retval EFI_SUCCESS Read success + @retval EFI_INVALID_PARAMETER Invalid region type given + @retval EFI_DEVICE_ERROR The region is not used +**/ +EFI_STATUS +EFIAPI +SpiProtocolGetRegionAddress ( + IN EFI_SPI_PROTOCOL *This, + IN FLASH_REGION_TYPE FlashRegionType, + OUT UINT32 *BaseAddress, + OUT UINT32 *RegionSize + ); + +/** + Read PCH Soft Strap Values + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] SoftStrapAddr PCH Soft Strap address offset from FPSBA. + @param[in] ByteCount Number of bytes in SoftStrap data portio= n of the SPI cycle + @param[out] SoftStrapValue The Pointer to caller-allocated buffer c= ontaining PCH Soft Strap Value. + If the value of ByteCount is 0, the data= type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Sof= t Strap Length + It is the caller's responsibility to mak= e sure Buffer is large enough for the total number of bytes read. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +EFI_STATUS +EFIAPI +SpiProtocolReadPchSoftStrap ( + IN EFI_SPI_PROTOCOL *This, + IN UINT32 SoftStrapAddr, + IN UINT32 ByteCount, + OUT VOID *SoftStrapValue + ); + +/** + Read CPU Soft Strap Values + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] SoftStrapAddr CPU Soft Strap address offset from FCPUS= BA. + @param[in] ByteCount Number of bytes in SoftStrap data portio= n of the SPI cycle. + @param[out] SoftStrapValue The Pointer to caller-allocated buffer c= ontaining CPU Soft Strap Value. + If the value of ByteCount is 0, the data= type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Sof= t Strap Length + It is the caller's responsibility to mak= e sure Buffer is large enough for the total number of bytes read. + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. +**/ +EFI_STATUS +EFIAPI +SpiProtocolReadCpuSoftStrap ( + IN EFI_SPI_PROTOCOL *This, + IN UINT32 SoftStrapAddr, + IN UINT32 ByteCount, + OUT VOID *SoftStrapValue + ); + +/** + This function sends the programmed SPI command to the slave device. + + @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. + @param[in] SpiRegionType The SPI Region type for flash cycle whic= h is listed in the Descriptor + @param[in] FlashCycleType The Flash SPI cycle type list in HSFC (H= ardware Sequencing Flash Control Register) register + @param[in] Address The Flash Linear Address must fall withi= n a region for which BIOS has access permissions. + @param[in] ByteCount Number of bytes in the data portion of t= he SPI cycle. + @param[in,out] Buffer Pointer to caller-allocated buffer conta= ining the dada received or sent during the SPI cycle. + + @retval EFI_SUCCESS SPI command completes successfully. + @retval EFI_DEVICE_ERROR Device error, the command aborts abnorma= lly. + @retval EFI_ACCESS_DENIED Some unrecognized command encountered in= hardware sequencing mode + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. +**/ +EFI_STATUS +SendSpiCmd ( + IN EFI_SPI_PROTOCOL *This, + IN FLASH_REGION_TYPE FlashRegionType, + IN FLASH_CYCLE_TYPE FlashCycleType, + IN UINT32 Address, + IN UINT32 ByteCount, + IN OUT UINT8 *Buffer + ); + +/** + Wait execution cycle to complete on the SPI interface. + + @param[in] This The SPI protocol instance + @param[in] PchSpiBar0 Spi MMIO base address + @param[in] ErrorCheck TRUE if the SpiCycle needs to do the err= or check + + @retval TRUE SPI cycle completed on the interface. + @retval FALSE Time out while waiting the SPI cycle to = complete. + It's not safe to program the next comman= d on the SPI interface. +**/ +BOOLEAN +WaitForSpiCycleComplete ( + IN EFI_SPI_PROTOCOL *This, + IN UINTN PchSpiBar0, + IN BOOLEAN ErrorCheck + ); + +#endif diff --git a/Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSyste= mLib.inf b/Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSystemL= ib.inf new file mode 100644 index 0000000000..7b50ee8867 --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSystemLib.inf @@ -0,0 +1,34 @@ +## @file +# Library instance for ResetSystem library class for OVMF +# +# Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D ResetSystemLib + FILE_GUID =3D 66564872-21d4-4d2a-a68b-1e844f980820 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D ResetSystemLib + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 +# + +[Sources] + ResetSystemLib.c + +[Packages] + MdePkg/MdePkg.dec + SimicsIch10Pkg/Ich10Pkg.dec + +[LibraryClasses] + DebugLib + IoLib + TimerLib diff --git a/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SmmS= piFlashCommonLib.inf b/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashComm= onLib/SmmSpiFlashCommonLib.inf new file mode 100644 index 0000000000..23b334a080 --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFlash= CommonLib.inf @@ -0,0 +1,50 @@ +## @file +# SMM Library instance of Spi Flash Common Library Class +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010017 + BASE_NAME =3D SmmSpiFlashCommonLib + FILE_GUID =3D 9632D96E-E849-4217-9217-DC500B8AAE47 + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D DXE_SMM_DRIVER + LIBRARY_CLASS =3D SpiFlashCommonLib|DXE_SMM_DRIVER + CONSTRUCTOR =3D SmmSpiFlashCommonLibConstructor +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 +# + +[LibraryClasses] + PciLib + IoLib + MemoryAllocationLib + BaseLib + UefiLib + SmmServicesTableLib + BaseMemoryLib + DebugLib + +[Packages] + MdePkg/MdePkg.dec + SimicsIch10Pkg/Ich10Pkg.dec + +[Pcd] + gEfiPchTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES + gEfiPchTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES + +[Sources] + SpiFlashCommonSmmLib.c + SpiFlashCommon.c + +[Protocols] + gEfiSmmSpiProtocolGuid ## CONSUMES + +[Depex.X64.DXE_SMM_DRIVER] + gEfiSmmSpiProtocolGuid diff --git a/Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiCommonLi= b/BasePchSpiCommonLib.inf b/Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/Bas= ePchSpiCommonLib/BasePchSpiCommonLib.inf new file mode 100644 index 0000000000..df1da274a6 --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiCommonLib/BaseP= chSpiCommonLib.inf @@ -0,0 +1,31 @@ +## @file +# Component description file for the PchSpiCommonLib +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D BasePchSpiCommonLib + FILE_GUID =3D A37CB67E-7D85-45B3-B07E-BF65BDB603E8 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D PchSpiCommonLib + +[Sources] + SpiCommon.c + +[Packages] + MdePkg/MdePkg.dec + SimicsIch10Pkg/Ich10Pkg.dec + +[LibraryClasses] + IoLib + DebugLib + +[Pcd] + gEfiPchTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES + gEfiPchTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES diff --git a/Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2= Dxe.inf b/Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe= .inf new file mode 100644 index 0000000000..d8bc156dca --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.inf @@ -0,0 +1,61 @@ +## @file +# A DXE_RUNTIME_DRIVER providing synchronous SMI activations via the +# EFI_SMM_CONTROL2_PROTOCOL. +# +# We expect the PEI phase to have covered the following: +# - ensure that the underlying QEMU machine type be X58 +# (responsible: OvmfPkg/SmmAccess/SmmAccessPei.inf) +# - ensure that the ACPI PM IO space be configured +# (responsible: OvmfPkg/PlatformPei/PlatformPei.inf) +# +# Our own entry point is responsible for confirming the SMI feature and for +# configuring it. +# +# Copyright (C) 2013, 2015, Red Hat, Inc. +# Copyright (C) 2009 - 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D SmmControl2Dxe + FILE_GUID =3D 1206F7CA-A475-4624-A83E-E6FC9BB38E49 + MODULE_TYPE =3D DXE_RUNTIME_DRIVER + VERSION_STRING =3D 1.0 + PI_SPECIFICATION_VERSION =3D 0x00010400 + ENTRY_POINT =3D SmmControl2DxeEntryPoint + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 +# + +[Sources] + SmmControl2Dxe.c + +[Packages] + MdePkg/MdePkg.dec + SimicsX58SktPkg/SktPkg.dec + SimicsIch10Pkg/Ich10Pkg.dec + +[LibraryClasses] + BaseLib + DebugLib + IoLib + PcdLib + PciLib + UefiBootServicesTableLib + UefiDriverEntryPoint + +[Protocols] + gEfiS3SaveStateProtocolGuid ## SOMETIMES_CONSUMES + gEfiSmmControl2ProtocolGuid ## PRODUCES + +[FeaturePcd] + gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire + +[Depex] + TRUE diff --git a/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.h b/Silicon/Intel/= SimicsIch10Pkg/Spi/Smm/PchSpi.h new file mode 100644 index 0000000000..6ada9b121d --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.h @@ -0,0 +1,23 @@ +/** @file + Header file for the PCH SPI SMM Driver. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _PCH_SPI_H_ +#define _PCH_SPI_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpiSmm.inf b/Silicon/I= ntel/SimicsIch10Pkg/Spi/Smm/PchSpiSmm.inf new file mode 100644 index 0000000000..7b60d36c5b --- /dev/null +++ b/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpiSmm.inf @@ -0,0 +1,44 @@ +## @file +# Component description file for the SPI SMM driver. +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010017 + BASE_NAME =3D PchSpiSmm + FILE_GUID =3D 27F4917B-A707-4aad-9676-26DF168CBF0D + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D DXE_SMM_DRIVER + PI_SPECIFICATION_VERSION =3D 1.10 + ENTRY_POINT =3D InstallPchSpi + + + [LibraryClasses] + DebugLib + IoLib + UefiDriverEntryPoint + UefiBootServicesTableLib + BaseLib + SmmServicesTableLib + PchSpiCommonLib + +[Packages] + MdePkg/MdePkg.dec + SimicsIch10Pkg/Ich10Pkg.dec + +[Sources] + PchSpi.h + PchSpi.c + + +[Protocols] + gEfiSmmSpiProtocolGuid # PRODUCES #SERVER_BIOS + + +[Depex] + gEfiSmmBase2ProtocolGuid #This is for SmmServicesTableLib + AND gEfiSmmCpuProtocolGuid # This is for CpuSmmDisableBiosWriteProtect() --=20 2.16.2.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 (#46944): https://edk2.groups.io/g/devel/message/46944 Mute This Topic: https://groups.io/mt/33159239/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Fri Apr 26 02:55:24 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+46946+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+46946+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1567719524; cv=none; d=zoho.com; s=zohoarc; b=NOXs0rcSoVwISjnJ4ivb+JwwliRLNx5aw+XzNc7jTDzuC7tHZpq32gQtZsRq75ORwb/fKlweOAQC6/zZmLRgSzGfA7VoOxRuL8GRz3Ma24VK2cL7nMSGYvqaFG0yX1QXjhdbBmgmCnqO5YEWfJTgbQsLGE2c0uY+JiQbtW0FxNY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1567719524; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To:ARC-Authentication-Results; bh=V9hTK2afidyJHp9dOWkvfRrPr1ZxObjDJVXDoplf2qA=; b=No3smKmGk0BOFd/twW/03vwL5ZRahnB7KyCxJuV71hKMdLhqwB2z5kRUCCcAhC1f3oJz2U8JGPWmNH8TL2AM/eCnwC5luba2lx+DLudnkEFTE8xxIxy85jJYFVtV4yVPK8vG4TgDg1X33ESFzQwVdpM7KiBaEXTyxx8ZUu3g0yU= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+46946+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1567719524522246.92778920083276; Thu, 5 Sep 2019 14:38:44 -0700 (PDT) Return-Path: X-Received: from mga11.intel.com (mga11.intel.com []) by groups.io with SMTP; Thu, 05 Sep 2019 14:38:42 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Sep 2019 14:38:42 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,471,1559545200"; d="scan'208";a="267151620" X-Received: from ydwei-desk.amr.corp.intel.com ([10.24.15.168]) by orsmga001.jf.intel.com with ESMTP; 05 Sep 2019 14:38:41 -0700 From: "David Wei" To: devel@edk2.groups.io Cc: Hao Wu , Liming Gao , Ankit Sinha , Agyeman Prince , Kubacki Michael A , Nate DeSimone , Michael D Kinney Subject: [edk2-devel] [edk2-platforms PATCH v5 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules Date: Thu, 5 Sep 2019 14:38:36 -0700 Message-Id: <05d1efba97a237a6a2c8517d4090699752c40df2.1567718650.git.david.y.wei@intel.com> In-Reply-To: References: MIME-Version: 1.0 In-Reply-To: References: Precedence: Bulk List-Unsubscribe: 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,david.y.wei@intel.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1567719524; bh=xTKqB/G4T/zBSeo8UN5i4UNoGnc0e3QFwG/QuTCAy70=; h=Cc:Content-Type:Date:From:Reply-To:Subject:To; b=BjkI7YEeP5dvPwGDP56qbddNDoCE2fSSuf7VgtRGGMHbRz4f6Hcx+MZiUOXO40TN/2g FgpkN49fz/s9MXHXSBb2LC7tW6ckUofFZwhO0v54wbpEe5cW+2IucFiH1HYoed+bL2K5t kxYxD6OBBQAIhDH14dVu8c+uVI6duaV6x6g= X-ZohoMail-DKIM: pass (identity @groups.io) Add modules Include, Library, SimicsDxe, SimicsPei, Policy, SmbiosPlatformD= xe and SecCore for Simics Quick Start Platform support Cc: Hao Wu Cc: Liming Gao Cc: Ankit Sinha Cc: Agyeman Prince Cc: Kubacki Michael A Cc: Nate DeSimone Cc: Michael D Kinney Signed-off-by: David Wei --- .../SimicsOpenBoardPkg/Library/DxeLogoLib/Logo.c | 647 ++++++++ .../Library/LoadLinuxLib/Linux.c | 662 +++++++++ .../Library/LoadLinuxLib/LinuxGdt.c | 175 +++ .../Library/NvVarsFileLib/FsAccess.c | 507 +++++++ .../Library/NvVarsFileLib/NvVarsFileLib.c | 77 + .../Library/PciHostBridgeLib/PciHostBridgeLib.c | 419 ++++++ .../SimicsOpenBoardPkg/Library/PeiReportFvLib/Fv.c | 100 ++ .../Library/PeiReportFvLib/PeiReportFvLib.c | 119 ++ .../Library/PlatformBootManagerLib/BdsPlatform.c | 1553 ++++++++++++++++= ++++ .../Library/PlatformBootManagerLib/PlatformData.c | 35 + .../SerializeVariablesLib/SerializeVariablesLib.c | 869 +++++++++++ .../SiliconPolicyInitLib/SiliconPolicyInitLib.c | 108 ++ .../SiliconPolicyUpdateLib.c | 70 + .../Intel/SimicsOpenBoardPkg/SecCore/SecMain.c | 956 ++++++++++++ .../Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.c | 865 +++++++++++ .../SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.c | 124 ++ Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.c | 57 + .../SimicsOpenBoardPkg/SimicsPei/FeatureControl.c | 115 ++ .../Intel/SimicsOpenBoardPkg/SimicsPei/MemDetect.c | 568 +++++++ .../Intel/SimicsOpenBoardPkg/SimicsPei/Platform.c | 630 ++++++++ .../SmbiosPlatformDxe/SmbiosPlatformDxe.c | 148 ++ .../Include/Guid/SimicsBoardConfig.h | 18 + .../Include/IndustryStandard/I440FxPiix4.h | 50 + .../Include/IndustryStandard/LinuxBzImage.h | 159 ++ .../Include/Library/LoadLinuxLib.h | 205 +++ .../Include/Library/SerializeVariablesLib.h | 224 +++ .../SimicsOpenBoardPkg/Include/SimicsPlatforms.h | 55 + .../Library/DxeLogoLib/DxeLogoLib.inf | 55 + .../Library/DxeLogoLib/OemBadging.h | 83 ++ .../Library/LoadLinuxLib/DxeLoadLinuxLib.inf | 42 + .../Library/LoadLinuxLib/Ia32/JumpToKernel.nasm | 41 + .../Library/LoadLinuxLib/LoadLinuxLib.h | 52 + .../Library/LoadLinuxLib/X64/JumpToKernel.nasm | 85 ++ .../Library/NvVarsFileLib/NvVarsFileLib.h | 55 + .../Library/NvVarsFileLib/NvVarsFileLib.inf | 53 + .../Library/PciHostBridgeLib/PciHostBridge.h | 68 + .../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 51 + .../Library/PeiReportFvLib/PeiReportFvLib.inf | 56 + .../Library/PlatformBootManagerLib/BdsPlatform.h | 172 +++ .../PlatformBootManagerLib.inf | 72 + .../SerializeVariablesLib/SerializeVariablesLib.h | 33 + .../SerializeVariablesLib.inf | 36 + .../SiliconPolicyInitLib/SiliconPolicyInitLib.inf | 38 + .../SiliconPolicyUpdateLib.inf | 35 + .../SimicsOpenBoardPkg/SecCore/Ia32/SecEntry.nasm | 45 + .../Intel/SimicsOpenBoardPkg/SecCore/SecMain.inf | 73 + .../SimicsOpenBoardPkg/SecCore/X64/SecEntry.nasm | 45 + .../Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.h | 38 + .../SimicsOpenBoardPkg/SimicsDxe/Platform.uni | 31 + .../SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.h | 52 + .../SimicsOpenBoardPkg/SimicsDxe/PlatformForms.vfr | 67 + .../SimicsOpenBoardPkg/SimicsDxe/SimicsDxe.inf | 65 + Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.h | 50 + .../Intel/SimicsOpenBoardPkg/SimicsPei/Platform.h | 88 ++ .../SimicsOpenBoardPkg/SimicsPei/SimicsPei.inf | 104 ++ .../SmbiosPlatformDxe/SmbiosPlatformDxe.h | 38 + .../SmbiosPlatformDxe/SmbiosPlatformDxe.inf | 51 + 57 files changed, 11289 insertions(+) create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/Lo= go.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/= Linux.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/= LinuxGdt.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib= /FsAccess.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib= /NvVarsFileLib.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridge= Lib/PciHostBridgeLib.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLi= b/Fv.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLi= b/PeiReportFvLib.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootM= anagerLib/BdsPlatform.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootM= anagerLib/PlatformData.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVari= ablesLib/SerializeVariablesLib.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Policy/Library/Silico= nPolicyInitLib/SiliconPolicyInitLib.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Policy/Library/Silico= nPolicyUpdateLib/SiliconPolicyUpdateLib.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformCon= fig.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/FeatureCont= rol.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/MemDetect.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/Smb= iosPlatformDxe.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsBo= ardConfig.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStand= ard/I440FxPiix4.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStand= ard/LinuxBzImage.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Library/LoadL= inuxLib.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Library/Seria= lizeVariablesLib.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatfor= ms.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/Dx= eLogoLib.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/Oe= mBadging.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/= DxeLoadLinuxLib.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/= Ia32/JumpToKernel.nasm create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/= LoadLinuxLib.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/= X64/JumpToKernel.nasm create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib= /NvVarsFileLib.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib= /NvVarsFileLib.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridge= Lib/PciHostBridge.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridge= Lib/PciHostBridgeLib.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLi= b/PeiReportFvLib.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootM= anagerLib/BdsPlatform.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootM= anagerLib/PlatformBootManagerLib.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVari= ablesLib/SerializeVariablesLib.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVari= ablesLib/SerializeVariablesLib.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Policy/Library/Silico= nPolicyInitLib/SiliconPolicyInitLib.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Policy/Library/Silico= nPolicyUpdateLib/SiliconPolicyUpdateLib.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SecCore/Ia32/SecEntry= .nasm create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SecCore/X64/SecEntry.= nasm create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.uni create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformCon= fig.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformFor= ms.vfr create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/SimicsDxe.i= nf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/SimicsPei.i= nf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/Smb= iosPlatformDxe.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/Smb= iosPlatformDxe.inf diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/Logo.c b/= Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/Logo.c new file mode 100644 index 0000000000..48a718a90d --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/Logo.c @@ -0,0 +1,647 @@ +/** @file + BDS Lib functions which contain all the code to connect console device + + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/** + Convert a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer + is passed in a GopBlt buffer will be allocated by this routine. If a Gop= Blt + buffer is passed in it will be used if it is big enough. + + @param BmpImage Pointer to BMP file + @param BmpImageSize Number of bytes in BmpImage + @param GopBlt Buffer containing GOP version of BmpImage. + @param GopBltSize Size of GopBlt in bytes. + @param PixelHeight Height of GopBlt/BmpImage in pixels + @param PixelWidth Width of GopBlt/BmpImage in pixels + + @retval EFI_SUCCESS GopBlt and GopBltSize are returned. + @retval EFI_UNSUPPORTED BmpImage is not a valid *.BMP image + @retval EFI_BUFFER_TOO_SMALL The passed in GopBlt buffer is not big eno= ugh. + GopBltSize will contain the required size. + @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate. + +**/ +EFI_STATUS +ConvertBmpToGopBlt ( + IN VOID *BmpImage, + IN UINTN BmpImageSize, + IN OUT VOID **GopBlt, + IN OUT UINTN *GopBltSize, + OUT UINTN *PixelHeight, + OUT UINTN *PixelWidth + ) +{ + UINT8 *Image; + UINT8 *ImageHeader; + BMP_IMAGE_HEADER *BmpHeader; + BMP_COLOR_MAP *BmpColorMap; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; + UINT64 BltBufferSize; + UINTN Index; + UINTN Height; + UINTN Width; + UINTN ImageIndex; + UINT32 DataSizePerLine; + BOOLEAN IsAllocated; + UINT32 ColorMapNum; + + if (sizeof (BMP_IMAGE_HEADER) > BmpImageSize) { + return EFI_INVALID_PARAMETER; + } + + BmpHeader =3D (BMP_IMAGE_HEADER *) BmpImage; + + if (BmpHeader->CharB !=3D 'B' || BmpHeader->CharM !=3D 'M') { + return EFI_UNSUPPORTED; + } + + // + // Doesn't support compress. + // + if (BmpHeader->CompressionType !=3D 0) { + return EFI_UNSUPPORTED; + } + + // + // Only support BITMAPINFOHEADER format. + // BITMAPFILEHEADER + BITMAPINFOHEADER =3D BMP_IMAGE_HEADER + // + if (BmpHeader->HeaderSize !=3D sizeof (BMP_IMAGE_HEADER) - OFFSET_OF(BMP= _IMAGE_HEADER, HeaderSize)) { + return EFI_UNSUPPORTED; + } + + // + // The data size in each line must be 4 byte alignment. + // + DataSizePerLine =3D ((BmpHeader->PixelWidth * BmpHeader->BitPerPixel + 3= 1) >> 3) & (~0x3); + BltBufferSize =3D MultU64x32 (DataSizePerLine, BmpHeader->PixelHeight); + if (BltBufferSize > (UINT32) ~0) { + return EFI_INVALID_PARAMETER; + } + + if ((BmpHeader->Size !=3D BmpImageSize) || + (BmpHeader->Size < BmpHeader->ImageOffset) || + (BmpHeader->Size - BmpHeader->ImageOffset !=3D BmpHeader->PixelHeig= ht * DataSizePerLine)) { + return EFI_INVALID_PARAMETER; + } + + // + // Calculate Color Map offset in the image. + // + Image =3D BmpImage; + BmpColorMap =3D (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER)); + if (BmpHeader->ImageOffset < sizeof (BMP_IMAGE_HEADER)) { + return EFI_INVALID_PARAMETER; + } + + if (BmpHeader->ImageOffset > sizeof (BMP_IMAGE_HEADER)) { + switch (BmpHeader->BitPerPixel) { + case 1: + ColorMapNum =3D 2; + break; + case 4: + ColorMapNum =3D 16; + break; + case 8: + ColorMapNum =3D 256; + break; + default: + ColorMapNum =3D 0; + break; + } + // + // BMP file may has padding data between the bmp header section and th= e bmp data section. + // + if (BmpHeader->ImageOffset - sizeof (BMP_IMAGE_HEADER) < sizeof (BMP_C= OLOR_MAP) * ColorMapNum) { + return EFI_INVALID_PARAMETER; + } + } + + // + // Calculate graphics image data address in the image + // + Image =3D ((UINT8 *) BmpImage) + BmpHeader->ImageOffset; + ImageHeader =3D Image; + + // + // Calculate the BltBuffer needed size. + // + BltBufferSize =3D MultU64x32 ((UINT64) BmpHeader->PixelWidth, BmpHeader-= >PixelHeight); + // + // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doe= sn't overflow + // + if (BltBufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_B= LT_PIXEL))) { + return EFI_UNSUPPORTED; + } + BltBufferSize =3D MultU64x32 (BltBufferSize, sizeof (EFI_GRAPHICS_OUTPUT= _BLT_PIXEL)); + + IsAllocated =3D FALSE; + if (*GopBlt =3D=3D NULL) { + // + // GopBlt is not allocated by caller. + // + *GopBltSize =3D (UINTN) BltBufferSize; + *GopBlt =3D AllocatePool (*GopBltSize); + IsAllocated =3D TRUE; + if (*GopBlt =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + } else { + // + // GopBlt has been allocated by caller. + // + if (*GopBltSize < (UINTN) BltBufferSize) { + *GopBltSize =3D (UINTN) BltBufferSize; + return EFI_BUFFER_TOO_SMALL; + } + } + + *PixelWidth =3D BmpHeader->PixelWidth; + *PixelHeight =3D BmpHeader->PixelHeight; + + // + // Convert image from BMP to Blt buffer format + // + BltBuffer =3D *GopBlt; + for (Height =3D 0; Height < BmpHeader->PixelHeight; Height++) { + Blt =3D &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->= PixelWidth]; + for (Width =3D 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt= ++) { + switch (BmpHeader->BitPerPixel) { + case 1: + // + // Convert 1-bit (2 colors) BMP to 24-bit color + // + for (Index =3D 0; Index < 8 && Width < BmpHeader->PixelWidth; Inde= x++) { + Blt->Red =3D BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red; + Blt->Green =3D BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Gre= en; + Blt->Blue =3D BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blu= e; + Blt++; + Width++; + } + + Blt--; + Width--; + break; + + case 4: + // + // Convert 4-bit (16 colors) BMP Palette to 24-bit color + // + Index =3D (*Image) >> 4; + Blt->Red =3D BmpColorMap[Index].Red; + Blt->Green =3D BmpColorMap[Index].Green; + Blt->Blue =3D BmpColorMap[Index].Blue; + if (Width < (BmpHeader->PixelWidth - 1)) { + Blt++; + Width++; + Index =3D (*Image) & 0x0f; + Blt->Red =3D BmpColorMap[Index].Red; + Blt->Green =3D BmpColorMap[Index].Green; + Blt->Blue =3D BmpColorMap[Index].Blue; + } + break; + + case 8: + // + // Convert 8-bit (256 colors) BMP Palette to 24-bit color + // + Blt->Red =3D BmpColorMap[*Image].Red; + Blt->Green =3D BmpColorMap[*Image].Green; + Blt->Blue =3D BmpColorMap[*Image].Blue; + break; + + case 24: + // + // It is 24-bit BMP. + // + Blt->Blue =3D *Image++; + Blt->Green =3D *Image++; + Blt->Red =3D *Image; + break; + + default: + // + // Other bit format BMP is not supported. + // + if (IsAllocated) { + FreePool (*GopBlt); + *GopBlt =3D NULL; + } + return EFI_UNSUPPORTED; + break; + }; + + } + + ImageIndex =3D (UINTN) (Image - ImageHeader); + if ((ImageIndex % 4) !=3D 0) { + // + // Bmp Image starts each row on a 32-bit boundary! + // + Image =3D Image + (4 - (ImageIndex % 4)); + } + } + + return EFI_SUCCESS; +} + +/** + Use SystemTable Conout to stop video based Simple Text Out consoles from= going + to the video device. Put up LogoFile on every video device that is a con= sole. + + @param[in] LogoFile File name of logo to display on the center of the= screen. + + @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and = logo displayed. + @retval EFI_UNSUPPORTED Logo not found + +**/ +EFI_STATUS +EFIAPI +EnableBootLogo ( + IN EFI_GUID *LogoFile + ) +{ + EFI_STATUS Status; + EFI_OEM_BADGING_PROTOCOL *Badging; + UINT32 SizeOfX; + UINT32 SizeOfY; + INTN DestX; + INTN DestY; + UINT8 *ImageData; + UINTN ImageSize; + UINTN BltSize; + UINT32 Instance; + EFI_BADGING_FORMAT Format; + EFI_BADGING_DISPLAY_ATTRIBUTE Attribute; + UINTN CoordinateX; + UINTN CoordinateY; + UINTN Height; + UINTN Width; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; + EFI_UGA_DRAW_PROTOCOL *UgaDraw; + UINT32 ColorDepth; + UINT32 RefreshRate; + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; + EFI_BOOT_LOGO_PROTOCOL *BootLogo; + UINTN NumberOfLogos; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LogoBlt; + UINTN LogoDestX; + UINTN LogoDestY; + UINTN LogoHeight; + UINTN LogoWidth; + UINTN NewDestX; + UINTN NewDestY; + UINTN NewHeight; + UINTN NewWidth; + UINT64 BufferSize; + + UgaDraw =3D NULL; + // + // Try to open GOP first + // + Status =3D gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutp= utProtocolGuid, (VOID **) &GraphicsOutput); + if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) { + GraphicsOutput =3D NULL; + // + // Open GOP failed, try to open UGA + // + Status =3D gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawPro= tocolGuid, (VOID **) &UgaDraw); + } + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + // + // Try to open Boot Logo Protocol. + // + BootLogo =3D NULL; + gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLog= o); + + // + // Erase Cursor from screen + // + gST->ConOut->EnableCursor (gST->ConOut, FALSE); + + Badging =3D NULL; + Status =3D gBS->LocateProtocol (&gEfiOemBadgingProtocolGuid, NULL, (VOI= D **) &Badging); + + if (GraphicsOutput !=3D NULL) { + SizeOfX =3D GraphicsOutput->Mode->Info->HorizontalResolution; + SizeOfY =3D GraphicsOutput->Mode->Info->VerticalResolution; + + } else if (UgaDraw !=3D NULL && FeaturePcdGet (PcdUgaConsumeSupport)) { + Status =3D UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth,= &RefreshRate); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + } else { + return EFI_UNSUPPORTED; + } + + Blt =3D NULL; + NumberOfLogos =3D 0; + LogoDestX =3D 0; + LogoDestY =3D 0; + LogoHeight =3D 0; + LogoWidth =3D 0; + NewDestX =3D 0; + NewDestY =3D 0; + NewHeight =3D 0; + NewWidth =3D 0; + Instance =3D 0; + while (1) { + ImageData =3D NULL; + ImageSize =3D 0; + + if (Badging !=3D NULL) { + // + // Get image from OEMBadging protocol. + // + Status =3D Badging->GetImage ( + Badging, + &Instance, + &Format, + &ImageData, + &ImageSize, + &Attribute, + &CoordinateX, + &CoordinateY + ); + if (EFI_ERROR (Status)) { + goto Done; + } + + } else { + // + // Get the specified image from FV. + // + Status =3D GetSectionFromAnyFv (LogoFile, EFI_SECTION_RAW, 0, (VOID = **) &ImageData, &ImageSize); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + CoordinateX =3D 0; + CoordinateY =3D 0; + Attribute =3D EfiBadgingDisplayAttributeCenter; + } + + if (Blt !=3D NULL) { + FreePool (Blt); + } + + // + // Try BMP decoder + // + Blt =3D NULL; + Status =3D ConvertBmpToGopBlt ( + ImageData, + ImageSize, + (VOID **) &Blt, + &BltSize, + &Height, + &Width + ); + + if (EFI_ERROR (Status)) { + FreePool (ImageData); + + if (Badging =3D=3D NULL) { + return Status; + } else { + continue; + } + } + + // + // Calculate the display position according to Attribute. + // + switch (Attribute) { + case EfiBadgingDisplayAttributeLeftTop: + DestX =3D CoordinateX; + DestY =3D CoordinateY; + break; + + case EfiBadgingDisplayAttributeCenterTop: + DestX =3D (SizeOfX - Width) / 2; + DestY =3D CoordinateY; + break; + + case EfiBadgingDisplayAttributeRightTop: + DestX =3D (SizeOfX - Width - CoordinateX); + DestY =3D CoordinateY;; + break; + + case EfiBadgingDisplayAttributeCenterRight: + DestX =3D (SizeOfX - Width - CoordinateX); + DestY =3D (SizeOfY - Height) / 2; + break; + + case EfiBadgingDisplayAttributeRightBottom: + DestX =3D (SizeOfX - Width - CoordinateX); + DestY =3D (SizeOfY - Height - CoordinateY); + break; + + case EfiBadgingDisplayAttributeCenterBottom: + DestX =3D (SizeOfX - Width) / 2; + DestY =3D (SizeOfY - Height - CoordinateY); + break; + + case EfiBadgingDisplayAttributeLeftBottom: + DestX =3D CoordinateX; + DestY =3D (SizeOfY - Height - CoordinateY); + break; + + case EfiBadgingDisplayAttributeCenterLeft: + DestX =3D CoordinateX; + DestY =3D (SizeOfY - Height) / 2; + break; + + case EfiBadgingDisplayAttributeCenter: + DestX =3D (SizeOfX - Width) / 2; + DestY =3D (SizeOfY - Height) / 2; + break; + + default: + DestX =3D CoordinateX; + DestY =3D CoordinateY; + break; + } + + if ((DestX >=3D 0) && (DestY >=3D 0)) { + if (GraphicsOutput !=3D NULL) { + Status =3D GraphicsOutput->Blt ( + GraphicsOutput, + Blt, + EfiBltBufferToVideo, + 0, + 0, + (UINTN) DestX, + (UINTN) DestY, + Width, + Height, + Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + ); + } else if (UgaDraw !=3D NULL && FeaturePcdGet (PcdUgaConsumeSupport)= ) { + Status =3D UgaDraw->Blt ( + UgaDraw, + (EFI_UGA_PIXEL *) Blt, + EfiUgaBltBufferToVideo, + 0, + 0, + (UINTN) DestX, + (UINTN) DestY, + Width, + Height, + Width * sizeof (EFI_UGA_PIXEL) + ); + } else { + Status =3D EFI_UNSUPPORTED; + } + + // + // Report displayed Logo information. + // + if (!EFI_ERROR (Status)) { + NumberOfLogos++; + + if (LogoWidth =3D=3D 0) { + // + // The first Logo. + // + LogoDestX =3D (UINTN) DestX; + LogoDestY =3D (UINTN) DestY; + LogoWidth =3D Width; + LogoHeight =3D Height; + } else { + // + // Merge new logo with old one. + // + NewDestX =3D MIN ((UINTN) DestX, LogoDestX); + NewDestY =3D MIN ((UINTN) DestY, LogoDestY); + NewWidth =3D MAX ((UINTN) DestX + Width, LogoDestX + LogoWidth) = - NewDestX; + NewHeight =3D MAX ((UINTN) DestY + Height, LogoDestY + LogoHeigh= t) - NewDestY; + + LogoDestX =3D NewDestX; + LogoDestY =3D NewDestY; + LogoWidth =3D NewWidth; + LogoHeight =3D NewHeight; + } + } + } + + FreePool (ImageData); + + if (Badging =3D=3D NULL) { + break; + } + } + +Done: + if (BootLogo =3D=3D NULL || NumberOfLogos =3D=3D 0) { + // + // No logo displayed. + // + if (Blt !=3D NULL) { + FreePool (Blt); + } + + return Status; + } + + // + // Advertise displayed Logo information. + // + if (NumberOfLogos =3D=3D 1) { + // + // Only one logo displayed, use its Blt buffer directly for BootLogo p= rotocol. + // + LogoBlt =3D Blt; + Status =3D EFI_SUCCESS; + } else { + // + // More than one Logo displayed, get merged BltBuffer using VideoToBuf= fer operation. + // + if (Blt !=3D NULL) { + FreePool (Blt); + } + + // + // Ensure the LogoHeight * LogoWidth doesn't overflow + // + if (LogoHeight > DivU64x64Remainder ((UINTN) ~0, LogoWidth, NULL)) { + return EFI_UNSUPPORTED; + } + BufferSize =3D MultU64x64 (LogoWidth, LogoHeight); + + // + // Ensure the BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) does= n't overflow + // + if (BufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BL= T_PIXEL))) { + return EFI_UNSUPPORTED; + } + + LogoBlt =3D AllocateZeroPool ((UINTN)BufferSize * sizeof (EFI_GRAPHICS= _OUTPUT_BLT_PIXEL)); + if (LogoBlt =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if (GraphicsOutput !=3D NULL) { + Status =3D GraphicsOutput->Blt ( + GraphicsOutput, + LogoBlt, + EfiBltVideoToBltBuffer, + LogoDestX, + LogoDestY, + 0, + 0, + LogoWidth, + LogoHeight, + LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXE= L) + ); + } else if (UgaDraw !=3D NULL && FeaturePcdGet (PcdUgaConsumeSupport)) { + Status =3D UgaDraw->Blt ( + UgaDraw, + (EFI_UGA_PIXEL *) LogoBlt, + EfiUgaVideoToBltBuffer, + LogoDestX, + LogoDestY, + 0, + 0, + LogoWidth, + LogoHeight, + LogoWidth * sizeof (EFI_UGA_PIXEL) + ); + } else { + Status =3D EFI_UNSUPPORTED; + } + } + + if (!EFI_ERROR (Status)) { + BootLogo->SetBootLogo (BootLogo, LogoBlt, LogoDestX, LogoDestY, LogoWi= dth, LogoHeight); + } + FreePool (LogoBlt); + + return Status; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c= b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c new file mode 100644 index 0000000000..631bb7ee69 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c @@ -0,0 +1,662 @@ +/** @file + Copyright (c) 2011 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "LoadLinuxLib.h" + + +/** + A simple check of the kernel setup image + + An assumption is made that the size of the data is at least the + size of struct boot_params. + + @param[in] KernelSetup - The kernel setup image + + @retval EFI_SUCCESS - The kernel setup looks valid and supported + @retval EFI_INVALID_PARAMETER - KernelSetup was NULL + @retval EFI_UNSUPPORTED - The kernel setup is not valid or supported + +**/ +STATIC +EFI_STATUS +EFIAPI +BasicKernelSetupCheck ( + IN VOID *KernelSetup + ) +{ + return LoadLinuxCheckKernelSetup(KernelSetup, sizeof (struct boot_params= )); +} + + +EFI_STATUS +EFIAPI +LoadLinuxCheckKernelSetup ( + IN VOID *KernelSetup, + IN UINTN KernelSetupSize + ) +{ + struct boot_params *Bp; + + if (KernelSetup =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + if (KernelSetupSize < sizeof (*Bp)) { + return EFI_UNSUPPORTED; + } + + Bp =3D (struct boot_params*) KernelSetup; + + if ((Bp->hdr.signature !=3D 0xAA55) || // Check boot sector signature + (Bp->hdr.header !=3D SETUP_HDR) || + (Bp->hdr.version < 0x205) || // We only support relocatable kernels + (!Bp->hdr.relocatable_kernel) + ) { + return EFI_UNSUPPORTED; + } else { + return EFI_SUCCESS; + } +} + + +UINTN +EFIAPI +LoadLinuxGetKernelSize ( + IN VOID *KernelSetup, + IN UINTN KernelSize + ) +{ + struct boot_params *Bp; + + if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) { + return 0; + } + + Bp =3D (struct boot_params*) KernelSetup; + + if (Bp->hdr.version > 0x20a) { + return Bp->hdr.init_size; + } else { + // + // Add extra size for kernel decompression + // + return 3 * KernelSize; + } +} + + +VOID* +EFIAPI +LoadLinuxAllocateKernelSetupPages ( + IN UINTN Pages + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Address; + + Address =3D BASE_1GB; + Status =3D gBS->AllocatePages ( + AllocateMaxAddress, + EfiLoaderData, + Pages, + &Address + ); + if (!EFI_ERROR (Status)) { + return (VOID*)(UINTN) Address; + } else { + return NULL; + } +} + +EFI_STATUS +EFIAPI +LoadLinuxInitializeKernelSetup ( + IN VOID *KernelSetup + ) +{ + EFI_STATUS Status; + UINTN SetupEnd; + struct boot_params *Bp; + + Status =3D BasicKernelSetupCheck (KernelSetup); + if (EFI_ERROR (Status)) { + return Status; + } + + Bp =3D (struct boot_params*) KernelSetup; + + SetupEnd =3D 0x202 + (Bp->hdr.jump & 0xff); + + // + // Clear all but the setup_header + // + ZeroMem (KernelSetup, 0x1f1); + ZeroMem (((UINT8 *)KernelSetup) + SetupEnd, 4096 - SetupEnd); + DEBUG ((EFI_D_INFO, "Cleared kernel setup 0-0x1f1, 0x%Lx-0x1000\n", + (UINT64)SetupEnd)); + + return EFI_SUCCESS; +} + +VOID* +EFIAPI +LoadLinuxAllocateKernelPages ( + IN VOID *KernelSetup, + IN UINTN Pages + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS KernelAddress; + UINT32 Loop; + struct boot_params *Bp; + + if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) { + return NULL; + } + + Bp =3D (struct boot_params*) KernelSetup; + + for (Loop =3D 1; Loop < 512; Loop++) { + KernelAddress =3D MultU64x32 ( + 2 * Bp->hdr.kernel_alignment, + Loop + ); + Status =3D gBS->AllocatePages ( + AllocateAddress, + EfiLoaderData, + Pages, + &KernelAddress + ); + if (!EFI_ERROR (Status)) { + return (VOID*)(UINTN) KernelAddress; + } + } + + return NULL; +} + + +VOID* +EFIAPI +LoadLinuxAllocateCommandLinePages ( + IN UINTN Pages + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Address; + + Address =3D 0xa0000; + Status =3D gBS->AllocatePages ( + AllocateMaxAddress, + EfiLoaderData, + Pages, + &Address + ); + if (!EFI_ERROR (Status)) { + return (VOID*)(UINTN) Address; + } else { + return NULL; + } +} + + +VOID* +EFIAPI +LoadLinuxAllocateInitrdPages ( + IN VOID *KernelSetup, + IN UINTN Pages + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Address; + + struct boot_params *Bp; + + if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) { + return NULL; + } + + Bp =3D (struct boot_params*) KernelSetup; + + Address =3D (EFI_PHYSICAL_ADDRESS)(UINTN) Bp->hdr.ramdisk_max; + Status =3D gBS->AllocatePages ( + AllocateMaxAddress, + EfiLoaderData, + Pages, + &Address + ); + if (!EFI_ERROR (Status)) { + return (VOID*)(UINTN) Address; + } else { + return NULL; + } +} + + +STATIC +VOID +SetupLinuxMemmap ( + IN OUT struct boot_params *Bp + ) +{ + EFI_STATUS Status; + UINT8 TmpMemoryMap[1]; + UINTN MapKey; + UINTN DescriptorSize; + UINT32 DescriptorVersion; + UINTN MemoryMapSize; + EFI_MEMORY_DESCRIPTOR *MemoryMap; + EFI_MEMORY_DESCRIPTOR *MemoryMapPtr; + UINTN Index; + struct efi_info *Efi; + struct e820_entry *LastE820; + struct e820_entry *E820; + UINTN E820EntryCount; + EFI_PHYSICAL_ADDRESS LastEndAddr; + + // + // Get System MemoryMapSize + // + MemoryMapSize =3D sizeof (TmpMemoryMap); + Status =3D gBS->GetMemoryMap ( + &MemoryMapSize, + (EFI_MEMORY_DESCRIPTOR *)TmpMemoryMap, + &MapKey, + &DescriptorSize, + &DescriptorVersion + ); + ASSERT (Status =3D=3D EFI_BUFFER_TOO_SMALL); + // + // Enlarge space here, because we will allocate pool now. + // + MemoryMapSize +=3D EFI_PAGE_SIZE; + Status =3D gBS->AllocatePool ( + EfiLoaderData, + MemoryMapSize, + (VOID **) &MemoryMap + ); + ASSERT_EFI_ERROR (Status); + + // + // Get System MemoryMap + // + Status =3D gBS->GetMemoryMap ( + &MemoryMapSize, + MemoryMap, + &MapKey, + &DescriptorSize, + &DescriptorVersion + ); + ASSERT_EFI_ERROR (Status); + + LastE820 =3D NULL; + E820 =3D &Bp->e820_map[0]; + E820EntryCount =3D 0; + LastEndAddr =3D 0; + MemoryMapPtr =3D MemoryMap; + for (Index =3D 0; Index < (MemoryMapSize / DescriptorSize); Index++) { + UINTN E820Type =3D 0; + + if (MemoryMap->NumberOfPages =3D=3D 0) { + continue; + } + + switch(MemoryMap->Type) { + case EfiReservedMemoryType: + case EfiRuntimeServicesCode: + case EfiRuntimeServicesData: + case EfiMemoryMappedIO: + case EfiMemoryMappedIOPortSpace: + case EfiPalCode: + E820Type =3D E820_RESERVED; + break; + + case EfiUnusableMemory: + E820Type =3D E820_UNUSABLE; + break; + + case EfiACPIReclaimMemory: + E820Type =3D E820_ACPI; + break; + + case EfiLoaderCode: + case EfiLoaderData: + case EfiBootServicesCode: + case EfiBootServicesData: + case EfiConventionalMemory: + E820Type =3D E820_RAM; + break; + + case EfiACPIMemoryNVS: + E820Type =3D E820_NVS; + break; + + default: + DEBUG (( + EFI_D_ERROR, + "Invalid EFI memory descriptor type (0x%x)!\n", + MemoryMap->Type + )); + continue; + } + + if ((LastE820 !=3D NULL) && + (LastE820->type =3D=3D (UINT32) E820Type) && + (MemoryMap->PhysicalStart =3D=3D LastEndAddr)) { + LastE820->size +=3D EFI_PAGES_TO_SIZE ((UINTN) MemoryMap->NumberOfPa= ges); + LastEndAddr +=3D EFI_PAGES_TO_SIZE ((UINTN) MemoryMap->NumberOfPages= ); + } else { + if (E820EntryCount >=3D (sizeof (Bp->e820_map) / sizeof (Bp->e820_ma= p[0]))) { + break; + } + E820->type =3D (UINT32) E820Type; + E820->addr =3D MemoryMap->PhysicalStart; + E820->size =3D EFI_PAGES_TO_SIZE ((UINTN) MemoryMap->NumberOfPages); + LastE820 =3D E820; + LastEndAddr =3D E820->addr + E820->size; + E820++; + E820EntryCount++; + } + + // + // Get next item + // + MemoryMap =3D (EFI_MEMORY_DESCRIPTOR *)((UINTN)MemoryMap + DescriptorS= ize); + } + Bp->e820_entries =3D (UINT8) E820EntryCount; + + Efi =3D &Bp->efi_info; + Efi->efi_systab =3D (UINT32)(UINTN) gST; + Efi->efi_memdesc_size =3D (UINT32) DescriptorSize; + Efi->efi_memdesc_version =3D DescriptorVersion; + Efi->efi_memmap =3D (UINT32)(UINTN) MemoryMapPtr; + Efi->efi_memmap_size =3D (UINT32) MemoryMapSize; +#ifdef MDE_CPU_IA32 + Efi->efi_loader_signature =3D SIGNATURE_32 ('E', 'L', '3', '2'); +#else + Efi->efi_systab_hi =3D (UINT32) (((UINT64)(UINTN) gST) >> 32); + Efi->efi_memmap_hi =3D (UINT32) (((UINT64)(UINTN) MemoryMapPtr) >> 32); + Efi->efi_loader_signature =3D SIGNATURE_32 ('E', 'L', '6', '4'); +#endif + + gBS->ExitBootServices (gImageHandle, MapKey); +} + + +EFI_STATUS +EFIAPI +LoadLinuxSetCommandLine ( + IN OUT VOID *KernelSetup, + IN CHAR8 *CommandLine + ) +{ + EFI_STATUS Status; + struct boot_params *Bp; + + Status =3D BasicKernelSetupCheck (KernelSetup); + if (EFI_ERROR (Status)) { + return Status; + } + + Bp =3D (struct boot_params*) KernelSetup; + + Bp->hdr.cmd_line_ptr =3D (UINT32)(UINTN) CommandLine; + + return EFI_SUCCESS; +} + + +EFI_STATUS +EFIAPI +LoadLinuxSetInitrd ( + IN OUT VOID *KernelSetup, + IN VOID *Initrd, + IN UINTN InitrdSize + ) +{ + EFI_STATUS Status; + struct boot_params *Bp; + + Status =3D BasicKernelSetupCheck (KernelSetup); + if (EFI_ERROR (Status)) { + return Status; + } + + Bp =3D (struct boot_params*) KernelSetup; + + Bp->hdr.ramdisk_start =3D (UINT32)(UINTN) Initrd; + Bp->hdr.ramdisk_len =3D (UINT32) InitrdSize; + + return EFI_SUCCESS; +} + + +STATIC VOID +FindBits ( + unsigned long Mask, + UINT8 *Pos, + UINT8 *Size + ) +{ + UINT8 First, Len; + + First =3D 0; + Len =3D 0; + + if (Mask) { + while (!(Mask & 0x1)) { + Mask =3D Mask >> 1; + First++; + } + + while (Mask & 0x1) { + Mask =3D Mask >> 1; + Len++; + } + } + *Pos =3D First; + *Size =3D Len; +} + + +STATIC +EFI_STATUS +SetupGraphicsFromGop ( + struct screen_info *Si, + EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop + ) +{ + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; + EFI_STATUS Status; + UINTN Size; + + Status =3D Gop->QueryMode(Gop, Gop->Mode->Mode, &Size, &Info); + if (EFI_ERROR (Status)) { + return Status; + } + + /* We found a GOP */ + + /* EFI framebuffer */ + Si->orig_video_isVGA =3D 0x70; + + Si->orig_x =3D 0; + Si->orig_y =3D 0; + Si->orig_video_page =3D 0; + Si->orig_video_mode =3D 0; + Si->orig_video_cols =3D 0; + Si->orig_video_lines =3D 0; + Si->orig_video_ega_bx =3D 0; + Si->orig_video_points =3D 0; + + Si->lfb_base =3D (UINT32) Gop->Mode->FrameBufferBase; + Si->lfb_size =3D (UINT32) Gop->Mode->FrameBufferSize; + Si->lfb_width =3D (UINT16) Info->HorizontalResolution; + Si->lfb_height =3D (UINT16) Info->VerticalResolution; + Si->pages =3D 1; + Si->vesapm_seg =3D 0; + Si->vesapm_off =3D 0; + + if (Info->PixelFormat =3D=3D PixelRedGreenBlueReserved8BitPerColor) { + Si->lfb_depth =3D 32; + Si->red_size =3D 8; + Si->red_pos =3D 0; + Si->green_size =3D 8; + Si->green_pos =3D 8; + Si->blue_size =3D 8; + Si->blue_pos =3D 16; + Si->rsvd_size =3D 8; + Si->rsvd_pos =3D 24; + Si->lfb_linelength =3D (UINT16) (Info->PixelsPerScanLine * 4); + + } else if (Info->PixelFormat =3D=3D PixelBlueGreenRedReserved8BitPerColo= r) { + Si->lfb_depth =3D 32; + Si->red_size =3D 8; + Si->red_pos =3D 16; + Si->green_size =3D 8; + Si->green_pos =3D 8; + Si->blue_size =3D 8; + Si->blue_pos =3D 0; + Si->rsvd_size =3D 8; + Si->rsvd_pos =3D 24; + Si->lfb_linelength =3D (UINT16) (Info->PixelsPerScanLine * 4); + } else if (Info->PixelFormat =3D=3D PixelBitMask) { + FindBits(Info->PixelInformation.RedMask, + &Si->red_pos, &Si->red_size); + FindBits(Info->PixelInformation.GreenMask, + &Si->green_pos, &Si->green_size); + FindBits(Info->PixelInformation.BlueMask, + &Si->blue_pos, &Si->blue_size); + FindBits(Info->PixelInformation.ReservedMask, + &Si->rsvd_pos, &Si->rsvd_size); + Si->lfb_depth =3D Si->red_size + Si->green_size + + Si->blue_size + Si->rsvd_size; + Si->lfb_linelength =3D (UINT16) ((Info->PixelsPerScanLine * Si->lfb_de= pth) / 8); + } else { + Si->lfb_depth =3D 4; + Si->red_size =3D 0; + Si->red_pos =3D 0; + Si->green_size =3D 0; + Si->green_pos =3D 0; + Si->blue_size =3D 0; + Si->blue_pos =3D 0; + Si->rsvd_size =3D 0; + Si->rsvd_pos =3D 0; + Si->lfb_linelength =3D Si->lfb_width / 2; + } + + return Status; +} + + +STATIC +EFI_STATUS +SetupGraphics ( + IN OUT struct boot_params *Bp + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN HandleCount; + UINTN Index; + EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop; + + ZeroMem ((VOID*)&Bp->screen_info, sizeof(Bp->screen_info)); + + Status =3D gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiGraphicsOutputProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + if (!EFI_ERROR (Status)) { + for (Index =3D 0; Index < HandleCount; Index++) { + Status =3D gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiGraphicsOutputProtocolGuid, + (VOID*) &Gop + ); + if (EFI_ERROR (Status)) { + continue; + } + + Status =3D SetupGraphicsFromGop (&Bp->screen_info, Gop); + if (!EFI_ERROR (Status)) { + FreePool (HandleBuffer); + return EFI_SUCCESS; + } + } + + FreePool (HandleBuffer); + } + + return EFI_NOT_FOUND; +} + + +STATIC +EFI_STATUS +SetupLinuxBootParams ( + IN OUT struct boot_params *Bp + ) +{ + SetupGraphics (Bp); + + SetupLinuxMemmap (Bp); + + return EFI_SUCCESS; +} + + +EFI_STATUS +EFIAPI +LoadLinux ( + IN VOID *Kernel, + IN OUT VOID *KernelSetup + ) +{ + EFI_STATUS Status; + struct boot_params *Bp; + + Status =3D BasicKernelSetupCheck (KernelSetup); + if (EFI_ERROR (Status)) { + return Status; + } + + Bp =3D (struct boot_params *) KernelSetup; + + if (Bp->hdr.version < 0x205 || !Bp->hdr.relocatable_kernel) { + // + // We only support relocatable kernels + // + return EFI_UNSUPPORTED; + } + + InitLinuxDescriptorTables (); + + Bp->hdr.code32_start =3D (UINT32)(UINTN) Kernel; + if (Bp->hdr.version >=3D 0x20c && Bp->hdr.handover_offset && + (Bp->hdr.xloadflags & (sizeof (UINTN) =3D=3D 4 ? BIT2 : BIT3))) { + DEBUG ((EFI_D_INFO, "Jumping to kernel EFI handover point at ofs %x\n"= , Bp->hdr.handover_offset)); + + DisableInterrupts (); + JumpToUefiKernel ((VOID*) gImageHandle, (VOID*) gST, KernelSetup, Kern= el); + } + + // + // Old kernels without EFI handover protocol + // + SetupLinuxBootParams (KernelSetup); + + DEBUG ((EFI_D_INFO, "Jumping to kernel\n")); + DisableInterrupts (); + SetLinuxDescriptorTables (); + JumpToKernel (Kernel, (VOID*) KernelSetup); + + return EFI_SUCCESS; +} + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGd= t.c b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c new file mode 100644 index 0000000000..fda185e3d7 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c @@ -0,0 +1,175 @@ +/** @file + Initialize GDT for Linux. + + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "LoadLinuxLib.h" + + +// +// Local structure definitions +// + +#pragma pack (1) + +// +// Global Descriptor Entry structures +// + +typedef struct _GDT_ENTRY { + UINT16 Limit15_0; + UINT16 Base15_0; + UINT8 Base23_16; + UINT8 Type; + UINT8 Limit19_16_and_flags; + UINT8 Base31_24; +} GDT_ENTRY; + +typedef +struct _GDT_ENTRIES { + GDT_ENTRY Null; + GDT_ENTRY Null2; + GDT_ENTRY Linear; + GDT_ENTRY LinearCode; + GDT_ENTRY TaskSegment; + GDT_ENTRY Spare4; + GDT_ENTRY Spare5; +} GDT_ENTRIES; + +#pragma pack () + +STATIC GDT_ENTRIES *mGdt =3D NULL; + +// +// Global descriptor table (GDT) Template +// +STATIC GDT_ENTRIES GdtTemplate =3D { + // + // Null + // + { + 0x0, // limit 15:0 + 0x0, // base 15:0 + 0x0, // base 23:16 + 0x0, // type + 0x0, // limit 19:16, flags + 0x0, // base 31:24 + }, + // + // Null2 + // + { + 0x0, // limit 15:0 + 0x0, // base 15:0 + 0x0, // base 23:16 + 0x0, // type + 0x0, // limit 19:16, flags + 0x0, // base 31:24 + }, + // + // Linear + // + { + 0x0FFFF, // limit 0xFFFFF + 0x0, // base 0 + 0x0, + 0x09A, // present, ring 0, data, expand-up, writable + 0x0CF, // page-granular, 32-bit + 0x0, + }, + // + // LinearCode + // + { + 0x0FFFF, // limit 0xFFFFF + 0x0, // base 0 + 0x0, + 0x092, // present, ring 0, data, expand-up, writable + 0x0CF, // page-granular, 32-bit + 0x0, + }, + // + // TaskSegment + // + { + 0x0, // limit 0 + 0x0, // base 0 + 0x0, + 0x089, // ? + 0x080, // ? + 0x0, + }, + // + // Spare4 + // + { + 0x0, // limit 0 + 0x0, // base 0 + 0x0, + 0x0, // present, ring 0, data, expand-up, writable + 0x0, // page-granular, 32-bit + 0x0, + }, + // + // Spare5 + // + { + 0x0, // limit 0 + 0x0, // base 0 + 0x0, + 0x0, // present, ring 0, data, expand-up, writable + 0x0, // page-granular, 32-bit + 0x0, + }, +}; + +/** + Initialize Global Descriptor Table. + +**/ +VOID +InitLinuxDescriptorTables ( + VOID + ) +{ + // + // Allocate Runtime Data for the GDT + // + mGdt =3D AllocateRuntimePool (sizeof (GdtTemplate) + 8); + ASSERT (mGdt !=3D NULL); + mGdt =3D ALIGN_POINTER (mGdt, 8); + + // + // Initialize all GDT entries + // + CopyMem (mGdt, &GdtTemplate, sizeof (GdtTemplate)); + +} + +/** + Initialize Global Descriptor Table. + +**/ +VOID +SetLinuxDescriptorTables ( + VOID + ) +{ + IA32_DESCRIPTOR GdtPtr; + IA32_DESCRIPTOR IdtPtr; + + // + // Write GDT register + // + GdtPtr.Base =3D (UINT32)(UINTN)(VOID*) mGdt; + GdtPtr.Limit =3D (UINT16) (sizeof (GdtTemplate) - 1); + AsmWriteGdtr (&GdtPtr); + + IdtPtr.Base =3D (UINT32) 0; + IdtPtr.Limit =3D (UINT16) 0; + AsmWriteIdtr (&IdtPtr); +} + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAcce= ss.c b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c new file mode 100644 index 0000000000..3d98291410 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c @@ -0,0 +1,507 @@ +/** @file + File System Access for NvVarsFileLib + + Copyright (c) 2004 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "NvVarsFileLib.h" + +#include +#include +#include + + +/** + Open the NvVars file for reading or writing + + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid ins= tance + @param[in] ReadingFile - TRUE: open the file for reading. FALSE: writi= ng + @param[out] NvVarsFile - If EFI_SUCCESS is returned, then this is updated + with the opened NvVars file. + + @return EFI_SUCCESS if the file was opened + +**/ +EFI_STATUS +GetNvVarsFile ( + IN EFI_HANDLE FsHandle, + IN BOOLEAN ReadingFile, + OUT EFI_FILE_HANDLE *NvVarsFile + ) +{ + EFI_STATUS Status; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs; + EFI_FILE_HANDLE Root; + + // + // Get the FileSystem protocol on that handle + // + Status =3D gBS->HandleProtocol ( + FsHandle, + &gEfiSimpleFileSystemProtocolGuid, + (VOID **)&Fs + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get the volume (the root directory) + // + Status =3D Fs->OpenVolume (Fs, &Root); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Attempt to open the NvVars file in the root directory + // + Status =3D Root->Open ( + Root, + NvVarsFile, + L"NvVars", + ReadingFile ? + EFI_FILE_MODE_READ : + ( + EFI_FILE_MODE_CREATE | + EFI_FILE_MODE_READ | + EFI_FILE_MODE_WRITE + ), + 0 + ); + + return Status; +} + + +/** + Open the NvVars file for reading or writing + + @param[in] File - The file to inspect + @param[out] Exists - Returns whether the file exists + @param[out] Size - Returns the size of the file + (0 if the file does not exist) + +**/ +VOID +NvVarsFileReadCheckup ( + IN EFI_FILE_HANDLE File, + OUT BOOLEAN *Exists, + OUT UINTN *Size + ) +{ + EFI_FILE_INFO *FileInfo; + + *Exists =3D FALSE; + *Size =3D 0; + + FileInfo =3D FileHandleGetInfo (File); + if (FileInfo =3D=3D NULL) { + return; + } + + if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) !=3D 0) { + FreePool (FileInfo); + return; + } + + *Exists =3D TRUE; + *Size =3D (UINTN) FileInfo->FileSize; + + FreePool (FileInfo); +} + + +/** + Open the NvVars file for reading or writing + + @param[in] File - The file to inspect + @param[out] Exists - Returns whether the file exists + @param[out] Size - Returns the size of the file + (0 if the file does not exist) + +**/ +EFI_STATUS +FileHandleEmpty ( + IN EFI_FILE_HANDLE File + ) +{ + EFI_STATUS Status; + EFI_FILE_INFO *FileInfo; + + // + // Retrieve the FileInfo structure + // + FileInfo =3D FileHandleGetInfo (File); + if (FileInfo =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // If the path is a directory, then return an error + // + if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) !=3D 0) { + FreePool (FileInfo); + return EFI_INVALID_PARAMETER; + } + + // + // If the file size is already 0, then it is empty, so + // we can return success. + // + if (FileInfo->FileSize =3D=3D 0) { + FreePool (FileInfo); + return EFI_SUCCESS; + } + + // + // Set the file size to 0. + // + FileInfo->FileSize =3D 0; + Status =3D FileHandleSetInfo (File, FileInfo); + + FreePool (FileInfo); + + return Status; +} + + +/** + Reads a file to a newly allocated buffer + + @param[in] File - The file to read + @param[in] ReadSize - The size of data to read from the file + + @return Pointer to buffer allocated to hold the file + contents. NULL if an error occurred. + +**/ +VOID* +FileHandleReadToNewBuffer ( + IN EFI_FILE_HANDLE FileHandle, + IN UINTN ReadSize + ) +{ + EFI_STATUS Status; + UINTN ActualReadSize; + VOID *FileContents; + + ActualReadSize =3D ReadSize; + FileContents =3D AllocatePool (ReadSize); + if (FileContents !=3D NULL) { + Status =3D FileHandleRead ( + FileHandle, + &ReadSize, + FileContents + ); + if (EFI_ERROR (Status) || (ActualReadSize !=3D ReadSize)) { + FreePool (FileContents); + return NULL; + } + } + + return FileContents; +} + + +/** + Reads the contents of the NvVars file on the file system + + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid ins= tance + + @return EFI_STATUS based on the success or failure of the file read + +**/ +EFI_STATUS +ReadNvVarsFile ( + IN EFI_HANDLE FsHandle + ) +{ + EFI_STATUS Status; + EFI_FILE_HANDLE File; + UINTN FileSize; + BOOLEAN FileExists; + VOID *FileContents; + EFI_HANDLE SerializedVariables; + + Status =3D GetNvVarsFile (FsHandle, TRUE, &File); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_INFO, "FsAccess.c: Could not open NV Variables file on t= his file system\n")); + return Status; + } + + NvVarsFileReadCheckup (File, &FileExists, &FileSize); + if (FileSize =3D=3D 0) { + FileHandleClose (File); + return EFI_UNSUPPORTED; + } + + FileContents =3D FileHandleReadToNewBuffer (File, FileSize); + if (FileContents =3D=3D NULL) { + FileHandleClose (File); + return EFI_UNSUPPORTED; + } + + DEBUG (( + EFI_D_INFO, + "FsAccess.c: Read %Lu bytes from NV Variables file\n", + (UINT64)FileSize + )); + + Status =3D SerializeVariablesNewInstanceFromBuffer ( + &SerializedVariables, + FileContents, + FileSize + ); + if (!RETURN_ERROR (Status)) { + Status =3D SerializeVariablesSetSerializedVariables (SerializedVariabl= es); + } + + FreePool (FileContents); + FileHandleClose (File); + + return Status; +} + + +/** + Writes a variable to indicate that the NV variables + have been loaded from the file system. + +**/ +STATIC +VOID +SetNvVarsVariable ( + VOID + ) +{ + BOOLEAN VarData; + UINTN Size; + + // + // Write a variable to indicate we've already loaded the + // variable data. If it is found, we skip the loading on + // subsequent attempts. + // + Size =3D sizeof (VarData); + VarData =3D TRUE; + gRT->SetVariable ( + L"NvVars", + &gEfiSimpleFileSystemProtocolGuid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + Size, + (VOID*) &VarData + ); +} + + +/** + Loads the non-volatile variables from the NvVars file on the + given file system. + + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid ins= tance + + @return EFI_STATUS based on the success or failure of load operation + +**/ +EFI_STATUS +LoadNvVarsFromFs ( + EFI_HANDLE FsHandle + ) +{ + EFI_STATUS Status; + BOOLEAN VarData; + UINTN Size; + + DEBUG ((EFI_D_INFO, "FsAccess.c: LoadNvVarsFromFs\n")); + + // + // We write a variable to indicate we've already loaded the + // variable data. If it is found, we skip the loading. + // + // This is relevant if the non-volatile variable have been + // able to survive a reboot operation. In that case, we don't + // want to re-load the file as it would overwrite newer changes + // made to the variables. + // + Size =3D sizeof (VarData); + VarData =3D TRUE; + Status =3D gRT->GetVariable ( + L"NvVars", + &gEfiSimpleFileSystemProtocolGuid, + NULL, + &Size, + (VOID*) &VarData + ); + if (Status =3D=3D EFI_SUCCESS) { + DEBUG ((EFI_D_INFO, "NV Variables were already loaded\n")); + return EFI_ALREADY_STARTED; + } + + // + // Attempt to restore the variables from the NvVars file. + // + Status =3D ReadNvVarsFile (FsHandle); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_INFO, "Error while restoring NV variable data\n")); + return Status; + } + + // + // Write a variable to indicate we've already loaded the + // variable data. If it is found, we skip the loading on + // subsequent attempts. + // + SetNvVarsVariable(); + + DEBUG (( + EFI_D_INFO, + "FsAccess.c: Read NV Variables file (size=3D%Lu)\n", + (UINT64)Size + )); + + return Status; +} + + +STATIC +RETURN_STATUS +EFIAPI +IterateVariablesCallbackAddAllNvVariables ( + IN VOID *Context, + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ) +{ + EFI_HANDLE Instance; + + Instance =3D (EFI_HANDLE) Context; + + // + // Only save non-volatile variables + // + if ((Attributes & EFI_VARIABLE_NON_VOLATILE) =3D=3D 0) { + return RETURN_SUCCESS; + } + + return SerializeVariablesAddVariable ( + Instance, + VariableName, + VendorGuid, + Attributes, + DataSize, + Data + ); +} + + +/** + Saves the non-volatile variables into the NvVars file on the + given file system. + + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid ins= tance + + @return EFI_STATUS based on the success or failure of load operation + +**/ +EFI_STATUS +SaveNvVarsToFs ( + EFI_HANDLE FsHandle + ) +{ + EFI_STATUS Status; + EFI_FILE_HANDLE File; + UINTN WriteSize; + UINTN VariableDataSize; + VOID *VariableData; + EFI_HANDLE SerializedVariables; + + SerializedVariables =3D NULL; + + Status =3D SerializeVariablesNewInstance (&SerializedVariables); + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D SerializeVariablesIterateSystemVariables ( + IterateVariablesCallbackAddAllNvVariables, + (VOID*) SerializedVariables + ); + if (EFI_ERROR (Status)) { + return Status; + } + + VariableData =3D NULL; + VariableDataSize =3D 0; + Status =3D SerializeVariablesToBuffer ( + SerializedVariables, + NULL, + &VariableDataSize + ); + if (Status =3D=3D RETURN_BUFFER_TOO_SMALL) { + VariableData =3D AllocatePool (VariableDataSize); + if (VariableData =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + } else { + Status =3D SerializeVariablesToBuffer ( + SerializedVariables, + VariableData, + &VariableDataSize + ); + } + } + + SerializeVariablesFreeInstance (SerializedVariables); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Open the NvVars file for writing. + // + Status =3D GetNvVarsFile (FsHandle, FALSE, &File); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_INFO, "FsAccess.c: Unable to open file to saved NV Varia= bles\n")); + return Status; + } + + // + // Empty the starting file contents. + // + Status =3D FileHandleEmpty (File); + if (EFI_ERROR (Status)) { + FileHandleClose (File); + return Status; + } + + WriteSize =3D VariableDataSize; + Status =3D FileHandleWrite (File, &WriteSize, VariableData); + if (EFI_ERROR (Status)) { + return Status; + } + + FileHandleClose (File); + + if (!EFI_ERROR (Status)) { + // + // Write a variable to indicate we've already loaded the + // variable data. If it is found, we skip the loading on + // subsequent attempts. + // + SetNvVarsVariable(); + + DEBUG ((EFI_D_INFO, "Saved NV Variables to NvVars file\n")); + } + + return Status; +} + + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVars= FileLib.c b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsF= ileLib.c new file mode 100644 index 0000000000..2e9618455d --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib= .c @@ -0,0 +1,77 @@ +/** @file + Save Non-Volatile Variables to a file system. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "NvVarsFileLib.h" +#include +#include + +EFI_HANDLE mNvVarsFileLibFsHandle =3D NULL; + + +/** + Attempts to connect the NvVarsFileLib to the specified file system. + + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid ins= tance + + @return The EFI_STATUS while attempting to connect the NvVarsFileLib + to the file system instance. + @retval EFI_SUCCESS - The given file system was connected successful= ly + +**/ +EFI_STATUS +EFIAPI +ConnectNvVarsToFileSystem ( + IN EFI_HANDLE FsHandle + ) +{ + EFI_STATUS Status; + + // + // We might fail to load the variable, since the file system initially + // will not have the NvVars file. + // + LoadNvVarsFromFs (FsHandle); + + // + // We must be able to save the variables successfully to the file system + // to have connected successfully. + // + Status =3D SaveNvVarsToFs (FsHandle); + if (!EFI_ERROR (Status)) { + mNvVarsFileLibFsHandle =3D FsHandle; + } + + return Status; +} + + +/** + Update non-volatile variables stored on the file system. + + @return The EFI_STATUS while attempting to update the variable on + the connected file system. + @retval EFI_SUCCESS - The non-volatile variables were saved to the d= isk + @retval EFI_NOT_STARTED - A file system has not been connected + +**/ +EFI_STATUS +EFIAPI +UpdateNvVarsOnFileSystem ( + ) +{ + if (mNvVarsFileLibFsHandle =3D=3D NULL) { + // + // A file system had not been connected to the library. + // + return EFI_NOT_STARTED; + } else { + return SaveNvVarsToFs (mNvVarsFileLibFsHandle); + } +} + + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/Pci= HostBridgeLib.c b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLi= b/PciHostBridgeLib.c new file mode 100644 index 0000000000..3b71c8ae97 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBri= dgeLib.c @@ -0,0 +1,419 @@ +/** @file + SIMICS QSP's instance of the PCI Host Bridge Library. + + Copyright (C) 2016, Red Hat, Inc. + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include "PciHostBridge.h" + + +#pragma pack(1) +typedef struct { + ACPI_HID_DEVICE_PATH AcpiDevicePath; + EFI_DEVICE_PATH_PROTOCOL EndDevicePath; +} OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH; +#pragma pack () + + +GLOBAL_REMOVE_IF_UNREFERENCED +CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] =3D { + L"Mem", L"I/O", L"Bus" +}; + + +STATIC +CONST +OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH mRootBridgeDevicePathTemplate =3D { + { + { + ACPI_DEVICE_PATH, + ACPI_DP, + { + (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)), + (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8) + } + }, + EISA_PNP_ID(0x0A03), // HID + 0 // UID + }, + + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + END_DEVICE_PATH_LENGTH, + 0 + } + } +}; + +STATIC PCI_ROOT_BRIDGE_APERTURE mNonExistAperture =3D { MAX_UINT64, 0 }; + +/** + Initialize a PCI_ROOT_BRIDGE structure. + + @param[in] Supports Supported attributes. + + @param[in] Attributes Initial attributes. + + @param[in] AllocAttributes Allocation attributes. + + @param[in] RootBusNumber The bus number to store in RootBus. + + @param[in] MaxSubBusNumber The inclusive maximum bus number that can be + assigned to any subordinate bus found behin= d any + PCI bridge hanging off this root bus. + + The caller is repsonsible for ensuring that + RootBusNumber <=3D MaxSubBusNumber. If + RootBusNumber equals MaxSubBusNumber, then = the + root bus has no room for subordinate buses. + + @param[in] Io IO aperture. + + @param[in] Mem MMIO aperture. + + @param[in] MemAbove4G MMIO aperture above 4G. + + @param[in] PMem Prefetchable MMIO aperture. + + @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G. + + @param[out] RootBus The PCI_ROOT_BRIDGE structure (allocated by= the + caller) that should be filled in by this + function. + + @retval EFI_SUCCESS Initialization successful. A device path + consisting of an ACPI device path node, wi= th + UID =3D RootBusNumber, has been allocated = and + linked into RootBus. + + @retval EFI_OUT_OF_RESOURCES Memory allocation failed. +**/ +EFI_STATUS +InitRootBridge ( + IN UINT64 Supports, + IN UINT64 Attributes, + IN UINT64 AllocAttributes, + IN UINT8 RootBusNumber, + IN UINT8 MaxSubBusNumber, + IN PCI_ROOT_BRIDGE_APERTURE *Io, + IN PCI_ROOT_BRIDGE_APERTURE *Mem, + IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G, + IN PCI_ROOT_BRIDGE_APERTURE *PMem, + IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G, + OUT PCI_ROOT_BRIDGE *RootBus + ) +{ + OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH *DevicePath; + + // + // Be safe if other fields are added to PCI_ROOT_BRIDGE later. + // + ZeroMem (RootBus, sizeof *RootBus); + + RootBus->Segment =3D 0; + + RootBus->Supports =3D Supports; + RootBus->Attributes =3D Attributes; + + RootBus->DmaAbove4G =3D FALSE; + + RootBus->AllocationAttributes =3D AllocAttributes; + RootBus->Bus.Base =3D RootBusNumber; + RootBus->Bus.Limit =3D MaxSubBusNumber; + CopyMem (&RootBus->Io, Io, sizeof (*Io)); + CopyMem (&RootBus->Mem, Mem, sizeof (*Mem)); + CopyMem (&RootBus->MemAbove4G, MemAbove4G, sizeof (*MemAbove4G)); + CopyMem (&RootBus->PMem, PMem, sizeof (*PMem)); + CopyMem (&RootBus->PMemAbove4G, PMemAbove4G, sizeof (*PMemAbove4G)); + + RootBus->NoExtendedConfigSpace =3D (PcdGet16 (PcdSimicsX58HostBridgePciD= evId) !=3D + INTEL_ICH10_DEVICE_ID); + + DevicePath =3D AllocateCopyPool (sizeof mRootBridgeDevicePathTemplate, + &mRootBridgeDevicePathTemplate); + if (DevicePath =3D=3D NULL) { + DEBUG ((EFI_D_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES)); + return EFI_OUT_OF_RESOURCES; + } + DevicePath->AcpiDevicePath.UID =3D RootBusNumber; + RootBus->DevicePath =3D (EFI_DEVICE_PATH_PROTOCOL *)DevicePath; + + DEBUG ((EFI_D_INFO, + "%a: populated root bus %d, with room for %d subordinate bus(es)\n", + __FUNCTION__, RootBusNumber, MaxSubBusNumber - RootBusNumber)); + return EFI_SUCCESS; +} + + +/** + Uninitialize a PCI_ROOT_BRIDGE structure set up with InitRootBridge(). + + param[in] RootBus The PCI_ROOT_BRIDGE structure, allocated by the calle= r and + initialized with InitRootBridge(), that should be + uninitialized. This function doesn't free RootBus. +**/ +STATIC +VOID +UninitRootBridge ( + IN PCI_ROOT_BRIDGE *RootBus + ) +{ + FreePool (RootBus->DevicePath); +} + + +/** + Return all the root bridge instances in an array. + + @param Count Return the count of root bridge instances. + + @return All the root bridge instances in an array. + The array should be passed into PciHostBridgeFreeRootBridges() + when it's not used. +**/ +PCI_ROOT_BRIDGE * +EFIAPI +PciHostBridgeGetRootBridges ( + UINTN *Count + ) +{ + EFI_STATUS Status; + UINT64 ExtraRootBridges; + PCI_ROOT_BRIDGE *Bridges; + UINTN Initialized; + UINTN LastRootBridgeNumber; + UINTN RootBridgeNumber; + UINT64 Attributes; + UINT64 AllocationAttributes; + PCI_ROOT_BRIDGE_APERTURE Io; + PCI_ROOT_BRIDGE_APERTURE Mem; + PCI_ROOT_BRIDGE_APERTURE MemAbove4G; + + ZeroMem (&Io, sizeof (Io)); + ZeroMem (&Mem, sizeof (Mem)); + ZeroMem (&MemAbove4G, sizeof (MemAbove4G)); + + Attributes =3D EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO | + EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO | + EFI_PCI_ATTRIBUTE_ISA_IO_16 | + EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO | + EFI_PCI_ATTRIBUTE_VGA_MEMORY | + EFI_PCI_ATTRIBUTE_VGA_IO_16 | + EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16; + + AllocationAttributes =3D EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM; + if (PcdGet64 (PcdPciMmio64Size) > 0) { + AllocationAttributes |=3D EFI_PCI_HOST_BRIDGE_MEM64_DECODE; + MemAbove4G.Base =3D PcdGet64 (PcdPciMmio64Base); + MemAbove4G.Limit =3D PcdGet64 (PcdPciMmio64Base) + + PcdGet64 (PcdPciMmio64Size) - 1; + } else { + CopyMem (&MemAbove4G, &mNonExistAperture, sizeof (mNonExistAperture)); + } + + Io.Base =3D PcdGet64 (PcdPciIoBase); + Io.Limit =3D PcdGet64 (PcdPciIoBase) + (PcdGet64 (PcdPciIoSize) - 1); + Mem.Base =3D PcdGet64 (PcdPciMmio32Base); + Mem.Limit =3D PcdGet64 (PcdPciMmio32Base) + (PcdGet64 (PcdPciMmio32Size)= - 1); + + *Count =3D 0; + ExtraRootBridges =3D 0; + + // + // Allocate the "main" root bridge, and any extra root bridges. + // + Bridges =3D AllocatePool ((1 + (UINTN)ExtraRootBridges) * sizeof *Bridge= s); + if (Bridges =3D=3D NULL) { + DEBUG ((EFI_D_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES)); + return NULL; + } + Initialized =3D 0; + + // + // The "main" root bus is always there. + // + LastRootBridgeNumber =3D 0; + + // + // Scan all other root buses. If function 0 of any device on a bus retur= ns a + // VendorId register value different from all-bits-one, then that bus is + // alive. + // + for (RootBridgeNumber =3D 1; + RootBridgeNumber <=3D PCI_MAX_BUS && Initialized < ExtraRootBridges; + ++RootBridgeNumber) { + UINTN Device; + + for (Device =3D 0; Device <=3D PCI_MAX_DEVICE; ++Device) { + if (PciRead16 (PCI_LIB_ADDRESS (RootBridgeNumber, Device, 0, + PCI_VENDOR_ID_OFFSET)) !=3D MAX_UINT16) { + break; + } + } + if (Device <=3D PCI_MAX_DEVICE) { + // + // Found the next root bus. We can now install the *previous* one, + // because now we know how big a bus number range *that* one has, fo= r any + // subordinate buses that might exist behind PCI bridges hanging off= it. + // + Status =3D InitRootBridge ( + Attributes, + Attributes, + AllocationAttributes, + (UINT8) LastRootBridgeNumber, + (UINT8) (RootBridgeNumber - 1), + &Io, + &Mem, + &MemAbove4G, + &mNonExistAperture, + &mNonExistAperture, + &Bridges[Initialized] + ); + if (EFI_ERROR (Status)) { + goto FreeBridges; + } + ++Initialized; + LastRootBridgeNumber =3D RootBridgeNumber; + } + } + + // + // Install the last root bus (which might be the only, ie. main, root bu= s, if + // we've found no extra root buses). + // + Status =3D InitRootBridge ( + Attributes, + Attributes, + AllocationAttributes, + (UINT8) LastRootBridgeNumber, + PCI_MAX_BUS, + &Io, + &Mem, + &MemAbove4G, + &mNonExistAperture, + &mNonExistAperture, + &Bridges[Initialized] + ); + if (EFI_ERROR (Status)) { + goto FreeBridges; + } + ++Initialized; + + *Count =3D Initialized; + return Bridges; + +FreeBridges: + while (Initialized > 0) { + --Initialized; + UninitRootBridge (&Bridges[Initialized]); + } + + FreePool (Bridges); + return NULL; +} + + +/** + Free the root bridge instances array returned from + PciHostBridgeGetRootBridges(). + + @param The root bridge instances array. + @param The count of the array. +**/ +VOID +EFIAPI +PciHostBridgeFreeRootBridges ( + PCI_ROOT_BRIDGE *Bridges, + UINTN Count + ) +{ + if (Bridges =3D=3D NULL && Count =3D=3D 0) { + return; + } + ASSERT (Bridges !=3D NULL && Count > 0); + + do { + --Count; + UninitRootBridge (&Bridges[Count]); + } while (Count > 0); + + FreePool (Bridges); +} + + +/** + Inform the platform that the resource conflict happens. + + @param HostBridgeHandle Handle of the Host Bridge. + @param Configuration Pointer to PCI I/O and PCI memory resource + descriptors. The Configuration contains the reso= urces + for all the root bridges. The resource for each = root + bridge is terminated with END descriptor and an + additional END is appended indicating the end of= the + entire resources. The resource descriptor field + values follow the description in + EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL + .SubmitResources(). +**/ +VOID +EFIAPI +PciHostBridgeResourceConflict ( + EFI_HANDLE HostBridgeHandle, + VOID *Configuration + ) +{ + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor; + UINTN RootBridgeIndex; + DEBUG ((EFI_D_ERROR, "PciHostBridge: Resource conflict happens!\n")); + + RootBridgeIndex =3D 0; + Descriptor =3D (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration; + while (Descriptor->Desc =3D=3D ACPI_ADDRESS_SPACE_DESCRIPTOR) { + DEBUG ((EFI_D_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++)); + for (; Descriptor->Desc =3D=3D ACPI_ADDRESS_SPACE_DESCRIPTOR; Descript= or++) { + ASSERT (Descriptor->ResType < + (sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr) / + sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr[0]) + ) + ); + DEBUG ((EFI_D_ERROR, " %s: Length/Alignment =3D 0x%lx / 0x%lx\n", + mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType= ], + Descriptor->AddrLen, Descriptor->AddrRangeMax + )); + if (Descriptor->ResType =3D=3D ACPI_ADDRESS_SPACE_TYPE_MEM) { + DEBUG ((EFI_D_ERROR, " Granularity/SpecificFlag =3D %ld / %02x= %s\n", + Descriptor->AddrSpaceGranularity, Descriptor->SpecificFlag, + ((Descriptor->SpecificFlag & + EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETC= HABLE + ) !=3D 0) ? L" (Prefetchable)" : L"" + )); + } + } + // + // Skip the END descriptor for root bridge + // + ASSERT (Descriptor->Desc =3D=3D ACPI_END_TAG_DESCRIPTOR); + Descriptor =3D (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)( + (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1 + ); + } +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/Fv.c = b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/Fv.c new file mode 100644 index 0000000000..4e3762465a --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/Fv.c @@ -0,0 +1,100 @@ +/** @file + Build FV related hobs for platform. + + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "PiPei.h" +#include +#include +#include +#include + +BOOLEAN mS3Supported =3D TRUE; + +/** + Publish PEI & DXE (Decompressed) Memory based FVs to let PEI + and DXE know about them. + + @retval EFI_SUCCESS Platform PEI FVs were initialized successfully. + +**/ +EFI_STATUS +PeiFvInitialization ( + VOID + ) +{ + BOOLEAN SecureS3Needed; + + DEBUG ((EFI_D_INFO, "Platform PEI Firmware Volume Initialization\n")); + + DEBUG ( + (EFI_D_ERROR, "Firmware Volume HOB: 0x%x 0x%x\n", + PcdGet32 (PcdSimicsPeiMemFvBase), + PcdGet32 (PcdSimicsPeiMemFvSize) + ) + ); + // + // Create a memory allocation HOB for the PEI FV. + // + // Allocate as ACPI NVS is S3 is supported + // + BuildMemoryAllocationHob ( + PcdGet32 (PcdSimicsPeiMemFvBase), + PcdGet32 (PcdSimicsPeiMemFvSize), + mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData + ); + + // + // Let DXE know about the DXE FV + // + BuildFvHob (PcdGet32 (PcdSimicsDxeMemFvBase), PcdGet32 (PcdSimicsDxeMemF= vSize)); + + SecureS3Needed =3D mS3Supported && FeaturePcdGet (PcdSmmSmramRequire); + + // + // Create a memory allocation HOB for the DXE FV. + // + // If "secure" S3 is needed, then SEC will decompress both PEI and DXE + // firmware volumes at S3 resume too, hence we need to keep away the OS = from + // DXEFV as well. Otherwise we only need to keep away DXE itself from the + // DXEFV area. + // + BuildMemoryAllocationHob ( + PcdGet32 (PcdSimicsDxeMemFvBase), + PcdGet32 (PcdSimicsDxeMemFvSize), + SecureS3Needed ? EfiACPIMemoryNVS : EfiBootServicesData + ); + + // + // Additionally, said decompression will use temporary memory above the = end + // of DXEFV, so let's keep away the OS from there too. + // + if (SecureS3Needed) { + UINT32 DxeMemFvEnd; + + DxeMemFvEnd =3D PcdGet32 (PcdSimicsDxeMemFvBase) + + PcdGet32 (PcdSimicsDxeMemFvSize); + BuildMemoryAllocationHob ( + DxeMemFvEnd, + PcdGet32 (PcdSimicsDecompressionScratchEnd) - DxeMemFvEnd, + EfiACPIMemoryNVS + ); + } + + // + // Let PEI know about the DXE FV so it can find the DXE Core + // + PeiServicesInstallFvInfoPpi ( + NULL, + (VOID *)(UINTN) PcdGet32 (PcdSimicsDxeMemFvBase), + PcdGet32 (PcdSimicsDxeMemFvSize), + NULL, + NULL + ); + + return EFI_SUCCESS; +} + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiRe= portFvLib.c b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiR= eportFvLib.c new file mode 100644 index 0000000000..bb5a060b8e --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvL= ib.c @@ -0,0 +1,119 @@ +/** @file + Source code file for Report Firmware Volume (FV) library + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +EFI_STATUS +PeiFvInitialization( + VOID +); + +VOID +ReportPreMemFv ( + VOID + ) +{ + if (IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12) !=3D 0x5) { // not S3 = resume + PeiFvInitialization(); + } + + DEBUG ((DEBUG_INFO, "Install FlashFvSecurity - 0x%x, 0x%x\n", PcdGet32 (= PcdFlashFvSecurityBase), PcdGet32 (PcdFlashFvSecuritySize))); + PeiServicesInstallFvInfo2Ppi ( + &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvSecurity= Base))->FileSystemGuid), + (VOID *) (UINTN) PcdGet32 (PcdFlashFvSecurityBase), + PcdGet32 (PcdFlashFvSecuritySize), + NULL, + NULL, + 0 + ); + DEBUG ((DEBUG_INFO, "Install FlashFvAdvanced - 0x%x, 0x%x\n", PcdGet32 (= PcdFlashFvAdvancedBase), PcdGet32 (PcdFlashFvAdvancedSize))); + PeiServicesInstallFvInfo2Ppi ( + &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvAdvanced= Base))->FileSystemGuid), + (VOID *) (UINTN) PcdGet32 (PcdFlashFvAdvancedBase), + PcdGet32 (PcdFlashFvAdvancedSize), + NULL, + NULL, + 0 + ); +} + +VOID +ReportPostMemFv ( + VOID + ) +{ + EFI_STATUS Status; + EFI_BOOT_MODE BootMode; + + Status =3D PeiServicesGetBootMode (&BootMode); + ASSERT_EFI_ERROR (Status); + + /// + /// Build HOB for DXE + /// + if (BootMode =3D=3D BOOT_IN_RECOVERY_MODE) { + /// + /// Prepare the recovery service + /// + } else { + DEBUG ((DEBUG_INFO, "Install FlashFvPostMemory - 0x%x, 0x%x\n", PcdGet= 32 (PcdFlashFvPostMemoryBase), PcdGet32 (PcdFlashFvPostMemorySize))); + PeiServicesInstallFvInfo2Ppi ( + &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvPostMe= moryBase))->FileSystemGuid), + (VOID *) (UINTN) PcdGet32 (PcdFlashFvPostMemoryBase), + PcdGet32 (PcdFlashFvPostMemorySize), + NULL, + NULL, + 0 + ); + DEBUG ((DEBUG_INFO, "Install FlashFvUefiBoot - 0x%x, 0x%x\n", PcdGet32= (PcdFlashFvUefiBootBase), PcdGet32 (PcdFlashFvUefiBootSize))); + PeiServicesInstallFvInfo2Ppi ( + &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvUefiBo= otBase))->FileSystemGuid), + (VOID *) (UINTN) PcdGet32 (PcdFlashFvUefiBootBase), + PcdGet32 (PcdFlashFvUefiBootSize), + NULL, + NULL, + 0 + ); + DEBUG ((DEBUG_INFO, "Install FlashFvOsBoot - 0x%x, 0x%x\n", PcdGet32 (= PcdFlashFvOsBootBase), PcdGet32 (PcdFlashFvOsBootSize))); + PeiServicesInstallFvInfo2Ppi ( + &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvOsBoot= Base))->FileSystemGuid), + (VOID *) (UINTN) PcdGet32 (PcdFlashFvOsBootBase), + PcdGet32 (PcdFlashFvOsBootSize), + NULL, + NULL, + 0 + ); + } + + // + // Report resource HOB for flash FV + // + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + (UINTN) PcdGet32 (PcdFlashAreaBaseAddress), + (UINTN) PcdGet32 (PcdFlashAreaSize) + ); + BuildMemoryAllocationHob ( + (UINTN) PcdGet32 (PcdFlashAreaBaseAddress), + (UINTN) PcdGet32 (PcdFlashAreaSize), + EfiMemoryMappedIO + ); +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerL= ib/BdsPlatform.c b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootMa= nagerLib/BdsPlatform.c new file mode 100644 index 0000000000..117c72b35f --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsP= latform.c @@ -0,0 +1,1553 @@ +/** @file + Platform BDS customizations. + + Copyright (c) 2004 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "BdsPlatform.h" +#include +#include + +#define LEGACY_8259_MASK_REGISTER_MASTER 0x21 +#define LEGACY_8259_MASK_REGISTER_SLAVE 0xA1 +#define LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER 0x4D0 +#define LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE 0x4D1 + +// +// Global data +// + +VOID *mEfiDevPathNotifyReg; +EFI_EVENT mEfiDevPathEvent; +VOID *mEmuVariableEventReg; +EFI_EVENT mEmuVariableEvent; +BOOLEAN mDetectVgaOnly; +UINT16 mHostBridgeDevId; + +// +// Table of host IRQs matching PCI IRQs A-D +// (for configuring PCI Interrupt Line register) +// +CONST UINT8 PciHostIrqs[] =3D { + 0x0a, 0x0a, 0x0b, 0x0b +}; + +// +// Type definitions +// + +typedef +EFI_STATUS +(EFIAPI *PROTOCOL_INSTANCE_CALLBACK)( + IN EFI_HANDLE Handle, + IN VOID *Instance, + IN VOID *Context + ); + +/** + @param[in] Handle - Handle of PCI device instance + @param[in] PciIo - PCI IO protocol instance + @param[in] Pci - PCI Header register block +**/ +typedef +EFI_STATUS +(EFIAPI *VISIT_PCI_INSTANCE_CALLBACK)( + IN EFI_HANDLE Handle, + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN PCI_TYPE00 *Pci + ); + + +// +// Function prototypes +// + +EFI_STATUS +VisitAllInstancesOfProtocol ( + IN EFI_GUID *Id, + IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction, + IN VOID *Context + ); + +EFI_STATUS +VisitAllPciInstancesOfProtocol ( + IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction + ); + +VOID +InstallDevicePathCallback ( + VOID + ); + +VOID +PlatformRegisterFvBootOption ( + EFI_GUID *FileGuid, + CHAR16 *Description, + UINT32 Attributes + ) +{ + EFI_STATUS Status; + INTN OptionIndex; + EFI_BOOT_MANAGER_LOAD_OPTION NewOption; + EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; + UINTN BootOptionCount; + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + Status =3D gBS->HandleProtocol ( + gImageHandle, + &gEfiLoadedImageProtocolGuid, + (VOID **) &LoadedImage + ); + ASSERT_EFI_ERROR (Status); + + EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid); + DevicePath =3D DevicePathFromHandle (LoadedImage->DeviceHandle); + ASSERT (DevicePath !=3D NULL); + DevicePath =3D AppendDevicePathNode ( + DevicePath, + (EFI_DEVICE_PATH_PROTOCOL *) &FileNode + ); + ASSERT (DevicePath !=3D NULL); + + Status =3D EfiBootManagerInitializeLoadOption ( + &NewOption, + LoadOptionNumberUnassigned, + LoadOptionTypeBoot, + Attributes, + Description, + DevicePath, + NULL, + 0 + ); + ASSERT_EFI_ERROR (Status); + FreePool (DevicePath); + + BootOptions =3D EfiBootManagerGetLoadOptions ( + &BootOptionCount, LoadOptionTypeBoot + ); + + OptionIndex =3D EfiBootManagerFindLoadOption ( + &NewOption, BootOptions, BootOptionCount + ); + + if (OptionIndex =3D=3D -1) { + Status =3D EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN); + ASSERT_EFI_ERROR (Status); + } + EfiBootManagerFreeLoadOption (&NewOption); + EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); +} + +/** + Remove all MemoryMapped(...)/FvFile(...) and Fv(...)/FvFile(...) boot op= tions + whose device paths do not resolve exactly to an FvFile in the system. + + This removes any boot options that point to binaries built into the firm= ware + and have become stale due to any of the following: + - DXEFV's base address or size changed (historical), + - DXEFV's FvNameGuid changed, + - the FILE_GUID of the pointed-to binary changed, + - the referenced binary is no longer built into the firmware. + + EfiBootManagerFindLoadOption() used in PlatformRegisterFvBootOption() on= ly + avoids exact duplicates. +**/ +VOID +RemoveStaleFvFileOptions ( + VOID + ) +{ + EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; + UINTN BootOptionCount; + UINTN Index; + + BootOptions =3D EfiBootManagerGetLoadOptions (&BootOptionCount, + LoadOptionTypeBoot); + + for (Index =3D 0; Index < BootOptionCount; ++Index) { + EFI_DEVICE_PATH_PROTOCOL *Node1, *Node2, *SearchNode; + EFI_STATUS Status; + EFI_HANDLE FvHandle; + + // + // If the device path starts with neither MemoryMapped(...) nor Fv(...= ), + // then keep the boot option. + // + Node1 =3D BootOptions[Index].FilePath; + if (!(DevicePathType (Node1) =3D=3D HARDWARE_DEVICE_PATH && + DevicePathSubType (Node1) =3D=3D HW_MEMMAP_DP) && + !(DevicePathType (Node1) =3D=3D MEDIA_DEVICE_PATH && + DevicePathSubType (Node1) =3D=3D MEDIA_PIWG_FW_VOL_DP)) { + continue; + } + + // + // If the second device path node is not FvFile(...), then keep the bo= ot + // option. + // + Node2 =3D NextDevicePathNode (Node1); + if (DevicePathType (Node2) !=3D MEDIA_DEVICE_PATH || + DevicePathSubType (Node2) !=3D MEDIA_PIWG_FW_FILE_DP) { + continue; + } + + // + // Locate the Firmware Volume2 protocol instance that is denoted by the + // boot option. If this lookup fails (i.e., the boot option references= a + // firmware volume that doesn't exist), then we'll proceed to delete t= he + // boot option. + // + SearchNode =3D Node1; + Status =3D gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, + &SearchNode, &FvHandle); + + if (!EFI_ERROR (Status)) { + // + // The firmware volume was found; now let's see if it contains the F= vFile + // identified by GUID. + // + EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol; + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFileNode; + UINTN BufferSize; + EFI_FV_FILETYPE FoundType; + EFI_FV_FILE_ATTRIBUTES FileAttributes; + UINT32 AuthenticationStatus; + + Status =3D gBS->HandleProtocol (FvHandle, &gEfiFirmwareVolume2Protoc= olGuid, + (VOID **)&FvProtocol); + ASSERT_EFI_ERROR (Status); + + FvFileNode =3D (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)Node2; + // + // Buffer=3D=3DNULL means we request metadata only: BufferSize, Foun= dType, + // FileAttributes. + // + Status =3D FvProtocol->ReadFile ( + FvProtocol, + &FvFileNode->FvFileName, // NameGuid + NULL, // Buffer + &BufferSize, + &FoundType, + &FileAttributes, + &AuthenticationStatus + ); + if (!EFI_ERROR (Status)) { + // + // The FvFile was found. Keep the boot option. + // + continue; + } + } + + // + // Delete the boot option. + // + Status =3D EfiBootManagerDeleteLoadOptionVariable ( + BootOptions[Index].OptionNumber, LoadOptionTypeBoot); + DEBUG_CODE ( + CHAR16 *DevicePathString; + + DevicePathString =3D ConvertDevicePathToText(BootOptions[Index].File= Path, + FALSE, FALSE); + DEBUG (( + EFI_ERROR (Status) ? EFI_D_WARN : EFI_D_VERBOSE, + "%a: removing stale Boot#%04x %s: %r\n", + __FUNCTION__, + (UINT32)BootOptions[Index].OptionNumber, + DevicePathString =3D=3D NULL ? L"" : DevicePathString, + Status + )); + if (DevicePathString !=3D NULL) { + FreePool (DevicePathString); + } + ); + } + + EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); +} + +VOID +PlatformRegisterOptionsAndKeys ( + VOID + ) +{ + EFI_STATUS Status; + EFI_INPUT_KEY Enter; + EFI_INPUT_KEY F2; + EFI_INPUT_KEY Esc; + EFI_BOOT_MANAGER_LOAD_OPTION BootOption; + + // + // Register ENTER as CONTINUE key + // + Enter.ScanCode =3D SCAN_NULL; + Enter.UnicodeChar =3D CHAR_CARRIAGE_RETURN; + Status =3D EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL); + ASSERT_EFI_ERROR (Status); + + // + // Map F2 to Boot Manager Menu + // + F2.ScanCode =3D SCAN_F2; + F2.UnicodeChar =3D CHAR_NULL; + Esc.ScanCode =3D SCAN_ESC; + Esc.UnicodeChar =3D CHAR_NULL; + Status =3D EfiBootManagerGetBootManagerMenu (&BootOption); + ASSERT_EFI_ERROR (Status); + Status =3D EfiBootManagerAddKeyOptionVariable ( + NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL + ); + ASSERT (Status =3D=3D EFI_SUCCESS || Status =3D=3D EFI_ALREADY_STARTED); + Status =3D EfiBootManagerAddKeyOptionVariable ( + NULL, (UINT16) BootOption.OptionNumber, 0, &Esc, NULL + ); + ASSERT (Status =3D=3D EFI_SUCCESS || Status =3D=3D EFI_ALREADY_STARTED); +} + +EFI_STATUS +EFIAPI +ConnectRootBridge ( + IN EFI_HANDLE RootBridgeHandle, + IN VOID *Instance, + IN VOID *Context + ); + +STATIC +VOID +SaveS3BootScript ( + VOID + ); + +// +// BDS Platform Functions +// +/** + Do the platform init, can be customized by OEM/IBV + + Possible things that can be done in PlatformBootManagerBeforeConsole: + + > Update console variable: 1. include hot-plug devices; + > 2. Clear ConIn and add SOL for AMT + > Register new Driver#### or Boot#### + > Register new Key####: e.g.: F12 + > Signal ReadyToLock event + > Authentication action: 1. connect Auth devices; + > 2. Identify auto logon user. +**/ +VOID +EFIAPI +PlatformBootManagerBeforeConsole ( + VOID + ) +{ +// EFI_HANDLE Handle; +// EFI_STATUS Status; + + DEBUG ((EFI_D_INFO, "PlatformBootManagerBeforeConsole\n")); + InstallDevicePathCallback (); + + VisitAllInstancesOfProtocol (&gEfiPciRootBridgeIoProtocolGuid, + ConnectRootBridge, NULL); + // + // Enable LPC + // + PciOr16(POWER_MGMT_REGISTER_ICH10(0x04), + BIT0 | BIT1 | BIT2); + // + // We can't signal End-of-Dxe earlier than this. Namely, End-of-Dxe trig= gers + // the preparation of S3 system information. That logic has a hard depen= dency + // on the presence of the FACS ACPI table. Since our ACPI tables are only + // installed after PCI enumeration completes, we must not trigger the S3= save + // earlier, hence we can't signal End-of-Dxe earlier. + // + EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid); + + PlatformInitializeConsole (gPlatformConsole); + + PlatformRegisterOptionsAndKeys (); +} + + +EFI_STATUS +EFIAPI +ConnectRootBridge ( + IN EFI_HANDLE RootBridgeHandle, + IN VOID *Instance, + IN VOID *Context + ) +{ + EFI_STATUS Status; + + // + // Make the PCI bus driver connect the root bridge, non-recursively. This + // will produce a number of child handles with PciIo on them. + // + Status =3D gBS->ConnectController ( + RootBridgeHandle, // ControllerHandle + NULL, // DriverImageHandle + NULL, // RemainingDevicePath -- produce all + // children + FALSE // Recursive + ); + return Status; +} + + +/** + Add IsaKeyboard to ConIn; add IsaSerial to ConOut, ConIn, ErrOut. + + @param[in] DeviceHandle Handle of the LPC Bridge device. + + @retval EFI_SUCCESS Console devices on the LPC bridge have been added to + ConOut, ConIn, and ErrOut. + + @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing + from DeviceHandle. +**/ +EFI_STATUS +PrepareLpcBridgeDevicePath ( + IN EFI_HANDLE DeviceHandle + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; + CHAR16 *DevPathStr; + + DevicePath =3D NULL; + Status =3D gBS->HandleProtocol ( + DeviceHandle, + &gEfiDevicePathProtocolGuid, + (VOID*)&DevicePath + ); + if (EFI_ERROR (Status)) { + return Status; + } + TempDevicePath =3D DevicePath; + + // + // Register Keyboard + // + DevicePath =3D AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOC= OL *)&gPnpPs2KeyboardDeviceNode); + + EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL); + + // + // Register COM1 + // + DevicePath =3D TempDevicePath; + gPnp16550ComPortDeviceNode.UID =3D 0; + + DevicePath =3D AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOC= OL *)&gPnp16550ComPortDeviceNode); + DevicePath =3D AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOC= OL *)&gUartDeviceNode); + DevicePath =3D AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOC= OL *)&gTerminalTypeDeviceNode); + + // + // Print Device Path + // + DevPathStr =3D ConvertDevicePathToText (DevicePath, FALSE, FALSE); + if (DevPathStr !=3D NULL) { + DEBUG(( + EFI_D_INFO, + "BdsPlatform.c+%d: COM%d DevPath: %s\n", + __LINE__, + gPnp16550ComPortDeviceNode.UID + 1, + DevPathStr + )); + FreePool(DevPathStr); + } + + EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL); + EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL); + EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL); + + // + // Register COM2 + // + DevicePath =3D TempDevicePath; + gPnp16550ComPortDeviceNode.UID =3D 1; + + DevicePath =3D AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOC= OL *)&gPnp16550ComPortDeviceNode); + DevicePath =3D AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOC= OL *)&gUartDeviceNode); + DevicePath =3D AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOC= OL *)&gTerminalTypeDeviceNode); + + // + // Print Device Path + // + DevPathStr =3D ConvertDevicePathToText (DevicePath, FALSE, FALSE); + if (DevPathStr !=3D NULL) { + DEBUG(( + EFI_D_INFO, + "BdsPlatform.c+%d: COM%d DevPath: %s\n", + __LINE__, + gPnp16550ComPortDeviceNode.UID + 1, + DevPathStr + )); + FreePool(DevPathStr); + } + + EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL); + EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL); + EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL); + + return EFI_SUCCESS; +} + +EFI_STATUS +GetGopDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *PciDevicePath, + OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath + ) +{ + UINTN Index; + EFI_STATUS Status; + EFI_HANDLE PciDeviceHandle; + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; + EFI_DEVICE_PATH_PROTOCOL *TempPciDevicePath; + UINTN GopHandleCount; + EFI_HANDLE *GopHandleBuffer; + + if (PciDevicePath =3D=3D NULL || GopDevicePath =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Initialize the GopDevicePath to be PciDevicePath + // + *GopDevicePath =3D PciDevicePath; + TempPciDevicePath =3D PciDevicePath; + + Status =3D gBS->LocateDevicePath ( + &gEfiDevicePathProtocolGuid, + &TempPciDevicePath, + &PciDeviceHandle + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Try to connect this handle, so that GOP driver could start on this + // device and create child handles with GraphicsOutput Protocol installed + // on them, then we get device paths of these child handles and select + // them as possible console device. + // + gBS->ConnectController (PciDeviceHandle, NULL, NULL, FALSE); + + Status =3D gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiGraphicsOutputProtocolGuid, + NULL, + &GopHandleCount, + &GopHandleBuffer + ); + if (!EFI_ERROR (Status)) { + // + // Add all the child handles as possible Console Device + // + for (Index =3D 0; Index < GopHandleCount; Index++) { + Status =3D gBS->HandleProtocol (GopHandleBuffer[Index], &gEfiDeviceP= athProtocolGuid, (VOID*)&TempDevicePath); + if (EFI_ERROR (Status)) { + continue; + } + if (CompareMem ( + PciDevicePath, + TempDevicePath, + GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH + ) =3D=3D 0) { + // + // In current implementation, we only enable one of the child hand= les + // as console device, i.e. sotre one of the child handle's device + // path to variable "ConOut" + // In future, we could select all child handles to be console devi= ce + // + + *GopDevicePath =3D TempDevicePath; + + // + // Delete the PCI device's path that added by + // GetPlugInPciVgaDevicePath(). Add the integrity GOP device path. + // + EfiBootManagerUpdateConsoleVariable (ConOutDev, NULL, PciDevicePat= h); + EfiBootManagerUpdateConsoleVariable (ConOutDev, TempDevicePath, NU= LL); + } + } + gBS->FreePool (GopHandleBuffer); + } + + return EFI_SUCCESS; +} + +/** + Add PCI display to ConOut. + + @param[in] DeviceHandle Handle of the PCI display device. + + @retval EFI_SUCCESS The PCI display device has been added to ConOut. + + @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing + from DeviceHandle. +**/ +EFI_STATUS +PreparePciDisplayDevicePath ( + IN EFI_HANDLE DeviceHandle + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *GopDevicePath; + + DevicePath =3D NULL; + GopDevicePath =3D NULL; + Status =3D gBS->HandleProtocol ( + DeviceHandle, + &gEfiDevicePathProtocolGuid, + (VOID*)&DevicePath + ); + if (EFI_ERROR (Status)) { + return Status; + } + + GetGopDevicePath (DevicePath, &GopDevicePath); + DevicePath =3D GopDevicePath; + + EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL); + + return EFI_SUCCESS; +} + +/** + Add PCI Serial to ConOut, ConIn, ErrOut. + + @param[in] DeviceHandle Handle of the PCI serial device. + + @retval EFI_SUCCESS The PCI serial device has been added to ConOut, Con= In, + ErrOut. + + @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing + from DeviceHandle. +**/ +EFI_STATUS +PreparePciSerialDevicePath ( + IN EFI_HANDLE DeviceHandle + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + DevicePath =3D NULL; + Status =3D gBS->HandleProtocol ( + DeviceHandle, + &gEfiDevicePathProtocolGuid, + (VOID*)&DevicePath + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DevicePath =3D AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOC= OL *)&gUartDeviceNode); + DevicePath =3D AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOC= OL *)&gTerminalTypeDeviceNode); + + EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL); + EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL); + EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL); + + return EFI_SUCCESS; +} + +EFI_STATUS +VisitAllInstancesOfProtocol ( + IN EFI_GUID *Id, + IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction, + IN VOID *Context + ) +{ + EFI_STATUS Status; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + UINTN Index; + VOID *Instance; + + // + // Start to check all the PciIo to find all possible device + // + HandleCount =3D 0; + HandleBuffer =3D NULL; + Status =3D gBS->LocateHandleBuffer ( + ByProtocol, + Id, + NULL, + &HandleCount, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + + for (Index =3D 0; Index < HandleCount; Index++) { + Status =3D gBS->HandleProtocol (HandleBuffer[Index], Id, &Instance); + if (EFI_ERROR (Status)) { + continue; + } + + Status =3D (*CallBackFunction) ( + HandleBuffer[Index], + Instance, + Context + ); + } + + gBS->FreePool (HandleBuffer); + + return EFI_SUCCESS; +} + + +EFI_STATUS +EFIAPI +VisitingAPciInstance ( + IN EFI_HANDLE Handle, + IN VOID *Instance, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + PCI_TYPE00 Pci; + + PciIo =3D (EFI_PCI_IO_PROTOCOL*) Instance; + + // + // Check for all PCI device + // + Status =3D PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint32, + 0, + sizeof (Pci) / sizeof (UINT32), + &Pci + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return (*(VISIT_PCI_INSTANCE_CALLBACK)(UINTN) Context) ( + Handle, + PciIo, + &Pci + ); + +} + + + +EFI_STATUS +VisitAllPciInstances ( + IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction + ) +{ + return VisitAllInstancesOfProtocol ( + &gEfiPciIoProtocolGuid, + VisitingAPciInstance, + (VOID*)(UINTN) CallBackFunction + ); +} + + +/** + Do platform specific PCI Device check and add them to + ConOut, ConIn, ErrOut. + + @param[in] Handle - Handle of PCI device instance + @param[in] PciIo - PCI IO protocol instance + @param[in] Pci - PCI Header register block + + @retval EFI_SUCCESS - PCI Device check and Console variable update + successfully. + @retval EFI_STATUS - PCI Device check or Console variable update fail. + +**/ +EFI_STATUS +EFIAPI +DetectAndPreparePlatformPciDevicePath ( + IN EFI_HANDLE Handle, + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN PCI_TYPE00 *Pci + ) +{ + EFI_STATUS Status; + + Status =3D PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationEnable, + EFI_PCI_DEVICE_ENABLE, + NULL + ); + ASSERT_EFI_ERROR (Status); + + if (!mDetectVgaOnly) { + // + // Here we decide whether it is LPC Bridge + // + if ((IS_PCI_LPC (Pci)) || + ((IS_PCI_ISA_PDECODE (Pci)) && + (Pci->Hdr.VendorId =3D=3D 0x8086) && + (Pci->Hdr.DeviceId =3D=3D 0x7000) + ) + ) { + // + // Add IsaKeyboard to ConIn, + // add IsaSerial to ConOut, ConIn, ErrOut + // + DEBUG ((EFI_D_INFO, "Found LPC Bridge device\n")); + PrepareLpcBridgeDevicePath (Handle); + return EFI_SUCCESS; + } + // + // Here we decide which Serial device to enable in PCI bus + // + if (IS_PCI_16550SERIAL (Pci)) { + // + // Add them to ConOut, ConIn, ErrOut. + // + DEBUG ((EFI_D_INFO, "Found PCI 16550 SERIAL device\n")); + PreparePciSerialDevicePath (Handle); + return EFI_SUCCESS; + } + } + + // + // Here we decide which display device to enable in PCI bus + // + if (IS_PCI_DISPLAY (Pci)) { + // + // Add them to ConOut. + // + DEBUG ((EFI_D_INFO, "Found PCI display device\n")); + PreparePciDisplayDevicePath (Handle); + return EFI_SUCCESS; + } + + return Status; +} + + +/** + Do platform specific PCI Device check and add them to ConOut, ConIn, Err= Out + + @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE. + + @retval EFI_SUCCESS - PCI Device check and Console variable update succe= ssfully. + @retval EFI_STATUS - PCI Device check or Console variable update fail. + +**/ +EFI_STATUS +DetectAndPreparePlatformPciDevicePaths ( + BOOLEAN DetectVgaOnly + ) +{ + mDetectVgaOnly =3D DetectVgaOnly; + return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath); +} + +/** + Connect the predefined platform default console device. + + Always try to find and enable PCI display devices. + + @param[in] PlatformConsole Predefined platform default console device a= rray. +**/ +VOID +PlatformInitializeConsole ( + IN PLATFORM_CONSOLE_CONNECT_ENTRY *PlatformConsole + ) +{ + UINTN Index; + EFI_DEVICE_PATH_PROTOCOL *VarConout; + EFI_DEVICE_PATH_PROTOCOL *VarConin; + + // + // Connect RootBridge + // + GetEfiGlobalVariable2 (EFI_CON_OUT_VARIABLE_NAME, (VOID **) &VarConout, = NULL); + GetEfiGlobalVariable2 (EFI_CON_IN_VARIABLE_NAME, (VOID **) &VarConin, NU= LL); + + if (VarConout =3D=3D NULL || VarConin =3D=3D NULL) { + // + // Do platform specific PCI Device check and add them to ConOut, ConIn= , ErrOut + // + DetectAndPreparePlatformPciDevicePaths (FALSE); + DetectAndPreparePlatformPciDevicePaths(TRUE); + // + // Have chance to connect the platform default console, + // the platform default console is the minimue device group + // the platform should support + // + for (Index =3D 0; PlatformConsole[Index].DevicePath !=3D NULL; ++Index= ) { + // + // Update the console variable with the connect type + // + if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) =3D=3D CONSOLE= _IN) { + EfiBootManagerUpdateConsoleVariable (ConIn, PlatformConsole[Index]= .DevicePath, NULL); + } + if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) =3D=3D CONSOL= E_OUT) { + EfiBootManagerUpdateConsoleVariable (ConOut, PlatformConsole[Index= ].DevicePath, NULL); + } + if ((PlatformConsole[Index].ConnectType & STD_ERROR) =3D=3D STD_ERRO= R) { + EfiBootManagerUpdateConsoleVariable (ErrOut, PlatformConsole[Index= ].DevicePath, NULL); + } + } + } else { + // + // Only detect VGA device and add them to ConOut + // + DetectAndPreparePlatformPciDevicePaths (TRUE); + } +} + + +/** + Configure PCI Interrupt Line register for applicable devices + Ported from SeaBIOS, src/fw/pciinit.c, *_pci_slot_get_irq() + + @param[in] Handle - Handle of PCI device instance + @param[in] PciIo - PCI IO protocol instance + @param[in] PciHdr - PCI Header register block + + @retval EFI_SUCCESS - PCI Interrupt Line register configured successfull= y. + +**/ +EFI_STATUS +EFIAPI +SetPciIntLine ( + IN EFI_HANDLE Handle, + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN PCI_TYPE00 *PciHdr + ) +{ + EFI_DEVICE_PATH_PROTOCOL *DevPathNode; + EFI_DEVICE_PATH_PROTOCOL *DevPath; + UINTN RootSlot; + UINTN Idx; + UINT8 IrqLine; + EFI_STATUS Status; + UINT32 RootBusNumber; + + Status =3D EFI_SUCCESS; + + if (PciHdr->Device.InterruptPin !=3D 0) { + + DevPathNode =3D DevicePathFromHandle (Handle); + ASSERT (DevPathNode !=3D NULL); + DevPath =3D DevPathNode; + + RootBusNumber =3D 0; + if (DevicePathType (DevPathNode) =3D=3D ACPI_DEVICE_PATH && + DevicePathSubType (DevPathNode) =3D=3D ACPI_DP && + ((ACPI_HID_DEVICE_PATH *)DevPathNode)->HID =3D=3D EISA_PNP_ID(0x0A= 03)) { + RootBusNumber =3D ((ACPI_HID_DEVICE_PATH *)DevPathNode)->UID; + } + + // + // Compute index into PciHostIrqs[] table by walking + // the device path and adding up all device numbers + // + Status =3D EFI_NOT_FOUND; + RootSlot =3D 0; + Idx =3D PciHdr->Device.InterruptPin - 1; + while (!IsDevicePathEnd (DevPathNode)) { + if (DevicePathType (DevPathNode) =3D=3D HARDWARE_DEVICE_PATH && + DevicePathSubType (DevPathNode) =3D=3D HW_PCI_DP) { + + Idx +=3D ((PCI_DEVICE_PATH *)DevPathNode)->Device; + + // + // Unlike SeaBIOS, which starts climbing from the leaf device + // up toward the root, we traverse the device path starting at + // the root moving toward the leaf node. + // The slot number of the top-level parent bridge is needed + // with more than 24 slots on the root bus. + // + if (Status !=3D EFI_SUCCESS) { + Status =3D EFI_SUCCESS; + RootSlot =3D ((PCI_DEVICE_PATH *)DevPathNode)->Device; + } + } + + DevPathNode =3D NextDevicePathNode (DevPathNode); + } + if (EFI_ERROR (Status)) { + return Status; + } + if (RootBusNumber =3D=3D 0 && RootSlot =3D=3D 0) { + return Status; //bugbug: workaround; need SIMICS change B0/D0/F0 PCI= _IntPin reg(0x3D) =3D 0X0 +// DEBUG(( +// EFI_D_ERROR, +// "%a: PCI host bridge (00:00.0) should have no interrupts!\n", +// __FUNCTION__ +// )); +// ASSERT (FALSE); + } + + // + // Final PciHostIrqs[] index calculation depends on the platform + // and should match SeaBIOS src/fw/pciinit.c *_pci_slot_get_irq() + // + switch (mHostBridgeDevId) { + case INTEL_82441_DEVICE_ID: + Idx -=3D 1; + break; + case INTEL_ICH10_DEVICE_ID: + // + // SeaBIOS contains the following comment: + // "Slots 0-24 rotate slot:pin mapping similar to piix above, but + // with a different starting index. + // + // Slots 25-31 all use LNKA mapping (or LNKE, but A:D =3D E:H)" + // + if (RootSlot > 24) { + // + // in this case, subtract back out RootSlot from Idx + // (SeaBIOS never adds it to begin with, but that would make our + // device path traversal loop above too awkward) + // + Idx -=3D RootSlot; + } + break; + default: + ASSERT (FALSE); // should never get here + } + Idx %=3D ARRAY_SIZE (PciHostIrqs); + IrqLine =3D PciHostIrqs[Idx]; + + DEBUG_CODE_BEGIN (); + { + CHAR16 *DevPathString; + STATIC CHAR16 Fallback[] =3D L""; + UINTN Segment, Bus, Device, Function; + + DevPathString =3D ConvertDevicePathToText (DevPath, FALSE, FALSE); + if (DevPathString =3D=3D NULL) { + DevPathString =3D Fallback; + } + Status =3D PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Func= tion); + ASSERT_EFI_ERROR (Status); + + DEBUG ((EFI_D_VERBOSE, "%a: [%02x:%02x.%x] %s -> 0x%02x\n", __FUNCTI= ON__, + (UINT32)Bus, (UINT32)Device, (UINT32)Function, DevPathString, + IrqLine)); + + if (DevPathString !=3D Fallback) { + FreePool (DevPathString); + } + } + DEBUG_CODE_END (); + + // + // Set PCI Interrupt Line register for this device to PciHostIrqs[Idx] + // + Status =3D PciIo->Pci.Write ( + PciIo, + EfiPciIoWidthUint8, + PCI_INT_LINE_OFFSET, + 1, + &IrqLine + ); + } + + return Status; +} + +/** +Write to mask and edge/level triggered registers of master and slave 8259 = PICs. + +@param[in] Mask low byte for master PIC mask register, +high byte for slave PIC mask register. +@param[in] EdgeLevel low byte for master PIC edge/level triggered regist= er, +high byte for slave PIC edge/level triggered register. + +**/ +VOID +Interrupt8259WriteMask( + IN UINT16 Mask, + IN UINT16 EdgeLevel +) +{ + IoWrite8(LEGACY_8259_MASK_REGISTER_MASTER, (UINT8)Mask); + IoWrite8(LEGACY_8259_MASK_REGISTER_SLAVE, (UINT8)(Mask >> 8)); + IoWrite8(LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER, (UINT8)EdgeLe= vel); + IoWrite8(LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE, (UINT8)(EdgeLe= vel >> 8)); +} + +VOID +PciAcpiInitialization ( + ) +{ + UINTN Pmba; + + // + // Query Host Bridge DID to determine platform type + // + mHostBridgeDevId =3D PcdGet16 (PcdSimicsX58HostBridgePciDevId); + switch (mHostBridgeDevId) { + case INTEL_82441_DEVICE_ID: + Pmba =3D POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA); + // + // 00:01.0 ISA Bridge (PIIX4) LNK routing targets + // + PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b); // A + PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x0b); // B + PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0a); // C + PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x0a); // D + break; + case INTEL_ICH10_DEVICE_ID: + Pmba =3D POWER_MGMT_REGISTER_ICH10 (ICH10_PMBASE); + // + // 00:1f.0 LPC Bridge LNK routing targets + // + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x60), 0x0a); // A + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x61), 0x0a); // B + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x62), 0x0b); // C + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x63), 0x0b); // D + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x68), 0x0a); // E + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x69), 0x0a); // F + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6a), 0x0b); // G + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6b), 0x0b); // H + break; + default: + DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n", + __FUNCTION__, mHostBridgeDevId)); + ASSERT (FALSE); + return; + } + + // + // Initialize PCI_INTERRUPT_LINE for applicable present PCI devices + // + VisitAllPciInstances (SetPciIntLine); + + // + // Set ACPI SCI_EN bit in PMCNTRL + // + IoOr16 ((PciRead32 (Pmba) & ~BIT0) + 4, BIT0); + // + // Set all 8259 interrupts to edge triggered and disabled + // + Interrupt8259WriteMask(0xFFFF, 0x0000); +} + +EFI_STATUS +EFIAPI +ConnectRecursivelyIfPciMassStorage ( + IN EFI_HANDLE Handle, + IN EFI_PCI_IO_PROTOCOL *Instance, + IN PCI_TYPE00 *PciHeader + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + CHAR16 *DevPathStr; + + // + // Recognize PCI Mass Storage + // + if (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE)) { + DevicePath =3D NULL; + Status =3D gBS->HandleProtocol ( + Handle, + &gEfiDevicePathProtocolGuid, + (VOID*)&DevicePath + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Print Device Path + // + DevPathStr =3D ConvertDevicePathToText (DevicePath, FALSE, FALSE); + if (DevPathStr !=3D NULL) { + DEBUG(( + EFI_D_INFO, + "Found Mass Storage device: %s\n", + DevPathStr + )); + FreePool(DevPathStr); + } + + Status =3D gBS->ConnectController (Handle, NULL, NULL, TRUE); + if (EFI_ERROR (Status)) { + return Status; + } + + } + + return EFI_SUCCESS; +} + + +/** + This notification function is invoked when the + EMU Variable FVB has been changed. + + @param Event The event that occurred + @param Context For EFI compatibility. Not used. + +**/ +VOID +EFIAPI +EmuVariablesUpdatedCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + DEBUG ((EFI_D_INFO, "EmuVariablesUpdatedCallback\n")); + UpdateNvVarsOnFileSystem (); +} + + +EFI_STATUS +EFIAPI +VisitingFileSystemInstance ( + IN EFI_HANDLE Handle, + IN VOID *Instance, + IN VOID *Context + ) +{ + EFI_STATUS Status; + STATIC BOOLEAN ConnectedToFileSystem =3D FALSE; + + if (ConnectedToFileSystem) { + return EFI_ALREADY_STARTED; + } + + Status =3D ConnectNvVarsToFileSystem (Handle); + if (EFI_ERROR (Status)) { + return Status; + } + + ConnectedToFileSystem =3D TRUE; + mEmuVariableEvent =3D + EfiCreateProtocolNotifyEvent ( + &gEfiDevicePathProtocolGuid, + TPL_CALLBACK, + EmuVariablesUpdatedCallback, + NULL, + &mEmuVariableEventReg + ); + PcdSet64 (PcdEmuVariableEvent, (UINT64)(UINTN) mEmuVariableEvent); + + return EFI_SUCCESS; +} + + +VOID +PlatformBdsRestoreNvVarsFromHardDisk ( + ) +{ + VisitAllPciInstances (ConnectRecursivelyIfPciMassStorage); + VisitAllInstancesOfProtocol ( + &gEfiSimpleFileSystemProtocolGuid, + VisitingFileSystemInstance, + NULL + ); + +} + +/** + Connect with predefined platform connect sequence. + + The OEM/IBV can customize with their own connect sequence. +**/ +VOID +PlatformBdsConnectSequence ( + VOID + ) +{ + UINTN Index; + + DEBUG ((EFI_D_INFO, "PlatformBdsConnectSequence\n")); + + Index =3D 0; + + // + // Here we can get the customized platform connect sequence + // Notes: we can connect with new variable which record the + // last time boots connect device path sequence + // + while (gPlatformConnectSequence[Index] !=3D NULL) { + // + // Build the platform boot option + // + EfiBootManagerConnectDevicePath (gPlatformConnectSequence[Index], NULL= ); + Index++; + } + + // + // Just use the simple policy to connect all devices + // + DEBUG ((EFI_D_INFO, "EfiBootManagerConnectAll\n")); + EfiBootManagerConnectAll (); + + PciAcpiInitialization (); +} + +/** + Save the S3 boot script. + + Note that DxeSmmReadyToLock must be signaled after this function returns; + otherwise the script wouldn't be saved actually. +**/ +STATIC +VOID +SaveS3BootScript ( + VOID + ) +{ + EFI_STATUS Status; + EFI_S3_SAVE_STATE_PROTOCOL *BootScript; + STATIC CONST UINT8 Info[] =3D { 0xDE, 0xAD, 0xBE, 0xEF }; + + Status =3D gBS->LocateProtocol (&gEfiS3SaveStateProtocolGuid, NULL, + (VOID **) &BootScript); + ASSERT_EFI_ERROR (Status); + + // + // Despite the opcode documentation in the PI spec, the protocol + // implementation embeds a deep copy of the info in the boot script, rat= her + // than storing just a pointer to runtime or NVS storage. + // + Status =3D BootScript->Write(BootScript, EFI_BOOT_SCRIPT_INFORMATION_OPC= ODE, + (UINT32) sizeof Info, + (EFI_PHYSICAL_ADDRESS)(UINTN) &Info); + ASSERT_EFI_ERROR (Status); +} + + +/** + Do the platform specific action after the console is ready + + Possible things that can be done in PlatformBootManagerAfterConsole: + + > Console post action: + > Dynamically switch output mode from 100x31 to 80x25 for certain sena= rino + > Signal console ready platform customized event + > Run diagnostics like memory testing + > Connect certain devices + > Dispatch aditional option roms + > Special boot: e.g.: USB boot, enter UI +**/ +VOID +EFIAPI +PlatformBootManagerAfterConsole ( + VOID + ) +{ + EFI_BOOT_MODE BootMode; + EFI_HANDLE Handle; + EFI_STATUS Status; + + DEBUG ((EFI_D_INFO, "PlatformBootManagerAfterConsole\n")); + + // + // Prevent further changes to LockBoxes or SMRAM. + // + Handle =3D NULL; + Status =3D gBS->InstallProtocolInterface(&Handle, + &gEfiDxeSmmReadyToLockProtocolGuid, EFI_NATIVE_INTERFACE, + NULL); + ASSERT_EFI_ERROR(Status); + + if (PcdGetBool (PcdOvmfFlashVariablesEnable)) { + DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior: not restoring NvVars " + "from disk since flash variables appear to be supported.\n")); + } else { + // + // Try to restore variables from the hard disk early so + // they can be used for the other BDS connect operations. + // + PlatformBdsRestoreNvVarsFromHardDisk (); + } + + // + // Get current Boot Mode + // + BootMode =3D GetBootModeHob (); + DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", BootMode)); + + // + // Go the different platform policy with different boot mode + // Notes: this part code can be change with the table policy + // + ASSERT (BootMode =3D=3D BOOT_WITH_FULL_CONFIGURATION); + + // Perform some platform specific connect sequence + // + PlatformBdsConnectSequence (); + // + // Logo show + // + EnableBootLogo(PcdGetPtr(PcdLogoFile)); + + EfiBootManagerRefreshAllBootOption (); + + // + // Register UEFI Shell + // + PlatformRegisterFvBootOption ( + PcdGetPtr (PcdShellFile), L"EFI Internal Shell", LOAD_OPTION_ACTIVE + ); + + RemoveStaleFvFileOptions (); +} + +/** + This notification function is invoked when an instance of the + EFI_DEVICE_PATH_PROTOCOL is produced. + + @param Event The event that occurred + @param Context For EFI compatibility. Not used. + +**/ +VOID +EFIAPI +NotifyDevPath ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_HANDLE Handle; + EFI_STATUS Status; + UINTN BufferSize; + EFI_DEVICE_PATH_PROTOCOL *DevPathNode; + ATAPI_DEVICE_PATH *Atapi; + + // + // Examine all new handles + // + for (;;) { + // + // Get the next handle + // + BufferSize =3D sizeof (Handle); + Status =3D gBS->LocateHandle ( + ByRegisterNotify, + NULL, + mEfiDevPathNotifyReg, + &BufferSize, + &Handle + ); + + // + // If not found, we're done + // + if (EFI_NOT_FOUND =3D=3D Status) { + break; + } + + if (EFI_ERROR (Status)) { + continue; + } + + // + // Get the DevicePath protocol on that handle + // + Status =3D gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (= VOID **)&DevPathNode); + ASSERT_EFI_ERROR (Status); + + while (!IsDevicePathEnd (DevPathNode)) { + // + // Find the handler to dump this device path node + // + if ( + (DevicePathType(DevPathNode) =3D=3D MESSAGING_DEVICE_PATH) && + (DevicePathSubType(DevPathNode) =3D=3D MSG_ATAPI_DP) + ) { + Atapi =3D (ATAPI_DEVICE_PATH*) DevPathNode; + PciOr16 ( + PCI_LIB_ADDRESS ( + 0, + 1, + 1, + (Atapi->PrimarySecondary =3D=3D 1) ? 0x42: 0x40 + ), + BIT15 + ); + } + + // + // Next device path node + // + DevPathNode =3D NextDevicePathNode (DevPathNode); + } + } + + return; +} + + +VOID +InstallDevicePathCallback ( + VOID + ) +{ + DEBUG ((EFI_D_INFO, "Registered NotifyDevPath Event\n")); + mEfiDevPathEvent =3D EfiCreateProtocolNotifyEvent ( + &gEfiDevicePathProtocolGuid, + TPL_CALLBACK, + NotifyDevPath, + NULL, + &mEfiDevPathNotifyReg + ); +} + +/** + This function is called each second during the boot manager waits the + timeout. + + @param TimeoutRemain The remaining timeout. +**/ +VOID +EFIAPI +PlatformBootManagerWaitCallback ( + UINT16 TimeoutRemain + ) +{ + EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White; + UINT16 Timeout; + + Timeout =3D PcdGet16 (PcdPlatformBootTimeOut); + + Black.Raw =3D 0x00000000; + White.Raw =3D 0x00FFFFFF; + + BootLogoUpdateProgress ( + White.Pixel, + Black.Pixel, + L"Start boot option", + White.Pixel, + (Timeout - TimeoutRemain) * 100 / Timeout, + 0 + ); +} + +/** + The function is called when no boot option could be launched, + including platform recovery options and options pointing to applications + built into firmware volumes. + + If this function returns, BDS attempts to enter an infinite loop. +**/ +VOID +EFIAPI +PlatformBootManagerUnableToBoot ( + VOID + ) +{ + // BUGBUG- will do it if need +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerL= ib/PlatformData.c b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootM= anagerLib/PlatformData.c new file mode 100644 index 0000000000..768843a8bf --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/Plat= formData.c @@ -0,0 +1,35 @@ +/** @file + Defined the platform specific device path which will be used by + platform Bbd to perform the platform policy connect. + + Copyright (c) 2004 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "BdsPlatform.h" + +ACPI_HID_DEVICE_PATH gPnpPs2KeyboardDeviceNode =3D gPnpPs2Keyboard; +ACPI_HID_DEVICE_PATH gPnp16550ComPortDeviceNode =3D gPnp16550ComPort; +UART_DEVICE_PATH gUartDeviceNode =3D gUart; +VENDOR_DEVICE_PATH gTerminalTypeDeviceNode =3D gPcAnsiTerminal; + +// +// Platform specific keyboard device path +// + +// +// Predefined platform default console device path +// +PLATFORM_CONSOLE_CONNECT_ENTRY gPlatformConsole[] =3D { + { + NULL, + 0 + } +}; + +// +// Predefined platform connect sequence +// +EFI_DEVICE_PATH_PROTOCOL *gPlatformConnectSequence[] =3D { NULL }; + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLi= b/SerializeVariablesLib.c b/Platform/Intel/SimicsOpenBoardPkg/Library/Seria= lizeVariablesLib/SerializeVariablesLib.c new file mode 100644 index 0000000000..be619c838a --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/Seria= lizeVariablesLib.c @@ -0,0 +1,869 @@ +/** @file + Serialize Variables Library implementation + + Copyright (c) 2004 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "SerializeVariablesLib.h" + +/** + Serialization format: + + The SerializeVariablesLib interface does not specify a format + for the serialization of the variable data. This library uses + a packed array of a non-uniformly sized data structure elements. + + Each variable is stored (packed) as: + UINT32 VendorNameSize; // Name size in bytes + CHAR16 VendorName[?]; // The variable unicode name including the + // null terminating character. + EFI_GUID VendorGuid; // The variable GUID + UINT32 DataSize; // The size of variable data in bytes + UINT8 Data[?]; // The variable data + +**/ + + +/** + Unpacks the next variable from the buffer + + @param[in] Buffer - Buffer pointing to the next variable instance + On subsequent calls, the pointer should be incremented + by the returned SizeUsed value. + @param[in] MaxSize - Max allowable size for the variable data + On subsequent calls, this should be decremented + by the returned SizeUsed value. + @param[out] Name - Variable name string (address in Buffer) + @param[out] NameSize - Size of Name in bytes + @param[out] Guid - GUID of variable (address in Buffer) + @param[out] Attributes - Attributes of variable + @param[out] Data - Buffer containing Data for variable (address in Buffe= r) + @param[out] DataSize - Size of Data in bytes + @param[out] SizeUsed - Total size used for this variable instance in Buf= fer + + @return EFI_STATUS based on the success or failure of the operation + +**/ +STATIC +EFI_STATUS +UnpackVariableFromBuffer ( + IN VOID *Buffer, + IN UINTN MaxSize, + OUT CHAR16 **Name, + OUT UINT32 *NameSize, + OUT EFI_GUID **Guid, + OUT UINT32 *Attributes, + OUT UINT32 *DataSize, + OUT VOID **Data, + OUT UINTN *SizeUsed + ) +{ + UINT8 *BytePtr; + UINTN Offset; + + BytePtr =3D (UINT8*)Buffer; + Offset =3D 0; + + *NameSize =3D *(UINT32*) (BytePtr + Offset); + Offset =3D Offset + sizeof (UINT32); + + if (Offset > MaxSize) { + return EFI_INVALID_PARAMETER; + } + + *Name =3D (CHAR16*) (BytePtr + Offset); + Offset =3D Offset + *(UINT32*)BytePtr; + if (Offset > MaxSize) { + return EFI_INVALID_PARAMETER; + } + + *Guid =3D (EFI_GUID*) (BytePtr + Offset); + Offset =3D Offset + sizeof (EFI_GUID); + if (Offset > MaxSize) { + return EFI_INVALID_PARAMETER; + } + + *Attributes =3D *(UINT32*) (BytePtr + Offset); + Offset =3D Offset + sizeof (UINT32); + if (Offset > MaxSize) { + return EFI_INVALID_PARAMETER; + } + + *DataSize =3D *(UINT32*) (BytePtr + Offset); + Offset =3D Offset + sizeof (UINT32); + if (Offset > MaxSize) { + return EFI_INVALID_PARAMETER; + } + + *Data =3D (VOID*) (BytePtr + Offset); + Offset =3D Offset + *DataSize; + if (Offset > MaxSize) { + return EFI_INVALID_PARAMETER; + } + + *SizeUsed =3D Offset; + + return EFI_SUCCESS; +} + + +/** + Iterates through the variables in the buffer, and calls a callback + function for each variable found. + + @param[in] CallbackFunction - Function called for each variable instance + @param[in] Context - Passed to each call of CallbackFunction + @param[in] Buffer - Buffer containing serialized variables + @param[in] MaxSize - Size of Buffer in bytes + + @return EFI_STATUS based on the success or failure of the operation + +**/ +STATIC +EFI_STATUS +IterateVariablesInBuffer ( + IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction, + IN VOID *CallbackContext, + IN VOID *Buffer, + IN UINTN MaxSize + ) +{ + RETURN_STATUS Status; + UINTN TotalSizeUsed; + UINTN SizeUsed; + + CHAR16 *Name; + UINT32 NameSize; + CHAR16 *AlignedName; + UINT32 AlignedNameMaxSize; + EFI_GUID *Guid; + UINT32 Attributes; + UINT32 DataSize; + VOID *Data; + + SizeUsed =3D 0; + AlignedName =3D NULL; + AlignedNameMaxSize =3D 0; + Name =3D NULL; + Guid =3D NULL; + Attributes =3D 0; + DataSize =3D 0; + Data =3D NULL; + + for ( + Status =3D EFI_SUCCESS, TotalSizeUsed =3D 0; + !EFI_ERROR (Status) && (TotalSizeUsed < MaxSize); + ) { + Status =3D UnpackVariableFromBuffer ( + (VOID*) ((UINT8*) Buffer + TotalSizeUsed), + (MaxSize - TotalSizeUsed), + &Name, + &NameSize, + &Guid, + &Attributes, + &DataSize, + &Data, + &SizeUsed + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // We copy the name to a separately allocated buffer, + // to be sure it is 16-bit aligned. + // + if (NameSize > AlignedNameMaxSize) { + if (AlignedName !=3D NULL) { + FreePool (AlignedName); + } + AlignedName =3D AllocatePool (NameSize); + } + if (AlignedName =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + CopyMem (AlignedName, Name, NameSize); + + TotalSizeUsed =3D TotalSizeUsed + SizeUsed; + + // + // Run the callback function + // + Status =3D (*CallbackFunction) ( + CallbackContext, + AlignedName, + Guid, + Attributes, + DataSize, + Data + ); + + } + + if (AlignedName !=3D NULL) { + FreePool (AlignedName); + } + + // + // Make sure the entire buffer was used, or else return an error + // + if (TotalSizeUsed !=3D MaxSize) { + DEBUG (( + EFI_D_ERROR, + "Deserialize variables error: TotalSizeUsed(%Lu) !=3D MaxSize(%Lu)\n= ", + (UINT64)TotalSizeUsed, + (UINT64)MaxSize + )); + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + + +STATIC +RETURN_STATUS +EFIAPI +IterateVariablesCallbackNop ( + IN VOID *Context, + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ) +{ + return RETURN_SUCCESS; +} + + +STATIC +RETURN_STATUS +EFIAPI +IterateVariablesCallbackSetInInstance ( + IN VOID *Context, + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ) +{ + EFI_HANDLE Instance; + + Instance =3D (EFI_HANDLE) Context; + + return SerializeVariablesAddVariable ( + Instance, + VariableName, + VendorGuid, + Attributes, + DataSize, + Data + ); +} + + +STATIC +RETURN_STATUS +EFIAPI +IterateVariablesCallbackSetSystemVariable ( + IN VOID *Context, + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ) +{ + EFI_STATUS Status; + STATIC CONST UINT32 AuthMask =3D + EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS; + + Status =3D gRT->SetVariable ( + VariableName, + VendorGuid, + Attributes, + DataSize, + Data + ); + + if (Status =3D=3D EFI_SECURITY_VIOLATION && (Attributes & AuthMask) !=3D= 0) { + DEBUG ((DEBUG_WARN, "%a: setting authenticated variable \"%s\" " + "failed with EFI_SECURITY_VIOLATION, ignoring\n", __FUNCTION__, + VariableName)); + Status =3D EFI_SUCCESS; + } else if (Status =3D=3D EFI_WRITE_PROTECTED) { + DEBUG ((DEBUG_WARN, "%a: setting ReadOnly variable \"%s\" " + "failed with EFI_WRITE_PROTECTED, ignoring\n", __FUNCTION__, + VariableName)); + Status =3D EFI_SUCCESS; + } + return Status; +} + + +STATIC +RETURN_STATUS +EnsureExtraBufferSpace ( + IN SV_INSTANCE *Instance, + IN UINTN Size + ) +{ + VOID *NewBuffer; + UINTN NewSize; + + NewSize =3D Instance->DataSize + Size; + if (NewSize <=3D Instance->BufferSize) { + return RETURN_SUCCESS; + } + + // + // Double the required size to lessen the need to re-allocate in the fut= ure + // + NewSize =3D 2 * NewSize; + + NewBuffer =3D AllocatePool (NewSize); + if (NewBuffer =3D=3D NULL) { + return RETURN_OUT_OF_RESOURCES; + } + + if (Instance->BufferPtr !=3D NULL) { + CopyMem (NewBuffer, Instance->BufferPtr, Instance->DataSize); + FreePool (Instance->BufferPtr); + } + + Instance->BufferPtr =3D NewBuffer; + Instance->BufferSize =3D NewSize; + + return RETURN_SUCCESS; +} + + +STATIC +VOID +AppendToBuffer ( + IN SV_INSTANCE *Instance, + IN VOID *Data, + IN UINTN Size + ) +{ + UINTN NewSize; + + ASSERT (Instance !=3D NULL); + ASSERT (Data !=3D NULL); + + NewSize =3D Instance->DataSize + Size; + ASSERT ((Instance->DataSize + Size) <=3D Instance->BufferSize); + + CopyMem ( + (VOID*) (((UINT8*) (Instance->BufferPtr)) + Instance->DataSize), + Data, + Size + ); + + Instance->DataSize =3D NewSize; +} + + +/** + Creates a new variable serialization instance + + @param[out] Handle - Handle for a variable serialization instance + + @retval RETURN_SUCCESS - The variable serialization instance was + successfully created. + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to + create the variable serialization instance. + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesNewInstance ( + OUT EFI_HANDLE *Handle + ) +{ + SV_INSTANCE *New; + + New =3D AllocateZeroPool (sizeof (*New)); + if (New =3D=3D NULL) { + return RETURN_OUT_OF_RESOURCES; + } + + New->Signature =3D SV_SIGNATURE; + + *Handle =3D (EFI_HANDLE) New; + return RETURN_SUCCESS; +} + + +/** + Free memory associated with a variable serialization instance + + @param[in] Handle - Handle for a variable serialization instance + + @retval RETURN_SUCCESS - The variable serialization instance was + successfully freed. + @retval RETURN_INVALID_PARAMETER - Handle was not a valid + variable serialization instance. + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesFreeInstance ( + IN EFI_HANDLE Handle + ) +{ + SV_INSTANCE *Instance; + + Instance =3D SV_FROM_HANDLE (Handle); + + if (Instance->Signature !=3D SV_SIGNATURE) { + return RETURN_INVALID_PARAMETER; + } + + Instance->Signature =3D 0; + + if (Instance->BufferPtr !=3D NULL) { + FreePool (Instance->BufferPtr); + } + + FreePool (Instance); + + return RETURN_SUCCESS; +} + + +/** + Creates a new variable serialization instance using the given + binary representation of the variables to fill the new instance + + @param[out] Handle - Handle for a variable serialization instance + @param[in] Buffer - A buffer with the serialized representation + of the variables. Must be the same format as produced + by SerializeVariablesToBuffer. + @param[in] Size - This is the size of the binary representation + of the variables. + + @retval RETURN_SUCCESS - The binary representation was successfully + imported into a new variable serialization instance + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to + create the new variable serialization instance + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesNewInstanceFromBuffer ( + OUT EFI_HANDLE *Handle, + IN VOID *Buffer, + IN UINTN Size + ) +{ + RETURN_STATUS Status; + + Status =3D SerializeVariablesNewInstance (Handle); + if (RETURN_ERROR (Status)) { + return Status; + } + + Status =3D IterateVariablesInBuffer ( + IterateVariablesCallbackNop, + NULL, + Buffer, + Size + ); + if (RETURN_ERROR (Status)) { + SerializeVariablesFreeInstance (*Handle); + return Status; + } + + Status =3D IterateVariablesInBuffer ( + IterateVariablesCallbackSetInInstance, + (VOID*) *Handle, + Buffer, + Size + ); + if (RETURN_ERROR (Status)) { + SerializeVariablesFreeInstance (*Handle); + return Status; + } + + return Status; +} + + +/** + Iterates all variables found with RuntimeServices GetNextVariableName + + @param[in] CallbackFunction - Function called for each variable instan= ce + @param[in] Context - Passed to each call of CallbackFunction + + @retval RETURN_SUCCESS - All variables were iterated without the + CallbackFunction returning an error + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to + iterate through the variables + @return Any of RETURN_ERROR indicates an error reading the variable + or an error was returned from CallbackFunction + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesIterateSystemVariables ( + IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction, + IN VOID *Context + ) +{ + RETURN_STATUS Status; + UINTN VariableNameBufferSize; + UINTN VariableNameSize; + CHAR16 *VariableName; + EFI_GUID VendorGuid; + UINTN VariableDataBufferSize; + UINTN VariableDataSize; + VOID *VariableData; + UINT32 VariableAttributes; + VOID *NewBuffer; + + // + // Initialize the variable name and data buffer variables. + // + VariableNameBufferSize =3D sizeof (CHAR16); + VariableName =3D AllocateZeroPool (VariableNameBufferSize); + + VariableDataBufferSize =3D 0; + VariableData =3D NULL; + + for (;;) { + // + // Get the next variable name and guid + // + VariableNameSize =3D VariableNameBufferSize; + Status =3D gRT->GetNextVariableName ( + &VariableNameSize, + VariableName, + &VendorGuid + ); + if (Status =3D=3D EFI_BUFFER_TOO_SMALL) { + // + // The currently allocated VariableName buffer is too small, + // so we allocate a larger buffer, and copy the old buffer + // to it. + // + NewBuffer =3D AllocatePool (VariableNameSize); + if (NewBuffer =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + break; + } + CopyMem (NewBuffer, VariableName, VariableNameBufferSize); + if (VariableName !=3D NULL) { + FreePool (VariableName); + } + VariableName =3D NewBuffer; + VariableNameBufferSize =3D VariableNameSize; + + // + // Try to get the next variable name again with the larger buffer. + // + Status =3D gRT->GetNextVariableName ( + &VariableNameSize, + VariableName, + &VendorGuid + ); + } + + if (EFI_ERROR (Status)) { + if (Status =3D=3D EFI_NOT_FOUND) { + Status =3D EFI_SUCCESS; + } + break; + } + + // + // Get the variable data and attributes + // + VariableDataSize =3D VariableDataBufferSize; + Status =3D gRT->GetVariable ( + VariableName, + &VendorGuid, + &VariableAttributes, + &VariableDataSize, + VariableData + ); + if (Status =3D=3D EFI_BUFFER_TOO_SMALL) { + // + // The currently allocated VariableData buffer is too small, + // so we allocate a larger buffer. + // + if (VariableDataBufferSize !=3D 0) { + FreePool (VariableData); + VariableData =3D NULL; + VariableDataBufferSize =3D 0; + } + VariableData =3D AllocatePool (VariableDataSize); + if (VariableData =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + break; + } + VariableDataBufferSize =3D VariableDataSize; + + // + // Try to read the variable again with the larger buffer. + // + Status =3D gRT->GetVariable ( + VariableName, + &VendorGuid, + &VariableAttributes, + &VariableDataSize, + VariableData + ); + } + if (EFI_ERROR (Status)) { + break; + } + + // + // Run the callback function + // + Status =3D (*CallbackFunction) ( + Context, + VariableName, + &VendorGuid, + VariableAttributes, + VariableDataSize, + VariableData + ); + if (EFI_ERROR (Status)) { + break; + } + + } + + if (VariableName !=3D NULL) { + FreePool (VariableName); + } + + if (VariableData !=3D NULL) { + FreePool (VariableData); + } + + return Status; +} + + +/** + Iterates all variables found in the variable serialization instance + + @param[in] Handle - Handle for a variable serialization instance + @param[in] CallbackFunction - Function called for each variable instan= ce + @param[in] Context - Passed to each call of CallbackFunction + + @retval RETURN_SUCCESS - All variables were iterated without the + CallbackFunction returning an error + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to + iterate through the variables + @return Any of RETURN_ERROR indicates an error reading the variable + or an error was returned from CallbackFunction + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesIterateInstanceVariables ( + IN EFI_HANDLE Handle, + IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction, + IN VOID *Context + ) +{ + SV_INSTANCE *Instance; + + Instance =3D SV_FROM_HANDLE (Handle); + + if ((Instance->BufferPtr !=3D NULL) && (Instance->DataSize !=3D 0)) { + return IterateVariablesInBuffer ( + CallbackFunction, + Context, + Instance->BufferPtr, + Instance->DataSize + ); + } else { + return RETURN_SUCCESS; + } +} + + +/** + Sets all variables found in the variable serialization instance + + @param[in] Handle - Handle for a variable serialization instance + + @retval RETURN_SUCCESS - All variables were set successfully + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to + set all the variables + @return Any of RETURN_ERROR indicates an error reading the variables + or in attempting to set a variable + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesSetSerializedVariables ( + IN EFI_HANDLE Handle + ) +{ + return SerializeVariablesIterateInstanceVariables ( + Handle, + IterateVariablesCallbackSetSystemVariable, + NULL + ); +} + + +/** + Adds a variable to the variable serialization instance + + @param[in] Handle - Handle for a variable serialization instance + @param[in] VariableName - Refer to RuntimeServices GetVariable + @param[in] VendorGuid - Refer to RuntimeServices GetVariable + @param[in] Attributes - Refer to RuntimeServices GetVariable + @param[in] DataSize - Refer to RuntimeServices GetVariable + @param[in] Data - Refer to RuntimeServices GetVariable + + @retval RETURN_SUCCESS - All variables were set successfully + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to + add the variable + @retval RETURN_INVALID_PARAMETER - Handle was not a valid + variable serialization instance or + VariableName, VariableGuid or Data are NULL. + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesAddVariable ( + IN EFI_HANDLE Handle, + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ) +{ + RETURN_STATUS Status; + SV_INSTANCE *Instance; + UINT32 SerializedNameSize; + UINT32 SerializedDataSize; + UINTN SerializedSize; + + Instance =3D SV_FROM_HANDLE (Handle); + + if ((Instance->Signature !=3D SV_SIGNATURE) || + (VariableName =3D=3D NULL) || (VendorGuid =3D=3D NULL) || (Data =3D= =3D NULL)) { + } + + SerializedNameSize =3D (UINT32) StrSize (VariableName); + + SerializedSize =3D + sizeof (SerializedNameSize) + + SerializedNameSize + + sizeof (*VendorGuid) + + sizeof (Attributes) + + sizeof (SerializedDataSize) + + DataSize; + + Status =3D EnsureExtraBufferSpace ( + Instance, + SerializedSize + ); + if (RETURN_ERROR (Status)) { + return Status; + } + + // + // Add name size (UINT32) + // + AppendToBuffer (Instance, (VOID*) &SerializedNameSize, sizeof (Serialize= dNameSize)); + + // + // Add variable unicode name string + // + AppendToBuffer (Instance, (VOID*) VariableName, SerializedNameSize); + + // + // Add variable GUID + // + AppendToBuffer (Instance, (VOID*) VendorGuid, sizeof (*VendorGuid)); + + // + // Add variable attributes + // + AppendToBuffer (Instance, (VOID*) &Attributes, sizeof (Attributes)); + + // + // Add variable data size (UINT32) + // + SerializedDataSize =3D (UINT32) DataSize; + AppendToBuffer (Instance, (VOID*) &SerializedDataSize, sizeof (Serialize= dDataSize)); + + // + // Add variable data + // + AppendToBuffer (Instance, Data, DataSize); + + return RETURN_SUCCESS; +} + + +/** + Serializes the variables known to this instance into the + provided buffer. + + @param[in] Handle - Handle for a variable serialization instance + @param[out] Buffer - A buffer to store the binary representation + of the variables. + @param[in,out] Size - On input this is the size of the buffer. + On output this is the size of the binary representation + of the variables. + + @retval RETURN_SUCCESS - The binary representation was successfully + completed and returned in the buffer. + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to + save the variables to the buffer. + @retval RETURN_INVALID_PARAMETER - Handle was not a valid + variable serialization instance or + Size or Buffer were NULL. + @retval RETURN_BUFFER_TOO_SMALL - The Buffer size as indicated by + the Size parameter was too small for the serialized + variable data. Size is returned with the required size. + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesToBuffer ( + IN EFI_HANDLE Handle, + OUT VOID *Buffer, + IN OUT UINTN *Size + ) +{ + SV_INSTANCE *Instance; + + Instance =3D SV_FROM_HANDLE (Handle); + + if (Size =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (*Size < Instance->DataSize) { + *Size =3D Instance->DataSize; + return RETURN_BUFFER_TOO_SMALL; + } + + if (Buffer =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + *Size =3D Instance->DataSize; + CopyMem (Buffer, Instance->BufferPtr, Instance->DataSize); + + return RETURN_SUCCESS; +} + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicy= InitLib/SiliconPolicyInitLib.c b/Platform/Intel/SimicsOpenBoardPkg/Policy/L= ibrary/SiliconPolicyInitLib/SiliconPolicyInitLib.c new file mode 100644 index 0000000000..383501898d --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib= /SiliconPolicyInitLib.c @@ -0,0 +1,108 @@ +/** @file + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include + +/** + Performs silicon pre-mem policy initialization. + + The meaning of Policy is defined by silicon code. + It could be the raw data, a handle, a PPI, etc. + + The returned data must be used as input data for SiliconPolicyDonePreMem= (), + and SiliconPolicyUpdateLib.SiliconPolicyUpdatePreMem(). + + 1) In FSP path, the input Policy should be FspmUpd. + Value of FspmUpd has been initialized by FSP binary default value. + Only a subset of FspmUpd needs to be updated for different silicon sku. + The return data is same FspmUpd. + + 2) In non-FSP path, the input policy could be NULL. + The return data is the initialized policy. + + @param[in, out] Policy Pointer to policy. + + @return the initialized policy. +**/ +VOID * +EFIAPI +SiliconPolicyInitPreMem ( + IN OUT VOID *Policy OPTIONAL + ) +{ + return Policy; +} + +/* + The silicon pre-mem policy is finalized. + Silicon code can do initialization based upon the policy data. + + The input Policy must be returned by SiliconPolicyInitPreMem(). + + @param[in] Policy Pointer to policy. + + @retval RETURN_SUCCESS The policy is handled consumed by silicon code. +*/ +RETURN_STATUS +EFIAPI +SiliconPolicyDonePreMem ( + IN VOID *Policy + ) +{ + return RETURN_SUCCESS; +} + +/** + Performs silicon post-mem policy initialization. + + The meaning of Policy is defined by silicon code. + It could be the raw data, a handle, a PPI, etc. + + The returned data must be used as input data for SiliconPolicyDonePostMe= m(), + and SiliconPolicyUpdateLib.SiliconPolicyUpdatePostMem(). + + 1) In FSP path, the input Policy should be FspsUpd. + Value of FspsUpd has been initialized by FSP binary default value. + Only a subset of FspsUpd needs to be updated for different silicon sku. + The return data is same FspsUpd. + + 2) In non-FSP path, the input policy could be NULL. + The return data is the initialized policy. + + @param[in, out] Policy Pointer to policy. + + @return the initialized policy. +**/ +VOID * +EFIAPI +SiliconPolicyInitPostMem ( + IN OUT VOID *Policy OPTIONAL + ) +{ + return Policy; +} + +/* + The silicon post-mem policy is finalized. + Silicon code can do initialization based upon the policy data. + + The input Policy must be returned by SiliconPolicyInitPostMem(). + + @param[in] Policy Pointer to policy. + + @retval RETURN_SUCCESS The policy is handled consumed by silicon code. +*/ +RETURN_STATUS +EFIAPI +SiliconPolicyDonePostMem ( + IN VOID *Policy + ) +{ + return RETURN_SUCCESS; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicy= UpdateLib/SiliconPolicyUpdateLib.c b/Platform/Intel/SimicsOpenBoardPkg/Poli= cy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.c new file mode 100644 index 0000000000..3b207a4e78 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateL= ib/SiliconPolicyUpdateLib.c @@ -0,0 +1,70 @@ +/** @file + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include + +#include +#include +#include +#include + +/** + Performs silicon pre-mem policy update. + + The meaning of Policy is defined by silicon code. + It could be the raw data, a handle, a PPI, etc. + + The input Policy must be returned by SiliconPolicyDonePreMem(). + + 1) In FSP path, the input Policy should be FspmUpd. + A platform may use this API to update the FSPM UPD policy initialized + by the silicon module or the default UPD data. + The output of FSPM UPD data from this API is the final UPD data. + + 2) In non-FSP path, the board may use additional way to get + the silicon policy data field based upon the input Policy. + + @param[in, out] Policy Pointer to policy. + + @return the updated policy. +**/ +VOID * +EFIAPI +SiliconPolicyUpdatePreMem ( + IN OUT VOID *Policy + ) +{ + return Policy; +} + +/** + Performs silicon post-mem policy update. + + The meaning of Policy is defined by silicon code. + It could be the raw data, a handle, a PPI, etc. + + The input Policy must be returned by SiliconPolicyDonePostMem(). + + 1) In FSP path, the input Policy should be FspsUpd. + A platform may use this API to update the FSPS UPD policy initialized + by the silicon module or the default UPD data. + The output of FSPS UPD data from this API is the final UPD data. + + 2) In non-FSP path, the board may use additional way to get + the silicon policy data field based upon the input Policy. + + @param[in, out] Policy Pointer to policy. + + @return the updated policy. +**/ +VOID * +EFIAPI +SiliconPolicyUpdatePostMem ( + IN OUT VOID *Policy + ) +{ + return Policy; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.c b/Platform= /Intel/SimicsOpenBoardPkg/SecCore/SecMain.c new file mode 100644 index 0000000000..5cbb47687b --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.c @@ -0,0 +1,956 @@ +/** @file + Main SEC phase code. Transitions to PEI. + + Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2016 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define SEC_IDT_ENTRY_COUNT 34 + +typedef struct _SEC_IDT_TABLE { + EFI_PEI_SERVICES *PeiService; + IA32_IDT_GATE_DESCRIPTOR IdtTable[SEC_IDT_ENTRY_COUNT]; +} SEC_IDT_TABLE; + +VOID +EFIAPI +SecStartupPhase2 ( + IN VOID *Context + ); + +EFI_STATUS +EFIAPI +TemporaryRamMigration ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ); + +EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi =3D { + TemporaryRamMigration +}; + +EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] =3D { + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiTemporaryRamSupportPpiGuid, + &mTemporaryRamSupportPpi + }, +}; + +// +// Template of an IDT entry pointing to 10:FFFFFFE4h. +// +IA32_IDT_GATE_DESCRIPTOR mIdtEntryTemplate =3D { + { // Bits + 0xffe4, // OffsetLow + 0x10, // Selector + 0x0, // Reserved_0 + IA32_IDT_GATE_TYPE_INTERRUPT_32, // GateType + 0xffff // OffsetHigh + } +}; + +/** + Locates the main boot firmware volume. + + @param[in,out] BootFv On input, the base of the BootFv + On output, the decompressed main firmware volume + + @retval EFI_SUCCESS The main firmware volume was located and decompre= ssed + @retval EFI_NOT_FOUND The main firmware volume was not found + +**/ +EFI_STATUS +FindMainFv ( + IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv + ) +{ + EFI_FIRMWARE_VOLUME_HEADER *Fv; + UINTN Distance; + + ASSERT (((UINTN) *BootFv & EFI_PAGE_MASK) =3D=3D 0); + + Fv =3D *BootFv; + Distance =3D (UINTN) (*BootFv)->FvLength; + do { + Fv =3D (EFI_FIRMWARE_VOLUME_HEADER*) ((UINT8*) Fv - EFI_PAGE_SIZE); + Distance +=3D EFI_PAGE_SIZE; + if (Distance > SIZE_32MB) { + return EFI_NOT_FOUND; + } + + if (Fv->Signature !=3D EFI_FVH_SIGNATURE) { + continue; + } + + if ((UINTN) Fv->FvLength > Distance) { + continue; + } + + *BootFv =3D Fv; + return EFI_SUCCESS; + + } while (TRUE); +} + +/** + Locates a section within a series of sections + with the specified section type. + + The Instance parameter indicates which instance of the section + type to return. (0 is first instance, 1 is second...) + + @param[in] Sections The sections to search + @param[in] SizeOfSections Total size of all sections + @param[in] SectionType The section type to locate + @param[in] Instance The section instance number + @param[out] FoundSection The FFS section if found + + @retval EFI_SUCCESS The file and section was found + @retval EFI_NOT_FOUND The file and section was not found + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted + +**/ +EFI_STATUS +FindFfsSectionInstance ( + IN VOID *Sections, + IN UINTN SizeOfSections, + IN EFI_SECTION_TYPE SectionType, + IN UINTN Instance, + OUT EFI_COMMON_SECTION_HEADER **FoundSection + ) +{ + EFI_PHYSICAL_ADDRESS CurrentAddress; + UINT32 Size; + EFI_PHYSICAL_ADDRESS EndOfSections; + EFI_COMMON_SECTION_HEADER *Section; + EFI_PHYSICAL_ADDRESS EndOfSection; + + // + // Loop through the FFS file sections within the PEI Core FFS file + // + EndOfSection =3D (EFI_PHYSICAL_ADDRESS)(UINTN) Sections; + EndOfSections =3D EndOfSection + SizeOfSections; + for (;;) { + if (EndOfSection =3D=3D EndOfSections) { + break; + } + CurrentAddress =3D (EndOfSection + 3) & ~(3ULL); + if (CurrentAddress >=3D EndOfSections) { + return EFI_VOLUME_CORRUPTED; + } + + Section =3D (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress; + DEBUG ((EFI_D_VERBOSE, "Section->Type: 0x%x\n", Section->Type)); + + Size =3D SECTION_SIZE (Section); + if (Size < sizeof (*Section)) { + return EFI_VOLUME_CORRUPTED; + } + + EndOfSection =3D CurrentAddress + Size; + if (EndOfSection > EndOfSections) { + return EFI_VOLUME_CORRUPTED; + } + + // + // Look for the requested section type + // + if (Section->Type =3D=3D SectionType) { + if (Instance =3D=3D 0) { + *FoundSection =3D Section; + return EFI_SUCCESS; + } else { + Instance--; + } + } + DEBUG ((EFI_D_VERBOSE, "Section->Type (0x%x) !=3D SectionType (0x%x)\n= ", Section->Type, SectionType)); + } + + return EFI_NOT_FOUND; +} + +/** + Locates a section within a series of sections + with the specified section type. + + @param[in] Sections The sections to search + @param[in] SizeOfSections Total size of all sections + @param[in] SectionType The section type to locate + @param[out] FoundSection The FFS section if found + + @retval EFI_SUCCESS The file and section was found + @retval EFI_NOT_FOUND The file and section was not found + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted + +**/ +EFI_STATUS +FindFfsSectionInSections ( + IN VOID *Sections, + IN UINTN SizeOfSections, + IN EFI_SECTION_TYPE SectionType, + OUT EFI_COMMON_SECTION_HEADER **FoundSection + ) +{ + return FindFfsSectionInstance ( + Sections, + SizeOfSections, + SectionType, + 0, + FoundSection + ); +} + +/** + Locates a FFS file with the specified file type and a section + within that file with the specified section type. + + @param[in] Fv The firmware volume to search + @param[in] FileType The file type to locate + @param[in] SectionType The section type to locate + @param[out] FoundSection The FFS section if found + + @retval EFI_SUCCESS The file and section was found + @retval EFI_NOT_FOUND The file and section was not found + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted + +**/ +EFI_STATUS +FindFfsFileAndSection ( + IN EFI_FIRMWARE_VOLUME_HEADER *Fv, + IN EFI_FV_FILETYPE FileType, + IN EFI_SECTION_TYPE SectionType, + OUT EFI_COMMON_SECTION_HEADER **FoundSection + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS CurrentAddress; + EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume; + EFI_FFS_FILE_HEADER *File; + UINT32 Size; + EFI_PHYSICAL_ADDRESS EndOfFile; + + if (Fv->Signature !=3D EFI_FVH_SIGNATURE) { + DEBUG ((EFI_D_ERROR, "FV at %p does not have FV header signature\n", F= v)); + return EFI_VOLUME_CORRUPTED; + } + + CurrentAddress =3D (EFI_PHYSICAL_ADDRESS)(UINTN) Fv; + EndOfFirmwareVolume =3D CurrentAddress + Fv->FvLength; + + // + // Loop through the FFS files in the Boot Firmware Volume + // + for (EndOfFile =3D CurrentAddress + Fv->HeaderLength; ; ) { + + CurrentAddress =3D (EndOfFile + 7) & ~(7ULL); + if (CurrentAddress > EndOfFirmwareVolume) { + return EFI_VOLUME_CORRUPTED; + } + + File =3D (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress; + Size =3D *(UINT32*) File->Size & 0xffffff; + if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) { + return EFI_VOLUME_CORRUPTED; + } + DEBUG ((EFI_D_VERBOSE, "File->Type: 0x%x\n", File->Type)); + + EndOfFile =3D CurrentAddress + Size; + if (EndOfFile > EndOfFirmwareVolume) { + return EFI_VOLUME_CORRUPTED; + } + + // + // Look for the request file type + // + if (File->Type !=3D FileType) { + DEBUG ((EFI_D_VERBOSE, "File->Type (0x%x) !=3D FileType (0x%x)\n", F= ile->Type, FileType)); + continue; + } + + Status =3D FindFfsSectionInSections ( + (VOID*) (File + 1), + (UINTN) EndOfFile - (UINTN) (File + 1), + SectionType, + FoundSection + ); + if (!EFI_ERROR (Status) || (Status =3D=3D EFI_VOLUME_CORRUPTED)) { + return Status; + } + } +} + +/** + Locates the compressed main firmware volume and decompresses it. + + @param[in,out] Fv On input, the firmware volume to search + On output, the decompressed BOOT/PEI FV + + @retval EFI_SUCCESS The file and section was found + @retval EFI_NOT_FOUND The file and section was not found + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted + +**/ +EFI_STATUS +DecompressMemFvs ( + IN OUT EFI_FIRMWARE_VOLUME_HEADER **Fv + ) +{ + EFI_STATUS Status; + EFI_GUID_DEFINED_SECTION *Section; + UINT32 OutputBufferSize; + UINT32 ScratchBufferSize; + UINT16 SectionAttribute; + UINT32 AuthenticationStatus; + VOID *OutputBuffer; + VOID *ScratchBuffer; + EFI_COMMON_SECTION_HEADER *FvSection; + EFI_FIRMWARE_VOLUME_HEADER *PeiMemFv; + EFI_FIRMWARE_VOLUME_HEADER *DxeMemFv; + UINT32 FvHeaderSize; + UINT32 FvSectionSize; + + FvSection =3D (EFI_COMMON_SECTION_HEADER*) NULL; + + DEBUG ((EFI_D_VERBOSE, "Find and decompress FV image.\n")); + Status =3D FindFfsFileAndSection ( + *Fv, + EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, + EFI_SECTION_GUID_DEFINED, + (EFI_COMMON_SECTION_HEADER**) &Section + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Unable to find GUID defined section\n")); + return Status; + } + + Status =3D ExtractGuidedSectionGetInfo ( + Section, + &OutputBufferSize, + &ScratchBufferSize, + &SectionAttribute + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Unable to GetInfo for GUIDed section\n")); + return Status; + } + + OutputBuffer =3D (VOID*) ((UINT8*)(UINTN) PcdGet32 (PcdSimicsDxeMemFvBas= e) + SIZE_1MB); + ScratchBuffer =3D ALIGN_POINTER ((UINT8*) OutputBuffer + OutputBufferSiz= e, SIZE_1MB); + + DEBUG ((EFI_D_VERBOSE, "PcdSimicsDxeMemFvBase: 0x%x\n", PcdGet32 (PcdSim= icsDxeMemFvBase))); + DEBUG ((EFI_D_VERBOSE, "OutputBuffer: 0x%x\n", OutputBuffer)); + DEBUG ((EFI_D_VERBOSE, "OutputBufferSize: 0x%x\n", OutputBufferSize)); + DEBUG ((EFI_D_VERBOSE, "ScratchBuffer: 0x%x\n", ScratchBuffer)); + DEBUG ((EFI_D_VERBOSE, "ScratchBufferSize: 0x%x\n", ScratchBufferSize)); + DEBUG ((EFI_D_VERBOSE, "PcdSimicsDecompressionScratchEnd: 0x%x\n", PcdGe= t32 (PcdSimicsDecompressionScratchEnd))); + + DEBUG ((EFI_D_VERBOSE, "%a: OutputBuffer@%p+0x%x ScratchBuffer@%p+0x%x " + "PcdSimicsDecompressionScratchEnd=3D0x%x\n", __FUNCTION__, OutputBuffe= r, + OutputBufferSize, ScratchBuffer, ScratchBufferSize, + PcdGet32 (PcdSimicsDecompressionScratchEnd))); + ASSERT ((UINTN)ScratchBuffer + ScratchBufferSize =3D=3D + PcdGet32 (PcdSimicsDecompressionScratchEnd)); + + Status =3D ExtractGuidedSectionDecode ( + Section, + &OutputBuffer, + ScratchBuffer, + &AuthenticationStatus + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Error during GUID section decode\n")); + return Status; + } + + Status =3D FindFfsSectionInstance ( + OutputBuffer, + OutputBufferSize, + EFI_SECTION_FIRMWARE_VOLUME_IMAGE, + 0, + &FvSection + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Unable to find PEI FV section\n")); + return Status; + } + + ASSERT (SECTION_SIZE (FvSection) =3D=3D + (PcdGet32 (PcdSimicsPeiMemFvSize) + sizeof (*FvSection))); + ASSERT (FvSection->Type =3D=3D EFI_SECTION_FIRMWARE_VOLUME_IMAGE); + + PeiMemFv =3D (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdSimicsPei= MemFvBase); + CopyMem (PeiMemFv, (VOID*) (FvSection + 1), PcdGet32 (PcdSimicsPeiMemFvS= ize)); + + if (PeiMemFv->Signature !=3D EFI_FVH_SIGNATURE) { + DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header signa= ture\n", PeiMemFv)); + CpuDeadLoop (); + return EFI_VOLUME_CORRUPTED; + } + + Status =3D FindFfsSectionInstance ( + OutputBuffer, + OutputBufferSize, + EFI_SECTION_FIRMWARE_VOLUME_IMAGE, + 1, + &FvSection + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Unable to find DXE FV section\n")); + return Status; + } + + ASSERT (FvSection->Type =3D=3D EFI_SECTION_FIRMWARE_VOLUME_IMAGE); + + if (IS_SECTION2 (FvSection)) { + FvSectionSize =3D SECTION2_SIZE (FvSection); + FvHeaderSize =3D sizeof (EFI_COMMON_SECTION_HEADER2); + } else { + FvSectionSize =3D SECTION_SIZE (FvSection); + FvHeaderSize =3D sizeof (EFI_COMMON_SECTION_HEADER); + } + + ASSERT (FvSectionSize =3D=3D (PcdGet32 (PcdSimicsDxeMemFvSize) + FvHeade= rSize)); + + DxeMemFv =3D (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdSimicsDxe= MemFvBase); + CopyMem (DxeMemFv, (VOID*) ((UINTN)FvSection + FvHeaderSize), PcdGet32 (= PcdSimicsDxeMemFvSize)); + + if (DxeMemFv->Signature !=3D EFI_FVH_SIGNATURE) { + DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header signa= ture\n", DxeMemFv)); + CpuDeadLoop (); + return EFI_VOLUME_CORRUPTED; + } + + *Fv =3D PeiMemFv; + return EFI_SUCCESS; +} + +/** + Locates the PEI Core entry point address + + @param[in] Fv The firmware volume to search + @param[out] PeiCoreEntryPoint The entry point of the PEI Core image + + @retval EFI_SUCCESS The file and section was found + @retval EFI_NOT_FOUND The file and section was not found + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted + +**/ +EFI_STATUS +FindPeiCoreImageBaseInFv ( + IN EFI_FIRMWARE_VOLUME_HEADER *Fv, + OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase + ) +{ + EFI_STATUS Status; + EFI_COMMON_SECTION_HEADER *Section; + + DEBUG ((EFI_D_VERBOSE, "Find PEI Core image.\n")); + Status =3D FindFfsFileAndSection ( + Fv, + EFI_FV_FILETYPE_PEI_CORE, + EFI_SECTION_PE32, + &Section + ); + if (EFI_ERROR (Status)) { + Status =3D FindFfsFileAndSection ( + Fv, + EFI_FV_FILETYPE_PEI_CORE, + EFI_SECTION_TE, + &Section + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Unable to find PEI Core image\n")); + return Status; + } + } + + *PeiCoreImageBase =3D (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1); + DEBUG ((EFI_D_VERBOSE, "PEI core image base 0x%016LX.\n", *PeiCoreImageB= ase)); + return EFI_SUCCESS; +} + + +/** + Reads 8-bits of CMOS data. + + Reads the 8-bits of CMOS data at the location specified by Index. + The 8-bit read value is returned. + + @param Index The CMOS location to read. + + @return The value read. + +**/ +STATIC +UINT8 +CmosRead8 ( + IN UINTN Index + ) +{ + IoWrite8 (0x70, (UINT8) Index); + return IoRead8 (0x71); +} + + +STATIC +BOOLEAN +IsS3Resume ( + VOID + ) +{ + DEBUG((EFI_D_VERBOSE, "modeValue =3D %x\n", IoBitFieldRead16(ICH10_PMBAS= E_IO + 4, 10, 12))); + return (IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12) =3D=3D 0x5); +} + + +STATIC +EFI_STATUS +GetS3ResumePeiFv ( + IN OUT EFI_FIRMWARE_VOLUME_HEADER **PeiFv + ) +{ + *PeiFv =3D (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdSimicsPeiMe= mFvBase); + return EFI_SUCCESS; +} + + +/** + Locates the PEI Core entry point address + + @param[in,out] Fv The firmware volume to search + @param[out] PeiCoreEntryPoint The entry point of the PEI Core image + + @retval EFI_SUCCESS The file and section was found + @retval EFI_NOT_FOUND The file and section was not found + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted + +**/ +VOID +FindPeiCoreImageBase ( + IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv, + OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase + ) +{ + BOOLEAN S3Resume; + + *PeiCoreImageBase =3D 0; + + S3Resume =3D IsS3Resume (); + if (S3Resume && !FeaturePcdGet (PcdSmmSmramRequire)) { + // + // A malicious runtime OS may have injected something into our previou= sly + // decoded PEI FV, but we don't care about that unless SMM/SMRAM is re= quired. + // + DEBUG ((EFI_D_VERBOSE, "SEC: S3 resume\n")); + GetS3ResumePeiFv (BootFv); + } else { + // + // We're either not resuming, or resuming "securely" -- we'll decompre= ss + // both PEI FV and DXE FV from pristine flash. + // + DEBUG ((EFI_D_VERBOSE, "SEC: %a\n", + S3Resume ? "S3 resume (with PEI decompression)" : "Normal boot")); + FindMainFv (BootFv); + + DecompressMemFvs (BootFv); + } + + FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase); +} + +/** + Find core image base. + +**/ +EFI_STATUS +FindImageBase ( + IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr, + OUT EFI_PHYSICAL_ADDRESS *SecCoreImageBase + ) +{ + EFI_PHYSICAL_ADDRESS CurrentAddress; + EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume; + EFI_FFS_FILE_HEADER *File; + UINT32 Size; + EFI_PHYSICAL_ADDRESS EndOfFile; + EFI_COMMON_SECTION_HEADER *Section; + EFI_PHYSICAL_ADDRESS EndOfSection; + + *SecCoreImageBase =3D 0; + + CurrentAddress =3D (EFI_PHYSICAL_ADDRESS)(UINTN) BootFirmwareVolumePtr; + EndOfFirmwareVolume =3D CurrentAddress + BootFirmwareVolumePtr->FvLength; + + // + // Loop through the FFS files in the Boot Firmware Volume + // + for (EndOfFile =3D CurrentAddress + BootFirmwareVolumePtr->HeaderLength;= ; ) { + + CurrentAddress =3D (EndOfFile + 7) & 0xfffffffffffffff8ULL; + if (CurrentAddress > EndOfFirmwareVolume) { + return EFI_NOT_FOUND; + } + + File =3D (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress; + Size =3D *(UINT32*) File->Size & 0xffffff; + if (Size < sizeof (*File)) { + return EFI_NOT_FOUND; + } + + EndOfFile =3D CurrentAddress + Size; + if (EndOfFile > EndOfFirmwareVolume) { + return EFI_NOT_FOUND; + } + + // + // Look for SEC Core + // + if (File->Type !=3D EFI_FV_FILETYPE_SECURITY_CORE) { + continue; + } + + // + // Loop through the FFS file sections within the FFS file + // + EndOfSection =3D (EFI_PHYSICAL_ADDRESS)(UINTN) (File + 1); + for (;;) { + CurrentAddress =3D (EndOfSection + 3) & 0xfffffffffffffffcULL; + Section =3D (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress; + + Size =3D *(UINT32*) Section->Size & 0xffffff; + if (Size < sizeof (*Section)) { + return EFI_NOT_FOUND; + } + + EndOfSection =3D CurrentAddress + Size; + if (EndOfSection > EndOfFile) { + return EFI_NOT_FOUND; + } + + // + // Look for executable sections + // + if (Section->Type =3D=3D EFI_SECTION_PE32 || Section->Type =3D=3D EF= I_SECTION_TE) { + if (File->Type =3D=3D EFI_FV_FILETYPE_SECURITY_CORE) { + *SecCoreImageBase =3D (PHYSICAL_ADDRESS) (UINTN) (Section + 1); + } + break; + } + } + + // + // SEC Core image found + // + if (*SecCoreImageBase !=3D 0) { + return EFI_SUCCESS; + } + } +} + +/* + Find and return Pei Core entry point. + + It also find SEC and PEI Core file debug information. It will report the= m if + remote debug is enabled. + +**/ +VOID +FindAndReportEntryPoints ( + IN EFI_FIRMWARE_VOLUME_HEADER **BootFirmwareVolumePtr, + OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS SecCoreImageBase; + EFI_PHYSICAL_ADDRESS PeiCoreImageBase; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + + // + // Find SEC Core and PEI Core image base + // + Status =3D FindImageBase (*BootFirmwareVolumePtr, &SecCoreImageBase); + ASSERT_EFI_ERROR (Status); + + FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase); + + ZeroMem ((VOID *) &ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT)); + // + // Report SEC Core debug information when remote debug is enabled + // + ImageContext.ImageAddress =3D SecCoreImageBase; + ImageContext.PdbPointer =3D PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) I= mageContext.ImageAddress); + PeCoffLoaderRelocateImageExtraAction (&ImageContext); + + // + // Report PEI Core debug information when remote debug is enabled + // + ImageContext.ImageAddress =3D (EFI_PHYSICAL_ADDRESS)(UINTN)PeiCoreImageB= ase; + ImageContext.PdbPointer =3D PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) I= mageContext.ImageAddress); + PeCoffLoaderRelocateImageExtraAction (&ImageContext); + + // + // Find PEI Core entry point + // + Status =3D PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase,= (VOID**) PeiCoreEntryPoint); + if (EFI_ERROR (Status)) { + *PeiCoreEntryPoint =3D 0; + } + + return; +} + +VOID +EFIAPI +SecCoreStartupWithStack ( + IN EFI_FIRMWARE_VOLUME_HEADER *BootFv, + IN VOID *TopOfCurrentStack + ) +{ + EFI_SEC_PEI_HAND_OFF SecCoreData; + SEC_IDT_TABLE IdtTableInStack; + IA32_DESCRIPTOR IdtDescriptor; + UINT32 Index; + volatile UINT8 *Table; + + // + // Initialize floating point operating environment + // to be compliant with UEFI spec. + // + InitializeFloatingPointUnits (); + + // + // Initialize the PCIe Configuration base register. + // + PciCf8Write32 (PCI_CF8_LIB_ADDRESS (0xFF, 0, 1, 0x50), 0xE0000001); + + // + // To ensure SMM can't be compromised on S3 resume, we must force re-ini= t of + // the BaseExtractGuidedSectionLib. Since this is before library contruc= tors + // are called, we must use a loop rather than SetMem. + // + Table =3D (UINT8*)(UINTN)FixedPcdGet64 (PcdGuidedExtractHandlerTableAddr= ess); + for (Index =3D 0; + Index < FixedPcdGet32 (PcdGuidedExtractHandlerTableSize); + ++Index) { + Table[Index] =3D 0; + } + + ProcessLibraryConstructorList (NULL, NULL); + + DEBUG ((EFI_D_INFO, + "SecCoreStartupWithStack(0x%x, 0x%x)\n", + (UINT32)(UINTN)BootFv, + (UINT32)(UINTN)TopOfCurrentStack + )); + + // + // Initialize IDT + // + IdtTableInStack.PeiService =3D NULL; + for (Index =3D 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) { + CopyMem (&IdtTableInStack.IdtTable[Index], &mIdtEntryTemplate, sizeof = (mIdtEntryTemplate)); + } + + IdtDescriptor.Base =3D (UINTN)&IdtTableInStack.IdtTable; + IdtDescriptor.Limit =3D (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1); + + AsmWriteIdtr (&IdtDescriptor); + +#if defined (MDE_CPU_X64) + // + // ASSERT that the Page Tables were set by the reset vector code to + // the address we expect. + // + ASSERT (AsmReadCr3 () =3D=3D (UINTN) PcdGet32 (PcdSimicsSecPageTablesBas= e)); +#endif + + // + // |-------------| <-- TopOfCurrentStack + // | Stack | 32k + // |-------------| + // | Heap | 32k + // |-------------| <-- SecCoreData.TemporaryRamBase + // + + ASSERT ((UINTN) (PcdGet32 (PcdSimicsSecPeiTempRamBase) + + PcdGet32 (PcdSimicsSecPeiTempRamSize)) =3D=3D + (UINTN) TopOfCurrentStack); + + // + // Initialize SEC hand-off state + // + SecCoreData.DataSize =3D sizeof(EFI_SEC_PEI_HAND_OFF); + + SecCoreData.TemporaryRamSize =3D (UINTN) PcdGet32 (PcdSimicsSecPei= TempRamSize); + SecCoreData.TemporaryRamBase =3D (VOID*)((UINT8 *)TopOfCurrentStac= k - SecCoreData.TemporaryRamSize); + + SecCoreData.PeiTemporaryRamBase =3D SecCoreData.TemporaryRamBase; + SecCoreData.PeiTemporaryRamSize =3D SecCoreData.TemporaryRamSize >> 1; + + SecCoreData.StackBase =3D (UINT8 *)SecCoreData.TemporaryRam= Base + SecCoreData.PeiTemporaryRamSize; + SecCoreData.StackSize =3D SecCoreData.TemporaryRamSize >> 1; + + SecCoreData.BootFirmwareVolumeBase =3D BootFv; + SecCoreData.BootFirmwareVolumeSize =3D (UINTN) BootFv->FvLength; + + // + // Make sure the 8259 is masked before initializing the Debug Agent and = the debug timer is enabled + // + IoWrite8 (0x21, 0xff); + IoWrite8 (0xA1, 0xff); + + // + // Initialize Local APIC Timer hardware and disable Local APIC Timer + // interrupts before initializing the Debug Agent and the debug timer is + // enabled. + // + InitializeApicTimer (0, MAX_UINT32, TRUE, 5); + DisableApicTimerInterrupt (); + + // + // Initialize Debug Agent to support source level debug in SEC/PEI phase= s before memory ready. + // + InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData, SecStar= tupPhase2); +} + +/** + Caller provided function to be invoked at the end of InitializeDebugAgen= t(). + + Entry point to the C language phase of SEC. After the SEC assembly + code has initialized some temporary memory and set up the stack, + the control is transferred to this function. + + @param[in] Context The first input parameter of InitializeDebugAgent(= ). + +**/ +VOID +EFIAPI +SecStartupPhase2( + IN VOID *Context + ) +{ + EFI_SEC_PEI_HAND_OFF *SecCoreData; + EFI_FIRMWARE_VOLUME_HEADER *BootFv; + EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint; + + SecCoreData =3D (EFI_SEC_PEI_HAND_OFF *) Context; + + // + // Find PEI Core entry point. It will report SEC and Pei Core debug info= rmation if remote debug + // is enabled. + // + BootFv =3D (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolume= Base; + FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint); + SecCoreData->BootFirmwareVolumeBase =3D BootFv; + SecCoreData->BootFirmwareVolumeSize =3D (UINTN) BootFv->FvLength; + + // + // Transfer the control to the PEI core + // + (*PeiCoreEntryPoint) (SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDi= spatchTable); + + // + // If we get here then the PEI Core returned, which is not recoverable. + // + ASSERT (FALSE); + CpuDeadLoop (); +} + +EFI_STATUS +EFIAPI +TemporaryRamMigration ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ) +{ + IA32_DESCRIPTOR IdtDescriptor; + VOID *OldHeap; + VOID *NewHeap; + VOID *OldStack; + VOID *NewStack; + DEBUG_AGENT_CONTEXT_POSTMEM_SEC DebugAgentContext; + BOOLEAN OldStatus; + BASE_LIBRARY_JUMP_BUFFER JumpBuffer; + + DEBUG ((EFI_D_INFO, + "TemporaryRamMigration(0x%Lx, 0x%Lx, 0x%Lx)\n", + TemporaryMemoryBase, + PermanentMemoryBase, + (UINT64)CopySize + )); + + OldHeap =3D (VOID*)(UINTN)TemporaryMemoryBase; + NewHeap =3D (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1)); + + OldStack =3D (VOID*)((UINTN)TemporaryMemoryBase + (CopySize >> 1)); + NewStack =3D (VOID*)(UINTN)PermanentMemoryBase; + + DebugAgentContext.HeapMigrateOffset =3D (UINTN)NewHeap - (UINTN)OldHeap; + DebugAgentContext.StackMigrateOffset =3D (UINTN)NewStack - (UINTN)OldSta= ck; + + OldStatus =3D SaveAndSetDebugTimerInterrupt (FALSE); + InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *) &DebugAgent= Context, NULL); + + // + // Migrate Heap + // + CopyMem (NewHeap, OldHeap, CopySize >> 1); + + // + // Migrate Stack + // + CopyMem (NewStack, OldStack, CopySize >> 1); + + // + // Rebase IDT table in permanent memory + // + AsmReadIdtr (&IdtDescriptor); + IdtDescriptor.Base =3D IdtDescriptor.Base - (UINTN)OldStack + (UINTN)New= Stack; + + AsmWriteIdtr (&IdtDescriptor); + + // + // Use SetJump()/LongJump() to switch to a new stack. + // + if (SetJump (&JumpBuffer) =3D=3D 0) { +#if defined (MDE_CPU_IA32) + JumpBuffer.Esp =3D JumpBuffer.Esp + DebugAgentContext.StackMigrateOffs= et; +#endif +#if defined (MDE_CPU_X64) + JumpBuffer.Rsp =3D JumpBuffer.Rsp + DebugAgentContext.StackMigrateOffs= et; +#endif + LongJump (&JumpBuffer, (UINTN)-1); + } + + SaveAndSetDebugTimerInterrupt (OldStatus); + + return EFI_SUCCESS; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.c b/Platf= orm/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.c new file mode 100644 index 0000000000..b7fd4d1f6d --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.c @@ -0,0 +1,865 @@ +/** @file + This driver effectuates QSP platform configuration settings and exposes + them via HII. + + Copyright (C) 2014, Red Hat, Inc. + Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Platform.h" +#include "PlatformConfig.h" +#include +// +// The HiiAddPackages() library function requires that any controller (or +// image) handle, to be associated with the HII packages under installatio= n, be +// "decorated" with a device path. The tradition seems to be a vendor devi= ce +// path. +// +// We'd like to associate our HII packages with the driver's image handle.= The +// first idea is to use the driver image's device path. Unfortunately, loa= ded +// images only come with an EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL (not the +// usual EFI_DEVICE_PATH_PROTOCOL), ie. a different GUID. In addition, eve= n the +// EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL interface may be NULL, if the ima= ge +// has been loaded from an "unnamed" memory source buffer. +// +// Hence let's just stick with the tradition -- use a dedicated vendor dev= ice +// path, with the driver's FILE_GUID. +// +#pragma pack(1) +typedef struct { + VENDOR_DEVICE_PATH VendorDevicePath; + EFI_DEVICE_PATH_PROTOCOL End; +} PKG_DEVICE_PATH; +#pragma pack() + +STATIC PKG_DEVICE_PATH mPkgDevicePath =3D { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8) (sizeof (VENDOR_DEVICE_PATH) ), + (UINT8) (sizeof (VENDOR_DEVICE_PATH) >> 8) + } + }, + EFI_CALLER_ID_GUID + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + (UINT8) (END_DEVICE_PATH_LENGTH ), + (UINT8) (END_DEVICE_PATH_LENGTH >> 8) + } + } +}; + +// +// The configuration interface between the HII engine (form display etc) a= nd +// this driver. +// +STATIC EFI_HII_CONFIG_ACCESS_PROTOCOL mConfigAccess; + +// +// The handle representing our list of packages after installation. +// +STATIC EFI_HII_HANDLE mInstalledPackages; + +// +// The arrays below constitute our HII package list. They are auto-generat= ed by +// the VFR compiler and linked into the driver image during the build. +// +// - The strings package receives its C identifier from the driver's BASE_= NAME, +// plus "Strings". +// +// - The forms package receives its C identifier from the VFR file's basen= ame, +// plus "Bin". +// +// +extern UINT8 SimicsDxeStrings[]; +extern UINT8 PlatformFormsBin[]; + +// +// We want to be notified about GOP installations until we find one GOP +// interface that lets us populate the form. +// +STATIC EFI_EVENT mGopEvent; + +// +// The registration record underneath this pointer allows us to iterate th= rough +// the GOP instances one by one. +// +STATIC VOID *mGopTracker; + +// +// Cache the resolutions we get from the GOP. +// +typedef struct { + UINT32 X; + UINT32 Y; +} GOP_MODE; + +STATIC UINTN mNumGopModes; +STATIC GOP_MODE *mGopModes; + + +/** + Load the persistent platform configuration and translate it to binary fo= rm + state. + + If the platform configuration is missing, then the function fills in a + default state. + + @param[out] MainFormState Binary form/widget state after translation. + + @retval EFI_SUCCESS Form/widget state ready. + @return Error codes from underlying functions. +**/ +STATIC +EFI_STATUS +EFIAPI +PlatformConfigToFormState ( + OUT MAIN_FORM_STATE *MainFormState + ) +{ + EFI_STATUS Status; + PLATFORM_CONFIG PlatformConfig; + UINT64 OptionalElements; + UINTN ModeNumber; + + ZeroMem (MainFormState, sizeof *MainFormState); + + Status =3D PlatformConfigLoad (&PlatformConfig, &OptionalElements); + switch (Status) { + case EFI_SUCCESS: + if (OptionalElements & PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION) { + // + // Format the preferred resolution as text. + // + UnicodeSPrintAsciiFormat ( + (CHAR16 *) MainFormState->CurrentPreferredResolution, + sizeof MainFormState->CurrentPreferredResolution, + "%Ldx%Ld", + (INT64) PlatformConfig.HorizontalResolution, + (INT64) PlatformConfig.VerticalResolution); + + // + // Try to locate it in the drop-down list too. This may not succeed,= but + // that's fine. + // + for (ModeNumber =3D 0; ModeNumber < mNumGopModes; ++ModeNumber) { + if (mGopModes[ModeNumber].X =3D=3D PlatformConfig.HorizontalResolu= tion && + mGopModes[ModeNumber].Y =3D=3D PlatformConfig.VerticalResoluti= on) { + MainFormState->NextPreferredResolution =3D (UINT32) ModeNumber; + break; + } + } + + break; + } + // + // fall through otherwise + // + + case EFI_NOT_FOUND: + UnicodeSPrintAsciiFormat ( + (CHAR16 *) MainFormState->CurrentPreferredResolution, + sizeof MainFormState->CurrentPreferredResolution, + "Unset"); + break; + + default: + return Status; + } + + return EFI_SUCCESS; +} + + +/** + This function is called by the HII machinery when it fetches the form st= ate. + + See the precise documentation in the UEFI spec. + + @param[in] This The Config Access Protocol instance. + + @param[in] Request A format UCS-2 string describing t= he + query. + + @param[out] Progress A pointer into Request on output, identifying the = query + element where processing failed. + + @param[out] Results A format UCS-2 string that has + all values filled in for the names in the Request + string. + + @retval EFI_SUCCESS Extraction of form state in + encoding successful. + @return Status codes from underlying functions. + +**/ +STATIC +EFI_STATUS +EFIAPI +ExtractConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Request, + OUT EFI_STRING *Progress, + OUT EFI_STRING *Results +) +{ + MAIN_FORM_STATE MainFormState; + EFI_STATUS Status; + + DEBUG ((EFI_D_VERBOSE, "%a: Request=3D\"%s\"\n", __FUNCTION__, Request)); + + Status =3D PlatformConfigToFormState (&MainFormState); + if (EFI_ERROR (Status)) { + *Progress =3D Request; + return Status; + } + + // + // Answer the textual request keying off the binary form state. + // + Status =3D gHiiConfigRouting->BlockToConfig (gHiiConfigRouting, Request, + (VOID *) &MainFormState, sizeof MainFormSt= ate, + Results, Progress); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "%a: BlockToConfig(): %r, Progress=3D\"%s\"\n", + __FUNCTION__, Status, (Status =3D=3D EFI_DEVICE_ERROR) ? NULL : *Pro= gress)); + } else { + DEBUG ((EFI_D_VERBOSE, "%a: Results=3D\"%s\"\n", __FUNCTION__, *Result= s)); + } + return Status; +} + + +/** + Interpret the binary form state and save it as persistent platform + configuration. + + @param[in] MainFormState Binary form/widget state to verify and save. + + @retval EFI_SUCCESS Platform configuration saved. + @return Error codes from underlying functions. +**/ +STATIC +EFI_STATUS +EFIAPI +FormStateToPlatformConfig ( + IN CONST MAIN_FORM_STATE *MainFormState + ) +{ + EFI_STATUS Status; + PLATFORM_CONFIG PlatformConfig; + CONST GOP_MODE *GopMode; + + // + // There's nothing to do with the textual CurrentPreferredResolution fie= ld. + // We verify and translate the selection in the drop-down list. + // + if (MainFormState->NextPreferredResolution >=3D mNumGopModes) { + return EFI_INVALID_PARAMETER; + } + GopMode =3D mGopModes + MainFormState->NextPreferredResolution; + + ZeroMem (&PlatformConfig, sizeof PlatformConfig); + PlatformConfig.HorizontalResolution =3D GopMode->X; + PlatformConfig.VerticalResolution =3D GopMode->Y; + + Status =3D PlatformConfigSave (&PlatformConfig); + return Status; +} + + +/** + This function is called by the HII machinery when it wants the driver to + interpret and persist the form state. + + See the precise documentation in the UEFI spec. + + @param[in] This The Config Access Protocol instance. + + @param[in] Configuration A format UCS-2 string describing= the + form state. + + @param[out] Progress A pointer into Configuration on output, + identifying the element where processing fail= ed. + + @retval EFI_SUCCESS Configuration verified, state permanent. + + @return Status codes from underlying functions. +**/ +STATIC +EFI_STATUS +EFIAPI +RouteConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Configuration, + OUT EFI_STRING *Progress +) +{ + MAIN_FORM_STATE MainFormState; + UINTN BlockSize; + EFI_STATUS Status; + + DEBUG ((EFI_D_VERBOSE, "%a: Configuration=3D\"%s\"\n", __FUNCTION__, + Configuration)); + + // + // the "read" step in RMW + // + Status =3D PlatformConfigToFormState (&MainFormState); + if (EFI_ERROR (Status)) { + *Progress =3D Configuration; + return Status; + } + + // + // the "modify" step in RMW + // + // (Update the binary form state. This update may be partial, which is w= hy in + // general we must pre-load the form state from the platform config.) + // + BlockSize =3D sizeof MainFormState; + Status =3D gHiiConfigRouting->ConfigToBlock (gHiiConfigRouting, Configur= ation, + (VOID *) &MainFormState, &BlockSize, Progr= ess); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "%a: ConfigToBlock(): %r, Progress=3D\"%s\"\n", + __FUNCTION__, Status, + (Status =3D=3D EFI_BUFFER_TOO_SMALL) ? NULL : *Progress)); + return Status; + } + + // + // the "write" step in RMW + // + Status =3D FormStateToPlatformConfig (&MainFormState); + if (EFI_ERROR (Status)) { + *Progress =3D Configuration; + } + return Status; +} + + +STATIC +EFI_STATUS +EFIAPI +Callback ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN EFI_BROWSER_ACTION Action, + IN EFI_QUESTION_ID QuestionId, + IN UINT8 Type, + IN OUT EFI_IFR_TYPE_VALUE *Value, + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest + ) +{ + DEBUG ((EFI_D_VERBOSE, "%a: Action=3D0x%Lx QuestionId=3D%d Type=3D%d\n", + __FUNCTION__, (UINT64) Action, QuestionId, Type)); + + if (Action !=3D EFI_BROWSER_ACTION_CHANGED) { + return EFI_UNSUPPORTED; + } + + switch (QuestionId) { + case QUESTION_SAVE_EXIT: + *ActionRequest =3D EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT; + break; + + case QUESTION_DISCARD_EXIT: + *ActionRequest =3D EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT; + break; + + default: + break; + } + + return EFI_SUCCESS; +} + + +/** + Query and save all resolutions supported by the GOP. + + @param[in] Gop The Graphics Output Protocol instance to query. + + @param[out] NumGopModes The number of modes supported by the GOP. On ou= tput, + this parameter will be positive. + + @param[out] GopModes On output, a dynamically allocated array contai= ning + the resolutions returned by the GOP. The caller= is + responsible for freeing the array after use. + + @retval EFI_UNSUPPORTED No modes found. + @retval EFI_OUT_OF_RESOURCES Failed to allocate GopModes. + @return Error codes from Gop->QueryMode(). + +**/ +STATIC +EFI_STATUS +EFIAPI +QueryGopModes ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop, + OUT UINTN *NumGopModes, + OUT GOP_MODE **GopModes + ) +{ + EFI_STATUS Status; + UINT32 ModeNumber; + + if (Gop->Mode->MaxMode =3D=3D 0) { + return EFI_UNSUPPORTED; + } + *NumGopModes =3D Gop->Mode->MaxMode; + + *GopModes =3D AllocatePool (Gop->Mode->MaxMode * sizeof **GopModes); + if (*GopModes =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + for (ModeNumber =3D 0; ModeNumber < Gop->Mode->MaxMode; ++ModeNumber) { + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; + UINTN SizeOfInfo; + + Status =3D Gop->QueryMode (Gop, ModeNumber, &SizeOfInfo, &Info); + if (EFI_ERROR (Status)) { + goto FreeGopModes; + } + + (*GopModes)[ModeNumber].X =3D Info->HorizontalResolution; + (*GopModes)[ModeNumber].Y =3D Info->VerticalResolution; + FreePool (Info); + } + + return EFI_SUCCESS; + +FreeGopModes: + FreePool (*GopModes); + + return Status; +} + + +/** + Create a set of "one-of-many" (ie. "drop down list") option IFR opcodes, + based on available GOP resolutions, to be placed under a "one-of-many" (= ie. + "drop down list") opcode. + + @param[in] PackageList The package list with the formset and form for + which the drop down options are produced. Opti= on + names are added as new strings to PackageList. + + @param[out] OpCodeBuffer On output, a dynamically allocated opcode buff= er + with drop down list options corresponding to G= OP + resolutions. The caller is responsible for fre= eing + OpCodeBuffer with HiiFreeOpCodeHandle() after = use. + + @param[in] NumGopModes Number of entries in GopModes. + + @param[in] GopModes Array of resolutions retrieved from the GOP. + + @retval EFI_SUCESS Opcodes have been successfully produced. + + @return Status codes from underlying functions. PackageList = may + have been extended with new strings. OpCodeBuffer is + unchanged. +**/ +STATIC +EFI_STATUS +EFIAPI +CreateResolutionOptions ( + IN EFI_HII_HANDLE *PackageList, + OUT VOID **OpCodeBuffer, + IN UINTN NumGopModes, + IN GOP_MODE *GopModes + ) +{ + EFI_STATUS Status; + VOID *OutputBuffer; + UINTN ModeNumber; + + OutputBuffer =3D HiiAllocateOpCodeHandle (); + if (OutputBuffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + for (ModeNumber =3D 0; ModeNumber < NumGopModes; ++ModeNumber) { + CHAR16 Desc[MAXSIZE_RES_CUR]; + EFI_STRING_ID NewString; + VOID *OpCode; + + UnicodeSPrintAsciiFormat (Desc, sizeof Desc, "%Ldx%Ld", + (INT64) GopModes[ModeNumber].X, (INT64) GopModes[ModeNumber].Y); + NewString =3D HiiSetString (PackageList, 0 /* new string */, Desc, + NULL /* for all languages */); + if (NewString =3D=3D 0) { + Status =3D EFI_OUT_OF_RESOURCES; + goto FreeOutputBuffer; + } + OpCode =3D HiiCreateOneOfOptionOpCode (OutputBuffer, NewString, + 0 /* Flags */, EFI_IFR_NUMERIC_SIZE_4, ModeNumber); + if (OpCode =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto FreeOutputBuffer; + } + } + + *OpCodeBuffer =3D OutputBuffer; + return EFI_SUCCESS; + +FreeOutputBuffer: + HiiFreeOpCodeHandle (OutputBuffer); + + return Status; +} + + +/** + Populate the form identified by the (PackageList, FormSetGuid, FormId) + triplet. + + The drop down list of video resolutions is generated from (NumGopModes, + GopModes). + + @retval EFI_SUCESS Form successfully updated. + @return Status codes from underlying functions. + +**/ +STATIC +EFI_STATUS +EFIAPI +PopulateForm ( + IN EFI_HII_HANDLE *PackageList, + IN EFI_GUID *FormSetGuid, + IN EFI_FORM_ID FormId, + IN UINTN NumGopModes, + IN GOP_MODE *GopModes + ) +{ + EFI_STATUS Status; + VOID *OpCodeBuffer; + VOID *OpCode; + EFI_IFR_GUID_LABEL *Anchor; + VOID *OpCodeBuffer2; + + OpCodeBuffer2 =3D NULL; + + // + // 1. Allocate an empty opcode buffer. + // + OpCodeBuffer =3D HiiAllocateOpCodeHandle (); + if (OpCodeBuffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // 2. Create a label opcode (which is a Tiano extension) inside the buff= er. + // The label's number must match the "anchor" label in the form. + // + OpCode =3D HiiCreateGuidOpCode (OpCodeBuffer, &gEfiIfrTianoGuid, + NULL /* optional copy origin */, sizeof *Anchor); + if (OpCode =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto FreeOpCodeBuffer; + } + Anchor =3D OpCode; + Anchor->ExtendOpCode =3D EFI_IFR_EXTEND_OP_LABEL; + Anchor->Number =3D LABEL_RES_NEXT; + + // + // 3. Create the opcodes inside the buffer that are to be inserted into = the + // form. + // + // 3.1. Get a list of resolutions. + // + Status =3D CreateResolutionOptions (PackageList, &OpCodeBuffer2, + NumGopModes, GopModes); + if (EFI_ERROR (Status)) { + goto FreeOpCodeBuffer; + } + + // + // 3.2. Create a one-of-many question with the above options. + // + OpCode =3D HiiCreateOneOfOpCode ( + OpCodeBuffer, // create opcode inside = this + // opcode buffer, + QUESTION_RES_NEXT, // ID of question, + FORMSTATEID_MAIN_FORM, // identifies form state + // storage, + (UINT16) OFFSET_OF (MAIN_FORM_STATE, // value of question sto= red + NextPreferredResolution), // at this offset, + STRING_TOKEN (STR_RES_NEXT), // Prompt, + STRING_TOKEN (STR_RES_NEXT_HELP), // Help, + 0, // QuestionFlags, + EFI_IFR_NUMERIC_SIZE_4, // see sizeof + // NextPreferredResolu= tion, + OpCodeBuffer2, // buffer with possible + // choices, + NULL // DEFAULT opcodes + ); + if (OpCode =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto FreeOpCodeBuffer2; + } + + // + // 4. Update the form with the opcode buffer. + // + Status =3D HiiUpdateForm (PackageList, FormSetGuid, FormId, + OpCodeBuffer, // buffer with head anchor, and new contents to= be + // inserted at it + NULL // buffer with tail anchor, for deleting old + // contents up to it + ); + +FreeOpCodeBuffer2: + HiiFreeOpCodeHandle (OpCodeBuffer2); + +FreeOpCodeBuffer: + HiiFreeOpCodeHandle (OpCodeBuffer); + + return Status; +} + + +/** + Load and execute the platform configuration. + + @retval EFI_SUCCESS Configuration loaded and executed. + @return Status codes from PlatformConfigLoad(). +**/ +STATIC +EFI_STATUS +EFIAPI +ExecutePlatformConfig ( + VOID + ) +{ + EFI_STATUS Status; + PLATFORM_CONFIG PlatformConfig; + UINT64 OptionalElements; + + Status =3D PlatformConfigLoad (&PlatformConfig, &OptionalElements); + if (EFI_ERROR (Status)) { + DEBUG (((Status =3D=3D EFI_NOT_FOUND) ? EFI_D_VERBOSE : EFI_D_ERROR, + "%a: failed to load platform config: %r\n", __FUNCTION__, Status)); + return Status; + } + + if (OptionalElements & PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION) { + // + // Pass the preferred resolution to GraphicsConsoleDxe via dynamic PCD= s. + // + PcdSet32 (PcdVideoHorizontalResolution, + PlatformConfig.HorizontalResolution); + PcdSet32 (PcdVideoVerticalResolution, + PlatformConfig.VerticalResolution); + } + + return EFI_SUCCESS; +} + + +/** + Notification callback for GOP interface installation. + + @param[in] Event Event whose notification function is being invoked. + + @param[in] Context The pointer to the notification function's context, = which + is implementation-dependent. +**/ +STATIC +VOID +EFIAPI +GopInstalled ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop; + + ASSERT (Event =3D=3D mGopEvent); + + // + // Check further GOPs. + // + for (;;) { + mNumGopModes =3D 0; + mGopModes =3D NULL; + + Status =3D gBS->LocateProtocol (&gEfiGraphicsOutputProtocolGuid, mGopT= racker, + (VOID **) &Gop); + if (EFI_ERROR (Status)) { + return; + } + + Status =3D QueryGopModes (Gop, &mNumGopModes, &mGopModes); + if (EFI_ERROR (Status)) { + continue; + } + + Status =3D PopulateForm (mInstalledPackages, &gSimicsBoardConfigGuid, + FORMID_MAIN_FORM, mNumGopModes, mGopModes); + if (EFI_ERROR (Status)) { + FreePool (mGopModes); + continue; + } + + break; + } + + // + // Success -- so uninstall this callback. Closing the event removes all + // pending notifications and all protocol registrations. + // + Status =3D gBS->CloseEvent (mGopEvent); + ASSERT_EFI_ERROR (Status); + mGopEvent =3D NULL; + mGopTracker =3D NULL; +} + + +/** + Entry point for this driver. + + @param[in] ImageHandle Image handle of this driver. + @param[in] SystemTable Pointer to SystemTable. + + @retval EFI_SUCESS Driver has loaded successfully. + @retval EFI_OUT_OF_RESOURCES Failed to install HII packages. + @return Error codes from lower level functions. + +**/ +EFI_STATUS +EFIAPI +PlatformInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + ExecutePlatformConfig (); + + mConfigAccess.ExtractConfig =3D &ExtractConfig; + mConfigAccess.RouteConfig =3D &RouteConfig; + mConfigAccess.Callback =3D &Callback; + + // + // Declare ourselves suitable for HII communication. + // + Status =3D gBS->InstallMultipleProtocolInterfaces (&ImageHandle, + &gEfiDevicePathProtocolGuid, &mPkgDevicePath, + &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess, + NULL); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Publish the HII package list to HII Database. + // + mInstalledPackages =3D HiiAddPackages ( + &gEfiCallerIdGuid, // PackageListGuid + ImageHandle, // associated DeviceHandle + SimicsDxeStrings, // 1st package + PlatformFormsBin, // 2nd package + NULL // terminator + ); + if (mInstalledPackages =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto UninstallProtocols; + } + + Status =3D gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK, &GopInstal= led, + NULL /* Context */, &mGopEvent); + if (EFI_ERROR (Status)) { + goto RemovePackages; + } + + Status =3D gBS->RegisterProtocolNotify (&gEfiGraphicsOutputProtocolGuid, + mGopEvent, &mGopTracker); + if (EFI_ERROR (Status)) { + goto CloseGopEvent; + } + + // + // Check already installed GOPs. + // + Status =3D gBS->SignalEvent (mGopEvent); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; + +CloseGopEvent: + gBS->CloseEvent (mGopEvent); + +RemovePackages: + HiiRemovePackages (mInstalledPackages); + +UninstallProtocols: + gBS->UninstallMultipleProtocolInterfaces (ImageHandle, + &gEfiDevicePathProtocolGuid, &mPkgDevicePath, + &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess, + NULL); + return Status; +} + +/** + Unload the driver. + + @param[in] ImageHandle Handle that identifies the image to evict. + + @retval EFI_SUCCESS The image has been unloaded. +**/ +EFI_STATUS +EFIAPI +PlatformUnload ( + IN EFI_HANDLE ImageHandle + ) +{ + if (mGopEvent =3D=3D NULL) { + // + // The GOP callback ran successfully and unregistered itself. Release = the + // resources allocated there. + // + ASSERT (mGopModes !=3D NULL); + FreePool (mGopModes); + } else { + // + // Otherwise we need to unregister the callback. + // + ASSERT (mGopModes =3D=3D NULL); + gBS->CloseEvent (mGopEvent); + } + + // + // Release resources allocated by the entry point. + // + HiiRemovePackages (mInstalledPackages); + gBS->UninstallMultipleProtocolInterfaces (ImageHandle, + &gEfiDevicePathProtocolGuid, &mPkgDevicePath, + &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess, + NULL); + return EFI_SUCCESS; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.c b= /Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.c new file mode 100644 index 0000000000..09929e830a --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.c @@ -0,0 +1,124 @@ +/** @file + Utility functions for serializing (persistently storing) and deserializi= ng + SIMICS QSP's platform configuration. + + Copyright (C) 2014, Red Hat, Inc. + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include + +#include "PlatformConfig.h" + +// +// Name of the UEFI variable that we use for persistent storage. +// +STATIC CHAR16 mVariableName[] =3D L"PlatformConfig"; + + +/** + Serialize and persistently save platform configuration. + + @param[in] PlatformConfig The platform configuration to serialize and s= ave. + + @return Status codes returned by gRT->SetVariable(). +**/ +EFI_STATUS +EFIAPI +PlatformConfigSave ( + IN PLATFORM_CONFIG *PlatformConfig + ) +{ + EFI_STATUS Status; + + // + // We could implement any kind of translation here, as part of serializa= tion. + // For example, we could expose the platform configuration in separate + // variables with human-readable contents, allowing other tools to access + // them more easily. For now, just save a binary dump. + // + Status =3D gRT->SetVariable (mVariableName, &gSimicsBoardConfigGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACC= ESS | + EFI_VARIABLE_RUNTIME_ACCESS, + sizeof *PlatformConfig, PlatformConfig); + return Status; +} + + +/** + Load and deserialize platform configuration. + + When the function fails, output parameters are indeterminate. + + @param[out] PlatformConfig The platform configuration to receive the + loaded data. + + @param[out] OptionalElements This bitmap describes the presence of opti= onal + configuration elements that have been load= ed. + PLATFORM_CONFIG_F_DOWNGRADE means that some + unknown elements, present in the wire form= at, + have been ignored. + + @retval EFI_SUCCESS Loading & deserialization successful. + @return Error codes returned by GetVariable2(). +**/ +EFI_STATUS +EFIAPI +PlatformConfigLoad ( + OUT PLATFORM_CONFIG *PlatformConfig, + OUT UINT64 *OptionalElements + ) +{ + VOID *Data; + UINTN DataSize; + EFI_STATUS Status; + + // + // Any translation done in PlatformConfigSave() would have to be mirrored + // here. For now, just load the binary dump. + // + // Versioning of the binary wire format is implemented based on size + // (only incremental changes, ie. new fields), and on GUID. + // (Incompatible changes require a GUID change.) + // + Status =3D GetVariable2 (mVariableName, &gSimicsBoardConfigGuid, &Data, + &DataSize); + if (EFI_ERROR (Status)) { + return Status; + } + + *OptionalElements =3D 0; + if (DataSize > sizeof *PlatformConfig) { + // + // Handle firmware downgrade -- keep only leading part. + // + CopyMem (PlatformConfig, Data, sizeof *PlatformConfig); + *OptionalElements |=3D PLATFORM_CONFIG_F_DOWNGRADE; + } else { + CopyMem (PlatformConfig, Data, DataSize); + + // + // Handle firmware upgrade -- zero out missing fields. + // + ZeroMem ((UINT8 *)PlatformConfig + DataSize, + sizeof *PlatformConfig - DataSize); + } + + // + // Based on DataSize, report the optional features that we recognize. + // + if (DataSize >=3D (OFFSET_OF (PLATFORM_CONFIG, VerticalResolution) + + sizeof PlatformConfig->VerticalResolution)) { + *OptionalElements |=3D PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION; + } + + FreePool (Data); + return EFI_SUCCESS; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.c b/Platform/= Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.c new file mode 100644 index 0000000000..b34ba9283b --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.c @@ -0,0 +1,57 @@ +/** @file + PC/AT CMOS access routines + + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "Cmos.h" +#include "Library/IoLib.h" + +/** + Reads 8-bits of CMOS data. + + Reads the 8-bits of CMOS data at the location specified by Index. + The 8-bit read value is returned. + + @param Index The CMOS location to read. + + @return The value read. + +**/ +UINT8 +EFIAPI +CmosRead8 ( + IN UINTN Index + ) +{ + IoWrite8 (0x70, (UINT8) Index); + return IoRead8 (0x71); +} + + +/** + Writes 8-bits of CMOS data. + + Writes 8-bits of CMOS data to the location specified by Index + with the value specified by Value and returns Value. + + @param Index The CMOS location to write. + @param Value The value to write to CMOS. + + @return The value written to CMOS. + +**/ +UINT8 +EFIAPI +CmosWrite8 ( + IN UINTN Index, + IN UINT8 Value + ) +{ + IoWrite8 (0x70, (UINT8) Index); + IoWrite8 (0x71, Value); + return Value; +} + diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/FeatureControl.c b= /Platform/Intel/SimicsOpenBoardPkg/SimicsPei/FeatureControl.c new file mode 100644 index 0000000000..9d2fc65a14 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/FeatureControl.c @@ -0,0 +1,115 @@ +/** @file + Install a callback when necessary for setting the Feature Control MSR on= all + processors. + + Copyright (C) 2016, Red Hat, Inc. + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include + +#include "Platform.h" + +// +// The value to be written to the Feature Control MSR, retrieved from fw_c= fg. +// +STATIC UINT64 mFeatureControlValue =3D 0x00000005; + +/** + Write the Feature Control MSR on an Application Processor or the Boot + Processor. + + All APs execute this function in parallel. The BSP executes the function + separately. + + @param[in,out] WorkSpace Pointer to the input/output argument workspace + shared by all processors. +**/ +STATIC +VOID +EFIAPI +WriteFeatureControl ( + IN OUT VOID *WorkSpace + ) +{ + AsmWriteMsr64 (MSR_CORE2_FEATURE_CONTROL, mFeatureControlValue); +} + +/** + Notification function called when EFI_PEI_MP_SERVICES_PPI becomes availa= ble. + + @param[in] PeiServices Indirect reference to the PEI Services Table. + @param[in] NotifyDescriptor Address of the notification descriptor data + structure. + @param[in] Ppi Address of the PPI that was installed. + + @return Status of the notification. The status code returned from this + function is ignored. +**/ +STATIC +EFI_STATUS +EFIAPI +OnMpServicesAvailable ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + EFI_PEI_MP_SERVICES_PPI *MpServices; + EFI_STATUS Status; + + DEBUG ((EFI_D_VERBOSE, "%a: %a\n", gEfiCallerBaseName, __FUNCTION__)); + // + // Write the MSR on all the APs in parallel. + // + MpServices =3D Ppi; + Status =3D MpServices->StartupAllAPs ( + (CONST EFI_PEI_SERVICES **)PeiServices, + MpServices, + WriteFeatureControl, // Procedure + FALSE, // SingleThread + 0, // TimeoutInMicroSeconds: in= f. + NULL // ProcedureArgument + ); + if (EFI_ERROR (Status) && Status !=3D EFI_NOT_STARTED) { + DEBUG ((EFI_D_ERROR, "%a: StartupAllAps(): %r\n", __FUNCTION__, Status= )); + return Status; + } + + // + // Now write the MSR on the BSP too. + // + WriteFeatureControl (NULL); + + return EFI_SUCCESS; +} + +// +// Notification object for registering the callback, for when +// EFI_PEI_MP_SERVICES_PPI becomes available. +// +STATIC CONST EFI_PEI_NOTIFY_DESCRIPTOR mMpServicesNotify =3D { + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | // Flags + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gEfiPeiMpServicesPpiGuid, // Guid + OnMpServicesAvailable // Notify +}; + +VOID +InstallFeatureControlCallback ( + VOID + ) +{ + EFI_STATUS Status; + + Status =3D PeiServicesNotifyPpi (&mMpServicesNotify); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "%a: failed to set up MP Services callback: %r\n", + __FUNCTION__, Status)); + } +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/MemDetect.c b/Plat= form/Intel/SimicsOpenBoardPkg/SimicsPei/MemDetect.c new file mode 100644 index 0000000000..90e6d1d3cf --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/MemDetect.c @@ -0,0 +1,568 @@ +/** @file + Memory Detection for Virtual Machines. + + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// The package level header files this module uses +// +#include + +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Platform.h" +#include "Cmos.h" + +UINT8 mPhysMemAddressWidth; + +STATIC UINT32 mS3AcpiReservedMemoryBase; +STATIC UINT32 mS3AcpiReservedMemorySize; + +STATIC UINT16 mX58TsegMbytes; + +VOID +X58TsegMbytesInitialization( + VOID +) +{ + + if (mHostBridgeDevId !=3D INTEL_ICH10_DEVICE_ID) { + DEBUG (( + DEBUG_ERROR, + "%a: no TSEG (SMRAM) on host bridge DID=3D0x%04x; " + "only DID=3D0x%04x (X58) is supported\n", + __FUNCTION__, + mHostBridgeDevId, + INTEL_ICH10_DEVICE_ID + )); + ASSERT (FALSE); + CpuDeadLoop (); + } + + // + // Check if QEMU offers an extended TSEG. + // + // This can be seen from writing MCH_EXT_TSEG_MB_QUERY to the MCH_EXT_TS= EG_MB + // register, and reading back the register. + // + // On a QEMU machine type that does not offer an extended TSEG, the init= ial + // write overwrites whatever value a malicious guest OS may have placed = in + // the (unimplemented) register, before entering S3 or rebooting. + // Subsequently, the read returns MCH_EXT_TSEG_MB_QUERY unchanged. + // + // On a QEMU machine type that offers an extended TSEG, the initial write + // triggers an update to the register. Subsequently, the value read back + // (which is guaranteed to differ from MCH_EXT_TSEG_MB_QUERY) tells us t= he + // number of megabytes. + // + mX58TsegMbytes =3D FixedPcdGet8(PcdX58TsegMbytes); + return; +} + + +UINT32 +GetSystemMemorySizeBelow4gb ( + VOID + ) +{ + UINT8 Cmos0x34; + UINT8 Cmos0x35; + + // + // CMOS 0x34/0x35 specifies the system memory above 16 MB. + // * CMOS(0x35) is the high byte + // * CMOS(0x34) is the low byte + // * The size is specified in 64kb chunks + // * Since this is memory above 16MB, the 16MB must be added + // into the calculation to get the total memory size. + // + + Cmos0x34 =3D (UINT8) CmosRead8 (0x34); + Cmos0x35 =3D (UINT8) CmosRead8 (0x35); + + return (UINT32) (((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB= ); +} + + +STATIC +UINT64 +GetSystemMemorySizeAbove4gb ( + ) +{ + UINT32 Size; + UINTN CmosIndex; + + // + // CMOS 0x5b-0x5d specifies the system memory above 4GB MB. + // * CMOS(0x5d) is the most significant size byte + // * CMOS(0x5c) is the middle size byte + // * CMOS(0x5b) is the least significant size byte + // * The size is specified in 64kb chunks + // + + Size =3D 0; + for (CmosIndex =3D 0x5d; CmosIndex >=3D 0x5b; CmosIndex--) { + Size =3D (UINT32) (Size << 8) + (UINT32) CmosRead8 (CmosIndex); + } + + return LShiftU64 (Size, 16); +} + + +/** + Return the highest address that DXE could possibly use, plus one. +**/ +STATIC +UINT64 +GetFirstNonAddress ( + VOID + ) +{ + UINT64 FirstNonAddress; + UINT64 Pci64Base, Pci64Size; + + FirstNonAddress =3D BASE_4GB + GetSystemMemorySizeAbove4gb (); + + // + // If DXE is 32-bit, then we're done; PciBusDxe will degrade 64-bit MMIO + // resources to 32-bit anyway. See DegradeResource() in + // "PciResourceSupport.c". + // +#ifdef MDE_CPU_IA32 + if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) { + return FirstNonAddress; + } +#endif + + // + // Otherwise, in order to calculate the highest address plus one, we must + // consider the 64-bit PCI host aperture too. Fetch the default size. + // + Pci64Size =3D PcdGet64 (PcdPciMmio64Size); + + if (Pci64Size =3D=3D 0) { + if (mBootMode !=3D BOOT_ON_S3_RESUME) { + DEBUG ((EFI_D_INFO, "%a: disabling 64-bit PCI host aperture\n", + __FUNCTION__)); + PcdSet64 (PcdPciMmio64Size, 0); + } + + // + // There's nothing more to do; the amount of memory above 4GB fully + // determines the highest address plus one. The memory hotplug area (s= ee + // below) plays no role for the firmware in this case. + // + return FirstNonAddress; + } + + // + // SeaBIOS aligns both boundaries of the 64-bit PCI host aperture to 1GB= , so + // that the host can map it with 1GB hugepages. Follow suit. + // + Pci64Base =3D ALIGN_VALUE (FirstNonAddress, (UINT64)SIZE_1GB); + Pci64Size =3D ALIGN_VALUE (Pci64Size, (UINT64)SIZE_1GB); + + // + // The 64-bit PCI host aperture should also be "naturally" aligned. The + // alignment is determined by rounding the size of the aperture down to = the + // next smaller or equal power of two. That is, align the aperture by the + // largest BAR size that can fit into it. + // + Pci64Base =3D ALIGN_VALUE (Pci64Base, GetPowerOfTwo64 (Pci64Size)); + + if (mBootMode !=3D BOOT_ON_S3_RESUME) { + // + // The core PciHostBridgeDxe driver will automatically add this range = to + // the GCD memory space map through our PciHostBridgeLib instance; her= e we + // only need to set the PCDs. + // + PcdSet64 (PcdPciMmio64Base, Pci64Base); + PcdSet64 (PcdPciMmio64Size, Pci64Size); + DEBUG ((EFI_D_INFO, "%a: Pci64Base=3D0x%Lx Pci64Size=3D0x%Lx\n", + __FUNCTION__, Pci64Base, Pci64Size)); + } + + // + // The useful address space ends with the 64-bit PCI host aperture. + // + FirstNonAddress =3D Pci64Base + Pci64Size; + return FirstNonAddress; +} + + +/** + Initialize the mPhysMemAddressWidth variable, based on guest RAM size. +**/ +VOID +AddressWidthInitialization ( + VOID + ) +{ + UINT64 FirstNonAddress; + + // + // As guest-physical memory size grows, the permanent PEI RAM requiremen= ts + // are dominated by the identity-mapping page tables built by the DXE IP= L. + // The DXL IPL keys off of the physical address bits advertized in the C= PU + // HOB. To conserve memory, we calculate the minimum address width here. + // + FirstNonAddress =3D GetFirstNonAddress (); + mPhysMemAddressWidth =3D (UINT8)HighBitSet64 (FirstNonAddress); + + // + // If FirstNonAddress is not an integral power of two, then we need an + // additional bit. + // + if ((FirstNonAddress & (FirstNonAddress - 1)) !=3D 0) { + ++mPhysMemAddressWidth; + } + + // + // The minimum address width is 36 (covers up to and excluding 64 GB, wh= ich + // is the maximum for Ia32 + PAE). The theoretical architecture maximum = for + // X64 long mode is 52 bits, but the DXE IPL clamps that down to 48 bits= . We + // can simply assert that here, since 48 bits are good enough for 256 TB. + // + if (mPhysMemAddressWidth <=3D 36) { + mPhysMemAddressWidth =3D 36; + } + ASSERT (mPhysMemAddressWidth <=3D 48); +} + + +/** + Calculate the cap for the permanent PEI memory. +**/ +STATIC +UINT32 +GetPeiMemoryCap ( + VOID + ) +{ + BOOLEAN Page1GSupport; + UINT32 RegEax; + UINT32 RegEdx; + UINT32 Pml4Entries; + UINT32 PdpEntries; + UINTN TotalPages; + + // + // If DXE is 32-bit, then just return the traditional 64 MB cap. + // +#ifdef MDE_CPU_IA32 + if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) { + return SIZE_64MB; + } +#endif + + // + // Dependent on physical address width, PEI memory allocations can be + // dominated by the page tables built for 64-bit DXE. So we key the cap = off + // of those. The code below is based on CreateIdentityMappingPageTables(= ) in + // "MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c". + // + Page1GSupport =3D FALSE; + if (PcdGetBool (PcdUse1GPageTable)) { + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); + if (RegEax >=3D 0x80000001) { + AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx); + if ((RegEdx & BIT26) !=3D 0) { + Page1GSupport =3D TRUE; + } + } + } + + if (mPhysMemAddressWidth <=3D 39) { + Pml4Entries =3D 1; + PdpEntries =3D 1 << (mPhysMemAddressWidth - 30); + ASSERT (PdpEntries <=3D 0x200); + } else { + Pml4Entries =3D 1 << (mPhysMemAddressWidth - 39); + ASSERT (Pml4Entries <=3D 0x200); + PdpEntries =3D 512; + } + + TotalPages =3D Page1GSupport ? Pml4Entries + 1 : + (PdpEntries + 1) * Pml4Entries + 1; + ASSERT (TotalPages <=3D 0x40201); + + // + // Add 64 MB for miscellaneous allocations. Note that for + // mPhysMemAddressWidth values close to 36, the cap will actually be + // dominated by this increment. + // + return (UINT32)(EFI_PAGES_TO_SIZE (TotalPages) + SIZE_64MB); +} + + +/** + Publish PEI core memory + + @return EFI_SUCCESS The PEIM initialized successfully. + +**/ +EFI_STATUS +PublishPeiMemory ( + VOID + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS MemoryBase; + UINT64 MemorySize; + UINT32 LowerMemorySize; + UINT32 PeiMemoryCap; + + LowerMemorySize =3D GetSystemMemorySizeBelow4gb (); + if (FeaturePcdGet (PcdSmmSmramRequire)) { + // + // TSEG is chipped from the end of low RAM + // + LowerMemorySize -=3D mX58TsegMbytes * SIZE_1MB; + } + + // + // If S3 is supported, then the S3 permanent PEI memory is placed next, + // downwards. Its size is primarily dictated by CpuMpPei. The formula be= low + // is an approximation. + // + if (mS3Supported) { + mS3AcpiReservedMemorySize =3D SIZE_512KB + + mMaxCpuCount * + PcdGet32 (PcdCpuApStackSize); + mS3AcpiReservedMemoryBase =3D LowerMemorySize - mS3AcpiReservedMemoryS= ize; + LowerMemorySize =3D mS3AcpiReservedMemoryBase; + } + + if (mBootMode =3D=3D BOOT_ON_S3_RESUME) { + MemoryBase =3D mS3AcpiReservedMemoryBase; + MemorySize =3D mS3AcpiReservedMemorySize; + } else { + PeiMemoryCap =3D GetPeiMemoryCap (); + DEBUG ((EFI_D_INFO, "%a: mPhysMemAddressWidth=3D%d PeiMemoryCap=3D%u K= B\n", + __FUNCTION__, mPhysMemAddressWidth, PeiMemoryCap >> 10)); + + // + // Determine the range of memory to use during PEI + // + // Technically we could lay the permanent PEI RAM over SEC's temporary + // decompression and scratch buffer even if "secure S3" is needed, sin= ce + // their lifetimes don't overlap. However, PeiFvInitialization() will = cover + // RAM up to PcdOvmfDecompressionScratchEnd with an EfiACPIMemoryNVS m= emory + // allocation HOB, and other allocations served from the permanent PEI= RAM + // shouldn't overlap with that HOB. + // + MemoryBase =3D mS3Supported && FeaturePcdGet (PcdSmmSmramRequire) ? + PcdGet32 (PcdSimicsDecompressionScratchEnd) : + PcdGet32 (PcdSimicsDxeMemFvBase) + PcdGet32 (PcdSimicsDxeMemFvSize); + MemorySize =3D LowerMemorySize - MemoryBase; + } + DEBUG((EFI_D_INFO, "MemoryBase=3D0x%lx MemorySize=3D0x%lx\n", MemoryBase= , MemorySize)); + // + // Publish this memory to the PEI Core + // + Status =3D PublishSystemMemory(MemoryBase, MemorySize); + ASSERT_EFI_ERROR (Status); + + return Status; +} + + +/** + Peform Memory Detection for QEMU / KVM + +**/ +STATIC +VOID +QemuInitializeRam ( + VOID + ) +{ + UINT64 LowerMemorySize; + UINT64 UpperMemorySize; + UINTN BufferSize; + UINT8 SmramIndex; + UINT8 SmramRanges; + EFI_PEI_HOB_POINTERS Hob; + EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *SmramHobDescriptorBlock; + UINT8 Index; + + DEBUG ((EFI_D_INFO, "%a called\n", __FUNCTION__)); + + // + // Determine total memory size available + // + LowerMemorySize =3D GetSystemMemorySizeBelow4gb (); + UpperMemorySize =3D GetSystemMemorySizeAbove4gb (); + + if (mBootMode =3D=3D BOOT_ON_S3_RESUME) { + // + // Create the following memory HOB as an exception on the S3 boot path. + // + // Normally we'd create memory HOBs only on the normal boot path. Howe= ver, + // CpuMpPei specifically needs such a low-memory HOB on the S3 path as + // well, for "borrowing" a subset of it temporarily, for the AP startup + // vector. + // + // CpuMpPei saves the original contents of the borrowed area in perman= ent + // PEI RAM, in a backup buffer allocated with the normal PEI services. + // CpuMpPei restores the original contents ("returns" the borrowed are= a) at + // End-of-PEI. End-of-PEI in turn is emitted by S3Resume2Pei before + // transferring control to the OS's wakeup vector in the FACS. + // + // We expect any other PEIMs that "borrow" memory similarly to CpuMpPe= i to + // restore the original contents. Furthermore, we expect all such PEIMs + // (CpuMpPei included) to claim the borrowed areas by producing memory + // allocation HOBs, and to honor preexistent memory allocation HOBs wh= en + // looking for an area to borrow. + // + AddMemoryRangeHob (0, BASE_512KB + BASE_128KB); + } else { + // + // Create memory HOBs + // + AddMemoryRangeHob (0, BASE_512KB + BASE_128KB); + + if (FeaturePcdGet (PcdSmmSmramRequire)) { + UINT32 TsegSize; + + TsegSize =3D mX58TsegMbytes * SIZE_1MB; + AddMemoryRangeHob (BASE_1MB, LowerMemorySize - TsegSize); + AddReservedMemoryBaseSizeHob (LowerMemorySize - TsegSize, TsegSize, + TRUE); + + BufferSize =3D sizeof(EFI_SMRAM_HOB_DESCRIPTOR_BLOCK); + SmramRanges =3D 1; + + Hob.Raw =3D BuildGuidHob( + &gEfiSmmPeiSmramMemoryReserveGuid, + BufferSize + ); + ASSERT(Hob.Raw); + + SmramHobDescriptorBlock =3D (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *)(Hob.R= aw); + SmramHobDescriptorBlock->NumberOfSmmReservedRegions =3D SmramRanges; + + SmramIndex =3D 0; + for (Index =3D 0; Index < SmramRanges; Index++) { + // + // This is an SMRAM range, create an SMRAM descriptor + // + SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalStart =3D = LowerMemorySize - TsegSize; + SmramHobDescriptorBlock->Descriptor[SmramIndex].CpuStart =3D Lower= MemorySize - TsegSize; + SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalSize =3D T= segSize; + SmramHobDescriptorBlock->Descriptor[SmramIndex].RegionState =3D EF= I_SMRAM_CLOSED | EFI_CACHEABLE; + SmramIndex++; + } + + } else { + AddMemoryRangeHob (BASE_1MB, LowerMemorySize); + } + + // + // If QEMU presents an E820 map, then create memory HOBs for the >=3D4= GB RAM + // entries. Otherwise, create a single memory HOB with the flat >=3D4GB + // memory size read from the CMOS. + // + if (UpperMemorySize !=3D 0) { + AddMemoryBaseSizeHob (BASE_4GB, UpperMemorySize); + } + } +} + +/** + Publish system RAM and reserve memory regions + +**/ +VOID +InitializeRamRegions ( + VOID + ) +{ + QemuInitializeRam (); + + if (mS3Supported && mBootMode !=3D BOOT_ON_S3_RESUME) { + // + // This is the memory range that will be used for PEI on S3 resume + // + BuildMemoryAllocationHob ( + mS3AcpiReservedMemoryBase, + mS3AcpiReservedMemorySize, + EfiACPIMemoryNVS + ); + + // + // Cover the initial RAM area used as stack and temporary PEI heap. + // + // This is reserved as ACPI NVS so it can be used on S3 resume. + // + BuildMemoryAllocationHob ( + PcdGet32 (PcdSimicsSecPeiTempRamBase), + PcdGet32 (PcdSimicsSecPeiTempRamSize), + EfiACPIMemoryNVS + ); + + // + // SEC stores its table of GUIDed section handlers here. + // + BuildMemoryAllocationHob ( + PcdGet64 (PcdGuidedExtractHandlerTableAddress), + PcdGet32 (PcdGuidedExtractHandlerTableSize), + EfiACPIMemoryNVS + ); + + } + + if (mBootMode !=3D BOOT_ON_S3_RESUME) { + if (!FeaturePcdGet (PcdSmmSmramRequire)) { + // + // Reserve the lock box storage area + // + // Since this memory range will be used on S3 resume, it must be + // reserved as ACPI NVS. + // + // If S3 is unsupported, then various drivers might still write to t= he + // LockBox area. We ought to prevent DXE from serving allocation req= uests + // such that they would overlap the LockBox storage. + // + ZeroMem ( + (VOID*)(UINTN) PcdGet32 (PcdSimicsLockBoxStorageBase), + (UINTN) PcdGet32 (PcdSimicsLockBoxStorageSize) + ); + BuildMemoryAllocationHob ( + (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdSimicsLockBoxStorageBas= e), + (UINT64)(UINTN) PcdGet32 (PcdSimicsLockBoxStorageSize), + mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData + ); + } + + if (FeaturePcdGet (PcdSmmSmramRequire)) { + UINT32 TsegSize; + + // + // Make sure the TSEG area that we reported as a reserved memory res= ource + // cannot be used for reserved memory allocations. + // + TsegSize =3D mX58TsegMbytes * SIZE_1MB; + BuildMemoryAllocationHob ( + GetSystemMemorySizeBelow4gb() - TsegSize, + TsegSize, + EfiReservedMemoryType + ); + } + } +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.c b/Platf= orm/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.c new file mode 100644 index 0000000000..2fe34b02c4 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.c @@ -0,0 +1,630 @@ +/** @file + Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+ Copyright (c) 2011, Andrei Warkentin + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// The package level header files this module uses +// +#include + +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Platform.h" +#include "Cmos.h" + +EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] =3D { + { EfiACPIMemoryNVS, 0x004 }, + { EfiACPIReclaimMemory, 0x008 }, + { EfiReservedMemoryType, 0x004 }, + { EfiRuntimeServicesData, 0x024 }, + { EfiRuntimeServicesCode, 0x030 }, + { EfiBootServicesCode, 0x180 }, + { EfiBootServicesData, 0xF00 }, + { EfiMaxMemoryType, 0x000 } +}; + + +EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[] =3D { + { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gEfiPeiMasterBootModePpiGuid, + NULL + } +}; + + +UINT16 mHostBridgeDevId; + +EFI_BOOT_MODE mBootMode =3D BOOT_WITH_FULL_CONFIGURATION; + +BOOLEAN mS3Supported =3D FALSE; + +UINT32 mMaxCpuCount; + +VOID +AddIoMemoryBaseSizeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize + ) +{ + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | + EFI_RESOURCE_ATTRIBUTE_TESTED, + MemoryBase, + MemorySize + ); +} + +VOID +AddReservedMemoryBaseSizeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize, + BOOLEAN Cacheable + ) +{ + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_RESERVED, + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | + (Cacheable ? + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE : + 0 + ) | + EFI_RESOURCE_ATTRIBUTE_TESTED, + MemoryBase, + MemorySize + ); +} + +VOID +AddIoMemoryRangeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + EFI_PHYSICAL_ADDRESS MemoryLimit + ) +{ + AddIoMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase)); +} + + +VOID +AddMemoryBaseSizeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize + ) +{ + BuildResourceDescriptorHob ( + EFI_RESOURCE_SYSTEM_MEMORY, + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_TESTED, + MemoryBase, + MemorySize + ); +} + + +VOID +AddMemoryRangeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + EFI_PHYSICAL_ADDRESS MemoryLimit + ) +{ + AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase)); +} + + +VOID +AddUntestedMemoryBaseSizeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize + ) +{ + BuildResourceDescriptorHob ( + EFI_RESOURCE_SYSTEM_MEMORY, + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE, + MemoryBase, + MemorySize + ); +} + + +VOID +AddUntestedMemoryRangeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + EFI_PHYSICAL_ADDRESS MemoryLimit + ) +{ + AddUntestedMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryB= ase)); +} + +VOID +AddFlashDeviceRange ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize + ) +{ + BuildResourceDescriptorHob ( + EFI_RESOURCE_FIRMWARE_DEVICE, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + MemoryBase, + MemorySize + ); + + BuildMemoryAllocationHob ( + MemoryBase, + MemorySize, + EfiMemoryMappedIO + ); +} + +VOID +MemMapInitialization ( + VOID + ) +{ + UINT64 PciIoBase; + UINT64 PciIoSize; + + UINT32 TopOfLowRam; + UINT64 PciExBarBase; + UINT32 PciBase; + UINT32 PciSize; + + PciIoBase =3D 0xC000; + PciIoSize =3D 0x4000; + + // + // Create Memory Type Information HOB + // + BuildGuidDataHob ( + &gEfiMemoryTypeInformationGuid, + mDefaultMemoryTypeInformation, + sizeof(mDefaultMemoryTypeInformation) + ); + + // + // Video memory + Legacy BIOS region + // + AddIoMemoryRangeHob (0x0A0000, BASE_1MB); + + TopOfLowRam =3D GetSystemMemorySizeBelow4gb (); + PciExBarBase =3D 0; + if (mHostBridgeDevId =3D=3D INTEL_ICH10_DEVICE_ID) { + // + // The MMCONFIG area is expected to fall between the top of low RAM and + // the base of the 32-bit PCI host aperture. + // + PciExBarBase =3D FixedPcdGet64 (PcdPciExpressBaseAddress); + ASSERT (TopOfLowRam <=3D PciExBarBase); + ASSERT (PciExBarBase <=3D MAX_UINT32 - SIZE_256MB); + PciBase =3D (UINT32)(PciExBarBase + SIZE_256MB); + } else { + PciBase =3D (TopOfLowRam < BASE_2GB) ? BASE_2GB : TopOfLowRam; + } + + // + // address purpose size + // ------------ -------- ------------------------- + // 0x00000000 TopOfLowRam 0xDF000000 + // 0xDF000000 Tseg+UMA 0x01000000 + // 0xE0000000 PciExBarBase 0x10000000 + // 0xF0000000 PciBase 0x0C000000 + // ------------------------------------------------- + // max(top, 2g) PCI MMIO 0xFC000000 - max(top, 2g) + // 0xFC000000 gap 44 MB + // 0xFEC00000 IO-APIC 4 KB + // 0xFEC01000 gap 1020 KB + // 0xFED00000 HPET 1 KB + // 0xFED00400 gap 111 KB + // 0xFED1C000 gap (PIIX4) / RCRB (ICH9) 16 KB + // 0xFED20000 gap 896 KB + // 0xFEE00000 LAPIC 1 MB + // + PciSize =3D 0xFC000000 - PciBase; + AddIoMemoryBaseSizeHob (PciBase, PciSize); + PcdSet64 (PcdPciMmio32Base, PciBase); + PcdSet64 (PcdPciMmio32Size, PciSize); + AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB); + AddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB); + if (mHostBridgeDevId =3D=3D INTEL_ICH10_DEVICE_ID) { + AddIoMemoryBaseSizeHob (ICH10_ROOT_COMPLEX_BASE, SIZE_16KB); + // + // Note: there should be an + // + // AddIoMemoryBaseSizeHob (PciExBarBase, SIZE_256MB); + // BuildMemoryAllocationHob (PciExBarBase, SIZE_256MB, EfiMemoryMapp= edIO); + // + // call below, just like the one above for RCBA. However, Linux insists + // that the MMCONFIG area be marked in the E820 or UEFI memory map as + // "reserved memory" -- Linux does not content itself with a simple gap + // in the memory map wherever the MCFG ACPI table points to. + // + // This appears to be a safety measure. The PCI Firmware Specification + // (rev 3.1) says in 4.1.2. "MCFG Table Description": "The resources c= an + // *optionally* be returned in [...] EFIGetMemoryMap as reserved memory + // [...]". (Emphasis added here.) + // + // Normally we add memory resource descriptor HOBs in + // QemuInitializeRam(), and pre-allocate from those with memory + // allocation HOBs in InitializeRamRegions(). However, the MMCONFIG ar= ea + // is most definitely not RAM; so, as an exception, cover it with + // uncacheable reserved memory right here. + // + AddReservedMemoryBaseSizeHob (PciExBarBase, SIZE_256MB, FALSE); + BuildMemoryAllocationHob (PciExBarBase, SIZE_256MB, + EfiReservedMemoryType); + } + AddIoMemoryBaseSizeHob (PcdGet32(PcdCpuLocalApicBaseAddress), SIZE_1MB); + + // Add PCI IO Port space available for PCI resource allocations. + // + BuildResourceDescriptorHob ( + EFI_RESOURCE_IO, + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED, + PciIoBase, + PciIoSize + ); + PcdSet64 (PcdPciIoBase, PciIoBase); + PcdSet64 (PcdPciIoSize, PciIoSize); + + // + // Add flash range. + // + AddFlashDeviceRange (PcdGet32(PcdFlashAreaBaseAddress), PcdGet32(PcdFlas= hAreaSize)); + // + // Video memory / ABSEG + // + AddIoMemoryBaseSizeHob (0x0A0000, 0x20000); + // + // Legacy BIOS region. + // + AddReservedMemoryBaseSizeHob (0xC0000, 0x40000, TRUE); +} + +VOID +MiscInitialization ( + VOID + ) +{ + UINTN PmCmd; + UINTN Pmba; + UINT32 PmbaAndVal; + UINT32 PmbaOrVal; + UINTN AcpiCtlReg; + UINT8 AcpiEnBit; + + // + // Disable A20 Mask + // + IoOr8 (0x92, BIT1); + + // + // Build the CPU HOB with guest RAM size dependent address width and 16-= bits + // of IO space. (Side note: unlike other HOBs, the CPU HOB is needed dur= ing + // S3 resume as well, so we build it unconditionally.) + // + BuildCpuHob (mPhysMemAddressWidth, 16); + + // + // Determine platform type and save Host Bridge DID to PCD + // + switch (mHostBridgeDevId) { + case INTEL_82441_DEVICE_ID: + PmCmd =3D POWER_MGMT_REGISTER_PIIX4 (PCI_COMMAND_OFFSET); + Pmba =3D POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA); + PmbaAndVal =3D ~(UINT32)PIIX4_PMBA_MASK; + PmbaOrVal =3D PIIX4_PMBA_VALUE; + AcpiCtlReg =3D POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMREGMISC); + AcpiEnBit =3D PIIX4_PMREGMISC_PMIOSE; + break; + case INTEL_ICH10_DEVICE_ID: + PmCmd =3D POWER_MGMT_REGISTER_ICH10 (PCI_COMMAND_OFFSET); + Pmba =3D POWER_MGMT_REGISTER_ICH10 (ICH10_PMBASE); + PmbaAndVal =3D ~(UINT32)ICH10_PMBASE_MASK; + PmbaOrVal =3D ICH10_PMBASE_VALUE; + AcpiCtlReg =3D POWER_MGMT_REGISTER_ICH10 (ICH10_ACPI_CNTL); + AcpiEnBit =3D ICH10_ACPI_CNTL_ACPI_EN; + break; + default: + DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n", + __FUNCTION__, mHostBridgeDevId)); + ASSERT (FALSE); + return; + } + PcdSet16 (PcdSimicsX58HostBridgePciDevId, mHostBridgeDevId); + + // + // If the appropriate IOspace enable bit is set, assume the ACPI PMBA + // has been configured and skip the setup here. + // This matches the logic in AcpiTimerLibConstructor (). + // + if ((PciRead8 (AcpiCtlReg) & AcpiEnBit) =3D=3D 0) { + // + // The PEI phase should be exited with fully accessibe ACPI PM IO spac= e: + // 1. set PMBA + // + PciAndThenOr32 (Pmba, PmbaAndVal, PmbaOrVal); + + // + // 2. set PCICMD/IOSE + // + PciOr8 (PmCmd, EFI_PCI_COMMAND_IO_SPACE); + + // + // 3. set ACPI PM IO enable bit (PMREGMISC:PMIOSE or ACPI_CNTL:ACPI_EN) + // + PciOr8 (AcpiCtlReg, AcpiEnBit); + } + + if (mHostBridgeDevId =3D=3D INTEL_ICH10_DEVICE_ID) { + // + // Set Root Complex Register Block BAR + // + PciWrite32 ( + POWER_MGMT_REGISTER_ICH10 (ICH10_RCBA), + ICH10_ROOT_COMPLEX_BASE | ICH10_RCBA_EN + ); + + } + // + // Set the PM I/O base address to 0x400 + // + PciAndThenOr32 ( + PCI_LIB_ADDRESS ( + 0, + 31, + 0, + 0x40 + ), + (UINT32) ~0xfc0, ICH10_PMBASE_VALUE + ); + // + // Enable AHCI and all ports on the SATA controller. + // + // Address MAP Reg, setting AHCI mode + // + PciOr16 (PCI_LIB_ADDRESS (0, 31, 2, 0x90), 0x0060); + // + //Enabling Ports 0-5 + // + PciOr16 (PCI_LIB_ADDRESS (0, 31, 2, 0x92), 0x003F); + // + //Disabling Sata Controller 2, bit 25 =3D 1, bit 0 =3D 1 + // + MmioWrite32(0xFED1F418, 0x02000001); + // + //Enable HPET at FED0_0000h =E2=80=93 FED0_03FFh + // + MmioWrite8(ICH10_ROOT_COMPLEX_BASE + 0x3404, 0x80); + // + //Config and enable APIC + // + MmioWrite32(0xFEC00000 + 0X0, 0); + MmioWrite32(0xFEC00000 + 0X10, PcdGet8(PcdIoApicId)<<24); + MmioWrite8(ICH10_ROOT_COMPLEX_BASE + 0x31FF, 0x01); +} + + +VOID +BootModeInitialization ( + VOID + ) +{ + EFI_STATUS Status; + + DEBUG((EFI_D_INFO, "modeValue =3D %x\n", IoBitFieldRead16(ICH10_PMBASE_IO= + 4, 10, 12))); + if (IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12) =3D=3D 0x5) { + mBootMode =3D BOOT_ON_S3_RESUME; + } + + Status =3D PeiServicesSetBootMode (mBootMode); + ASSERT_EFI_ERROR (Status); + + Status =3D PeiServicesInstallPpi (mPpiBootMode); + ASSERT_EFI_ERROR (Status); +} + + +VOID +ReserveEmuVariableNvStore ( + ) +{ + EFI_PHYSICAL_ADDRESS VariableStore; + + // + // Allocate storage for NV variables early on so it will be + // at a consistent address. Since VM memory is preserved + // across reboots, this allows the NV variable storage to survive + // a VM reboot. + // + VariableStore =3D + (EFI_PHYSICAL_ADDRESS)(UINTN) + AllocateRuntimePages ( + EFI_SIZE_TO_PAGES (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)) + ); + DEBUG ((EFI_D_INFO, + "Reserved variable store memory: 0x%lX; size: %dkb\n", + VariableStore, + (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / 1024 + )); + PcdSet64 (PcdEmuVariableNvStoreReserved, VariableStore); +} + + +VOID +SimicsVersionCheck( + VOID + ) +{ + + UINTN PciAddrPtr; + UINT8 CapOffset; + STATIC CHAR8 SimicsStr[0x100]; + UINTN i; + UINT32 MajorVersion; + UINT32 MinorVersion; + UINT32 ModelNumber; + + PciAddrPtr =3D PCI_LIB_ADDRESS(0, SIMICS_SIDEBANDPCI_DEV, SIMICS_SIDEBAN= DPCI_FUNC, 0); + CapOffset =3D PciRead8(PciAddrPtr + PCI_CAPBILITY_POINTER_OFFSET); + if (CapOffset !=3D 0xFF) { + ModelNumber =3D PciRead32(PciAddrPtr + CapOffset + 4); + MajorVersion =3D PciRead32(PciAddrPtr + CapOffset + 8); + MinorVersion =3D PciRead32(PciAddrPtr + CapOffset + 0xc); + for (i =3D 0; i < 0x80; i++) { + SimicsStr[i] =3D PciRead8(PciAddrPtr + CapOffset + 0x10 + i); + } + DEBUG((EFI_D_INFO, "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3DSIMICS Vers= ion info=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n")); + DEBUG((EFI_D_INFO, "Model number =3D %d\n", ModelNumber)); + DEBUG((EFI_D_INFO, "Major version =3D %d\n", MajorVersion)); + DEBUG((EFI_D_INFO, "Minor version =3D %d\n", MinorVersion)); + DEBUG((EFI_D_INFO, "%a\n", SimicsStr)); + DEBUG((EFI_D_INFO, "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D\n")); + } +} + +VOID +DebugDumpCmos ( + VOID + ) +{ + UINT32 Loop; + + DEBUG ((EFI_D_INFO, "CMOS:\n")); + + for (Loop =3D 0; Loop < 0x80; Loop++) { + if ((Loop % 0x10) =3D=3D 0) { + DEBUG ((EFI_D_INFO, "%02x:", Loop)); + } + DEBUG ((EFI_D_INFO, " %02x", CmosRead8 (Loop))); + if ((Loop % 0x10) =3D=3D 0xf) { + DEBUG ((EFI_D_INFO, "\n")); + } + } +} + + +/** + Fetch the number of boot CPUs from QEMU and expose it to UefiCpuPkg modu= les. + Set the mMaxCpuCount variable. +**/ +VOID +MaxCpuCountInitialization ( + VOID + ) +{ + mMaxCpuCount =3D PcdGet32 (PcdCpuMaxLogicalProcessorNumber); + return; +} + +/** + Determine if S3 support is explicitly enabled. + + @retval TRUE If S3 support is explicitly enabled. Other functions in = this + library may be called (subject to their individual + restrictions). + + FALSE Otherwise. This includes unavailability of the firmware + configuration interface. No other function in this library + must be called. +**/ +BOOLEAN +EFIAPI +QemuFwCfgS3Enabled( + VOID +) +{ + //TO DO IF NEEDED + return TRUE; +} + +/** + Perform Platform PEI initialization. + + @param FileHandle Handle of the file being invoked. + @param PeiServices Describes the list of possible PEI Services. + + @return EFI_SUCCESS The PEIM initialized successfully. + +**/ +EFI_STATUS +EFIAPI +InitializePlatform ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + + DEBUG ((EFI_D_ERROR, "Platform PEIM Loaded\n")); + + SimicsVersionCheck (); + DebugDumpCmos (); + + if (QemuFwCfgS3Enabled ()) { + DEBUG ((EFI_D_INFO, "S3 support was detected on SIMICS\n")); + mS3Supported =3D TRUE; + Status =3D PcdSetBoolS (PcdAcpiS3Enable, TRUE); + ASSERT_EFI_ERROR (Status); + } + AddressWidthInitialization (); + MaxCpuCountInitialization (); + + mHostBridgeDevId =3D PciRead16(SIMICS_HOSTBRIDGE_DID); + + if (FeaturePcdGet (PcdSmmSmramRequire)) { + X58TsegMbytesInitialization (); + } + + PublishPeiMemory (); + + InitializeRamRegions (); + + if (mBootMode !=3D BOOT_ON_S3_RESUME) { + if (!FeaturePcdGet (PcdSmmSmramRequire)) { + ReserveEmuVariableNvStore (); + } + MemMapInitialization (); + } + + MiscInitialization (); + InstallFeatureControlCallback (); + + return EFI_SUCCESS; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlat= formDxe.c b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatf= ormDxe.c new file mode 100644 index 0000000000..7165c0a0c3 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe= .c @@ -0,0 +1,148 @@ +/** @file + This driver installs SMBIOS information for QSP + + Copyright (c) 2011, Bei Guan + Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "SmbiosPlatformDxe.h" + + +/** +Reads 8-bits of CMOS data. + +Reads the 8-bits of CMOS data at the location specified by Index. +The 8-bit read value is returned. + +@param Index The CMOS location to read. + +@return The value read. + +**/ +UINT8 +EFIAPI +CmosRead8( + IN UINTN Index + ) +{ + IoWrite8(0x70, (UINT8)Index); + return IoRead8(0x71); +} + +UINT32 +GetSystemMemorySizeBelow4gb( + VOID + ) +{ + UINT8 Cmos0x34; + UINT8 Cmos0x35; + + // + // CMOS 0x34/0x35 specifies the system memory above 16 MB. + // * CMOS(0x35) is the high byte + // * CMOS(0x34) is the low byte + // * The size is specified in 64kb chunks + // * Since this is memory above 16MB, the 16MB must be added + // into the calculation to get the total memory size. + // + + Cmos0x34 =3D (UINT8)CmosRead8(0x34); + Cmos0x35 =3D (UINT8)CmosRead8(0x35); + + return (UINT32)(((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB); +} + +STATIC +UINT64 +GetSystemMemorySizeAbove4gb( + VOID +) +{ + UINT32 Size; + UINTN CmosIndex; + + // + // CMOS 0x5b-0x5d specifies the system memory above 4GB MB. + // * CMOS(0x5d) is the most significant size byte + // * CMOS(0x5c) is the middle size byte + // * CMOS(0x5b) is the least significant size byte + // * The size is specified in 64kb chunks + // + + Size =3D 0; + for (CmosIndex =3D 0x5d; CmosIndex >=3D 0x5b; CmosIndex--) { + Size =3D (UINT32)(Size << 8) + (UINT32)CmosRead8(CmosIndex); + } + + return LShiftU64(Size, 16); +} + +/** + Installs SMBIOS information for SIMICS QSP + + @param ImageHandle Module's image handle + @param SystemTable Pointer of EFI_SYSTEM_TABLE + + @retval EFI_SUCCESS Smbios data successfully installed + @retval Other Smbios data was not installed + +**/ +EFI_STATUS +EFIAPI +SmbiosTablePublishEntry ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_SMBIOS_PROTOCOL *Smbios; + SMBIOS_TABLE_TYPE19 *Type19Record; + EFI_SMBIOS_HANDLE MemArrayMappedAddrSmbiosHandle; + UINT8 NumSlots; + UINT64 TotalMemorySize; + + // + // Find the SMBIOS protocol + // + Status =3D gBS->LocateProtocol ( + &gEfiSmbiosProtocolGuid, + NULL, + (VOID**)&Smbios + ); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Generate Memory Array Mapped Address info + // + NumSlots =3D 2; + TotalMemorySize =3D 0; + TotalMemorySize =3D GetSystemMemorySizeBelow4gb(); + Type19Record =3D AllocatePool(sizeof(SMBIOS_TABLE_TYPE19)); + ZeroMem(Type19Record, sizeof(SMBIOS_TABLE_TYPE19)); + Type19Record->Hdr.Type =3D EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS; + Type19Record->Hdr.Length =3D sizeof(SMBIOS_TABLE_TYPE19); + Type19Record->Hdr.Handle =3D 0; + Type19Record->StartingAddress =3D 0; + Type19Record->EndingAddress =3D (UINT32)RShiftU64(TotalMemorySize, 10) -= 1; + Type19Record->MemoryArrayHandle =3D SMBIOS_HANDLE_PI_RESERVED; + Type19Record->PartitionWidth =3D (UINT8)(NumSlots); + + MemArrayMappedAddrSmbiosHandle =3D SMBIOS_HANDLE_PI_RESERVED; + Status =3D Smbios->Add(Smbios, NULL, &MemArrayMappedAddrSmbiosHandle, (E= FI_SMBIOS_TABLE_HEADER*)Type19Record); + ASSERT_EFI_ERROR(Status); + + TotalMemorySize =3D GetSystemMemorySizeAbove4gb(); + Type19Record->StartingAddress =3D 0xFFFFFFFF; + Type19Record->ExtendedStartingAddress =3D 0xFFFFFFFF; + Type19Record->ExtendedEndingAddress =3D TotalMemorySize + 0xFFFFFFFF - 1; + + MemArrayMappedAddrSmbiosHandle =3D SMBIOS_HANDLE_PI_RESERVED; + Status =3D Smbios->Add(Smbios, NULL, &MemArrayMappedAddrSmbiosHandle, (E= FI_SMBIOS_TABLE_HEADER*)Type19Record); + FreePool(Type19Record); + ASSERT_EFI_ERROR(Status); + + return Status; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsBoardConf= ig.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsBoardConfig.h new file mode 100644 index 0000000000..acb2c4eee4 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsBoardConfig.h @@ -0,0 +1,18 @@ +/** @file + GUID for UEFI variables that are specific to Simics Board configuration. + + Copyright (C) 2014, Red Hat, Inc. + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __SIMICS_BOARD_CONFIG_H__ +#define __SIMICS_BOARD_CONFIG_H__ + +#define SIMICS_BOARD_CONFIG_GUID \ +{0x8a318e00, 0xfaf5, 0x499f, { 0x91,0x75, 0xce, 0x4d, 0x8d, 0xa6, 0x70, 0x= ae}} + +extern EFI_GUID gSimicsBoardConfigGuid; + +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/I44= 0FxPiix4.h b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/I44= 0FxPiix4.h new file mode 100644 index 0000000000..a2225493f7 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/I440FxPiix= 4.h @@ -0,0 +1,50 @@ +/** @file + Various register numbers and value bits based on the following publicati= ons: + - Intel(R) datasheet 290549-001 + - Intel(R) datasheet 290562-001 + - Intel(R) datasheet 297654-006 + - Intel(R) datasheet 297738-017 + + Copyright (C) 2015, Red Hat, Inc. + Copyright (c) 2014, Gabriel L. Somlo + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __I440FX_PIIX4_H__ +#define __I440FX_PIIX4_H__ + +#include + +// +// Host Bridge Device ID (DID) value for I440FX +// +#define INTEL_82441_DEVICE_ID 0x1237 + +// +// B/D/F/Type: 0/0/0/PCI +// +#define PMC_REGISTER_PIIX4(Offset) PCI_LIB_ADDRESS (0, 0, 0, (Offset)) + +#define PIIX4_PAM0 0x59 +#define PIIX4_PAM1 0x5A +#define PIIX4_PAM2 0x5B +#define PIIX4_PAM3 0x5C +#define PIIX4_PAM4 0x5D +#define PIIX4_PAM5 0x5E +#define PIIX4_PAM6 0x5F + +// +// B/D/F/Type: 0/1/3/PCI +// +#define POWER_MGMT_REGISTER_PIIX4(Offset) PCI_LIB_ADDRESS (0, 1, 3, (Offse= t)) + +#define PIIX4_PMBA 0x40 +#define PIIX4_PMBA_MASK (BIT15 | BIT14 | BIT13 | BIT12 | BIT11 | \ + BIT10 | BIT9 | BIT8 | BIT7 | BIT6) + +#define PIIX4_PMREGMISC 0x80 +#define PIIX4_PMREGMISC_PMIOSE BIT0 + +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/Lin= uxBzImage.h b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/Li= nuxBzImage.h new file mode 100644 index 0000000000..2708b1891d --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/LinuxBzIma= ge.h @@ -0,0 +1,159 @@ +/** @file + + Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __LINUX_BZIMAGE_H__ +#define __LINUX_BZIMAGE_H__ + +#define BOOTSIG 0x1FE +#define SETUP_HDR 0x53726448 /* 0x53726448 =3D=3D "HdrS" */ + +#define E820_RAM 1 +#define E820_RESERVED 2 +#define E820_ACPI 3 +#define E820_NVS 4 +#define E820_UNUSABLE 5 + +#pragma pack(1) + +struct setup_header { + UINT8 setup_secs; /* Sectors for setup code */ + UINT16 root_flags; + UINT32 sys_size; + UINT16 ram_size; + UINT16 video_mode; + UINT16 root_dev; + UINT16 signature; /* Boot signature */ + UINT16 jump; + UINT32 header; + UINT16 version; + UINT16 su_switch; + UINT16 setup_seg; + UINT16 start_sys; + UINT16 kernel_ver; + UINT8 loader_id; + UINT8 load_flags; + UINT16 movesize; + UINT32 code32_start; /* Start of code loaded high */ + UINT32 ramdisk_start; /* Start of initial ramdisk */ + UINT32 ramdisk_len; /* Length of initial ramdisk */ + UINT32 bootsect_kludge; + UINT16 heap_end; + UINT8 ext_loader_ver; /* Extended boot loader version */ + UINT8 ext_loader_type; /* Extended boot loader ID */ + UINT32 cmd_line_ptr; /* 32-bit pointer to the kernel command line */ + UINT32 ramdisk_max; /* Highest legal initrd address */ + UINT32 kernel_alignment; /* Physical addr alignment required for kernel= */ + UINT8 relocatable_kernel; /* Whether kernel is relocatable or not */ + UINT8 min_alignment; + UINT16 xloadflags; + UINT32 cmdline_size; + UINT32 hardware_subarch; + UINT64 hardware_subarch_data; + UINT32 payload_offset; + UINT32 payload_length; + UINT64 setup_data; + UINT64 pref_address; + UINT32 init_size; + UINT32 handover_offset; +}; + +struct efi_info { + UINT32 efi_loader_signature; + UINT32 efi_systab; + UINT32 efi_memdesc_size; + UINT32 efi_memdesc_version; + UINT32 efi_memmap; + UINT32 efi_memmap_size; + UINT32 efi_systab_hi; + UINT32 efi_memmap_hi; +}; + +struct e820_entry { + UINT64 addr; /* start of memory segment */ + UINT64 size; /* size of memory segment */ + UINT32 type; /* type of memory segment */ +}; + +struct screen_info { + UINT8 orig_x; /* 0x00 */ + UINT8 orig_y; /* 0x01 */ + UINT16 ext_mem_k; /* 0x02 */ + UINT16 orig_video_page; /* 0x04 */ + UINT8 orig_video_mode; /* 0x06 */ + UINT8 orig_video_cols; /* 0x07 */ + UINT8 flags; /* 0x08 */ + UINT8 unused2; /* 0x09 */ + UINT16 orig_video_ega_bx;/* 0x0a */ + UINT16 unused3; /* 0x0c */ + UINT8 orig_video_lines; /* 0x0e */ + UINT8 orig_video_isVGA; /* 0x0f */ + UINT16 orig_video_points;/* 0x10 */ + + /* VESA graphic mode -- linear frame buffer */ + UINT16 lfb_width; /* 0x12 */ + UINT16 lfb_height; /* 0x14 */ + UINT16 lfb_depth; /* 0x16 */ + UINT32 lfb_base; /* 0x18 */ + UINT32 lfb_size; /* 0x1c */ + UINT16 cl_magic, cl_offset; /* 0x20 */ + UINT16 lfb_linelength; /* 0x24 */ + UINT8 red_size; /* 0x26 */ + UINT8 red_pos; /* 0x27 */ + UINT8 green_size; /* 0x28 */ + UINT8 green_pos; /* 0x29 */ + UINT8 blue_size; /* 0x2a */ + UINT8 blue_pos; /* 0x2b */ + UINT8 rsvd_size; /* 0x2c */ + UINT8 rsvd_pos; /* 0x2d */ + UINT16 vesapm_seg; /* 0x2e */ + UINT16 vesapm_off; /* 0x30 */ + UINT16 pages; /* 0x32 */ + UINT16 vesa_attributes; /* 0x34 */ + UINT32 capabilities; /* 0x36 */ + UINT8 _reserved[6]; /* 0x3a */ +}; + +struct boot_params { +struct screen_info screen_info; + UINT8 apm_bios_info[0x14]; + UINT8 _pad2[4]; + UINT64 tboot_addr; + UINT8 ist_info[0x10]; + UINT8 _pad3[16]; + UINT8 hd0_info[16]; + UINT8 hd1_info[16]; + UINT8 sys_desc_table[0x10]; + UINT8 olpc_ofw_header[0x10]; + UINT8 _pad4[128]; + UINT8 edid_info[0x80]; + struct efi_info efi_info; + UINT32 alt_mem_k; + UINT32 scratch; + UINT8 e820_entries; + UINT8 eddbuf_entries; + UINT8 edd_mbr_sig_buf_entries; + UINT8 _pad6[6]; + struct setup_header hdr; + UINT8 _pad7[0x290-0x1f1-sizeof(struct setup_header)]; + UINT32 edd_mbr_sig_buffer[16]; + struct e820_entry e820_map[128]; + UINT8 _pad8[48]; + UINT8 eddbuf[0x1ec]; + UINT8 _pad9[276]; +}; + +typedef struct { + UINT16 limit; + UINT64 *base; +} dt_addr_t; + +#pragma pack() + +extern EFI_STATUS setup_graphics(struct boot_params *buf); + +#endif /* __LINUX_BZIMAGE_H__ */ diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Library/LoadLinuxLib= .h b/Platform/Intel/SimicsOpenBoardPkg/Include/Library/LoadLinuxLib.h new file mode 100644 index 0000000000..483f8d4b9c --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Library/LoadLinuxLib.h @@ -0,0 +1,205 @@ +/** @file + Load/boot UEFI Linux. + + Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __LOAD_LINUX_LIB__ +#define __LOAD_LINUX_LIB__ + + +/** + Verifies that the kernel setup image is valid and supported. + The kernel setup image should be checked before using other library + routines which take the kernel setup as an input. + + @param[in] KernelSetup - The kernel setup image + @param[in] KernelSetupSize - The kernel setup size + + @retval EFI_SUCCESS - The Linux kernel setup is valid and supported + @retval EFI_INVALID_PARAMETER - KernelSetup was NULL + @retval EFI_UNSUPPORTED - The Linux kernel is not supported + +**/ +EFI_STATUS +EFIAPI +LoadLinuxCheckKernelSetup ( + IN VOID *KernelSetup, + IN UINTN KernelSetupSize + ); + + +/** + Gets the initial runtime size of the Linux kernel image by examining + the kernel setup image. + + @param[in] KernelSetup - The kernel setup image + @param[in] KernelSize - The kernel size on disk. + + @retval 0 An error occurred + @retval !0 The initial size required by the kernel to + begin execution. + +**/ +UINTN +EFIAPI +LoadLinuxGetKernelSize ( + IN VOID *KernelSetup, + IN UINTN KernelSize + ); + + +/** + Loads and boots UEFI Linux. + + Note: If successful, then this routine will not return + + @param[in] Kernel - The main kernel image + @param[in,out] KernelSetup - The kernel setup image + + @retval EFI_NOT_FOUND - The Linux kernel was not found + @retval EFI_INVALID_PARAMETER - Kernel or KernelSetup was NULL + @retval EFI_UNSUPPORTED - The Linux kernel version is not supported + +**/ +EFI_STATUS +EFIAPI +LoadLinux ( + IN VOID *Kernel, + IN OUT VOID *KernelSetup + ); + + +/** + Allocates pages for the kernel setup image. + + @param[in] Pages - The number of pages + + @retval NULL - Unable to allocate pages + @retval !NULL - The address of the pages allocated + +**/ +VOID* +EFIAPI +LoadLinuxAllocateKernelSetupPages ( + IN UINTN Pages + ); + + +/** + Clears the uninitialised space before and after the struct setup_header + in the kernel setup image. The kernel requires that these be zeroed + unless explicitly initialised, so this function should be called after + the setup_header has been copied in from a bzImage, before setting up + anything else. + + @param[in] KernelSetup - The kernel setup image + + @retval EFI_SUCCESS - The Linux kernel setup was successfully initial= ized + @retval EFI_INVALID_PARAMETER - KernelSetup was NULL + @retval EFI_UNSUPPORTED - The Linux kernel is not supported + +**/ +EFI_STATUS +EFIAPI +LoadLinuxInitializeKernelSetup ( + IN VOID *KernelSetup + ); + +/** + Allocates pages for the kernel. + + @param[in] KernelSetup - The kernel setup image + @param[in] Pages - The number of pages. (It is recommended to use the + size returned from LoadLinuxGetKernelSize.) + + @retval NULL - Unable to allocate pages + @retval !NULL - The address of the pages allocated + +**/ +VOID* +EFIAPI +LoadLinuxAllocateKernelPages ( + IN VOID *KernelSetup, + IN UINTN Pages + ); + + +/** + Allocates pages for the kernel command line. + + @param[in] Pages - The number of pages. + + @retval NULL - Unable to allocate pages + @retval !NULL - The address of the pages allocated + +**/ +VOID* +EFIAPI +LoadLinuxAllocateCommandLinePages ( + IN UINTN Pages + ); + + +/** + Allocates pages for the initrd image. + + @param[in,out] KernelSetup - The kernel setup image + @param[in] Pages - The number of pages. + + @retval NULL - Unable to allocate pages + @retval !NULL - The address of the pages allocated + +**/ +VOID* +EFIAPI +LoadLinuxAllocateInitrdPages ( + IN VOID *KernelSetup, + IN UINTN Pages + ); + + +/** + Sets the kernel command line parameter within the setup image. + + @param[in,out] KernelSetup - The kernel setup image + @param[in] CommandLine - The kernel command line + + @retval EFI_SUCCESS - The Linux kernel setup is valid and supported + @retval EFI_INVALID_PARAMETER - KernelSetup was NULL + @retval EFI_UNSUPPORTED - The Linux kernel is not supported + +**/ +EFI_STATUS +EFIAPI +LoadLinuxSetCommandLine ( + IN OUT VOID *KernelSetup, + IN CHAR8 *CommandLine + ); + + +/** + Sets the kernel initial ram disk pointer within the setup image. + + @param[in,out] KernelSetup - The kernel setup image + @param[in] Initrd - Pointer to the initial ram disk + @param[in] InitrdSize - The initial ram disk image size + + @retval EFI_SUCCESS - The Linux kernel setup is valid and supported + @retval EFI_INVALID_PARAMETER - KernelSetup was NULL + @retval EFI_UNSUPPORTED - The Linux kernel is not supported + +**/ +EFI_STATUS +EFIAPI +LoadLinuxSetInitrd ( + IN OUT VOID *KernelSetup, + IN VOID *Initrd, + IN UINTN InitrdSize + ); + + +#endif + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Library/SerializeVar= iablesLib.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Library/SerializeVa= riablesLib.h new file mode 100644 index 0000000000..c32f97d787 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Library/SerializeVariablesL= ib.h @@ -0,0 +1,224 @@ +/** @file + Serialize & Deserialize UEFI Variables + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __SERIALIZE_VARIABLES_LIB__ +#define __SERIALIZE_VARIABLES_LIB__ + + +/** + Callback function for each variable + + @param[in] Context - Context as sent to the iteration function + @param[in] VariableName - Refer to RuntimeServices GetNextVariableName + @param[in] VendorGuid - Refer to RuntimeServices GetNextVariableName + @param[in] Attributes - Refer to RuntimeServices GetVariable + @param[in] DataSize - Refer to RuntimeServices GetVariable + @param[in] Data - Refer to RuntimeServices GetVariable + + @retval RETURN_SUCCESS Continue iterating through the variables + @return Any RETURN_ERROR Stop iterating through the variables + +**/ +typedef +RETURN_STATUS +(EFIAPI *VARIABLE_SERIALIZATION_ITERATION_CALLBACK)( + IN VOID *Context, + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ); + + +/** + Creates a new variable serialization instance + + @param[out] Handle - Handle for a variable serialization instance + + @retval RETURN_SUCCESS - The variable serialization instance was + successfully created. + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to + create the variable serialization instance. + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesNewInstance ( + OUT EFI_HANDLE *Handle + ); + + +/** + Free memory associated with a variable serialization instance + + @param[in] Handle - Handle for a variable serialization instance + + @retval RETURN_SUCCESS - The variable serialization instance was + successfully freed. + @retval RETURN_INVALID_PARAMETER - Handle was not a valid + variable serialization instance. + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesFreeInstance ( + IN EFI_HANDLE Handle + ); + + +/** + Creates a new variable serialization instance using the given + binary representation of the variables to fill the new instance + + @param[out] Handle - Handle for a variable serialization instance + @param[in] Buffer - A buffer with the serialized representation + of the variables. Must be the same format as produced + by SerializeVariablesToBuffer. + @param[in] Size - This is the size of the binary representation + of the variables. + + @retval RETURN_SUCCESS - The binary representation was successfully + imported into a new variable serialization instance + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to + create the new variable serialization instance + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesNewInstanceFromBuffer ( + OUT EFI_HANDLE *Handle, + IN VOID *Buffer, + IN UINTN Size + ); + + +/** + Iterates all variables found with RuntimeServices GetNextVariableName + + @param[in] CallbackFunction - Function called for each variable instan= ce + @param[in] Context - Passed to each call of CallbackFunction + + @retval RETURN_SUCCESS - All variables were iterated without the + CallbackFunction returning an error + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to + iterate through the variables + @return Any of RETURN_ERROR indicates an error reading the variable + or an error was returned from CallbackFunction + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesIterateSystemVariables ( + IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction, + IN VOID *Context + ); + + +/** + Iterates all variables found in the variable serialization instance + + @param[in] Handle - Handle for a variable serialization instance + @param[in] CallbackFunction - Function called for each variable instan= ce + @param[in] Context - Passed to each call of CallbackFunction + + @retval RETURN_SUCCESS - All variables were iterated without the + CallbackFunction returning an error + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to + iterate through the variables + @return Any of RETURN_ERROR indicates an error reading the variable + or an error was returned from CallbackFunction + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesIterateInstanceVariables ( + IN EFI_HANDLE Handle, + IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction, + IN VOID *Context + ); + + +/** + Sets all variables found in the variable serialization instance + + @param[in] Handle - Handle for a variable serialization instance + + @retval RETURN_SUCCESS - All variables were set successfully + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to + set all the variables + @return Any of RETURN_ERROR indicates an error reading the variables + or in attempting to set a variable + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesSetSerializedVariables ( + IN EFI_HANDLE Handle + ); + + +/** + Adds a variable to the variable serialization instance + + @param[in] Handle - Handle for a variable serialization instance + @param[in] VariableName - Refer to RuntimeServices GetVariable + @param[in] VendorGuid - Refer to RuntimeServices GetVariable + @param[in] Attributes - Refer to RuntimeServices GetVariable + @param[in] DataSize - Refer to RuntimeServices GetVariable + @param[in] Data - Refer to RuntimeServices GetVariable + + @retval RETURN_SUCCESS - All variables were set successfully + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to + add the variable + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesAddVariable ( + IN EFI_HANDLE Handle, + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ); + + +/** + Serializes the variables known to this instance into the + provided buffer. + + @param[in] Handle - Handle for a variable serialization instance + @param[out] Buffer - A buffer to store the binary representation + of the variables. + @param[in,out] Size - On input this is the size of the buffer. + On output this is the size of the binary representation + of the variables. + + @retval RETURN_SUCCESS - The binary representation was successfully + completed and returned in the buffer. + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to + save the variables to the buffer. + @retval RETURN_INVALID_PARAMETER - Handle was not a valid + variable serialization instance or + Size or Buffer were NULL. + +**/ +RETURN_STATUS +EFIAPI +SerializeVariablesToBuffer ( + IN EFI_HANDLE Handle, + OUT VOID *Buffer, + IN OUT UINTN *Size + ); + + +#endif + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h b/= Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h new file mode 100644 index 0000000000..67bb3af584 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h @@ -0,0 +1,55 @@ +/** @file + Simics Platform definitions + + Copyright (C) 2015, Red Hat, Inc. + Copyright (c) 2014, Gabriel L. Somlo + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __SIMICS_PLATFORMS_H__ +#define __SIMICS_PLATFORMS_H__ + +#include +#include +#include +#include + +// +// Simics Host Bridge DID Address +// +#define SIMICS_HOSTBRIDGE_DID \ + PCI_LIB_ADDRESS (0, 0, 0, PCI_DEVICE_ID_OFFSET) + +// +// Simics SideBand PCI device registers +// +#define SIMICS_SIDEBANDPCI_DEV 0 +#define SIMICS_SIDEBANDPCI_FUNC 7 +#define SIMICS_SIDEBANDPCI_SVID \ + PCI_LIB_ADDRESS (0, 0, 7, PCI_SVID_OFFSET) +#define SIMICS_SIDEBANDPCI_SDID \ + PCI_LIB_ADDRESS (0, 0, 7, PCI_SID_OFFSET) +#define SIMICS_SIDEBANDPCI_CAP \ + PCI_LIB_ADDRESS (0, 0, 7, PCI_CAPBILITY_POINTER_OFFSET) +#define SIMICS_SIDEBANDPCI_CAP_Offset 0x40 +#define SIMICS_SIDEBANDPCI_CAP_ID 0xFF + +// +// Values we program into the PM base address registers +// +#define PIIX4_PMBA_VALUE 0xB000 +#define ICH10_PMBASE_VALUE 0x0400 + +// +// Common bits in same-purpose registers +// +#define PMBA_RTE BIT0 + +// +// Common IO ports relative to the Power Management Base Address +// +#define ACPI_TIMER_OFFSET 0x8 + +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/DxeLogoLi= b.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/DxeLogoLib.inf new file mode 100644 index 0000000000..ff08c385b3 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/DxeLogoLib.inf @@ -0,0 +1,55 @@ +### @file +# Module that show progress bar and title above it. +# +# General BDS defines and produce general interfaces for platform BDS driv= er including: +# 1) BDS boot policy interface; +# 2) BDS boot device connect interface; +# 3) BDS Misc interfaces for mainting boot variable, ouput string, etc. +# +# Copyright (c) 2007 - 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +### + +[Defines] + INF_VERSION =3D 0x00010017 + BASE_NAME =3D DxeLogoLib + FILE_GUID =3D F5AE5B5C-42E8-4A9B-829D-5B631CD5367A + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D DXE_DRIVER + LIBRARY_CLASS =3D LogoLib|DXE_DRIVER UEFI_APPLICATION +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC +# + +[LibraryClasses] + BaseLib + UefiBootServicesTableLib + MemoryAllocationLib + UefiLib + BaseMemoryLib + DebugLib + PrintLib + PcdLib + DxeServicesLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SimicsOpenBoardPkg/OpenBoardPkg.dec + +[FeaturePcd] + gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport + +[Sources] + Logo.c + +[Protocols] + gEfiGraphicsOutputProtocolGuid ## SOMETIMES_CONSUMES + gEfiUgaDrawProtocolGuid ## SOMETIMES_CONSUMES + gEfiBootLogoProtocolGuid ## SOMETIMES_CONSUMES + gEfiUserManagerProtocolGuid ## CONSUMES + gEfiOemBadgingProtocolGuid ## CONSUMES diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/OemBadgin= g.h b/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/OemBadging.h new file mode 100644 index 0000000000..d2c39c3dfc --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/OemBadging.h @@ -0,0 +1,83 @@ +/** @file + The OEM Badging Protocol defines the interface to get the OEM badging + image with the display attribute. This protocol can be produced based on= OEM badging images. + + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __EFI_OEM_BADGING_H__ +#define __EFI_OEM_BADGING_H__ + +// +// GUID for EFI OEM Badging Protocol +// +#define EFI_OEM_BADGING_PROTOCOL_GUID \ + { 0x170e13c0, 0xbf1b, 0x4218, {0x87, 0x1d, 0x2a, 0xbd, 0xc6, 0xf8, 0x87,= 0xbc } } + + +typedef struct _EFI_OEM_BADGING_PROTOCOL EFI_OEM_BADGING_PROTOCOL; + +typedef enum { + EfiBadgingFormatBMP, + EfiBadgingFormatJPEG, + EfiBadgingFormatTIFF, + EfiBadgingFormatGIF, + EfiBadgingFormatUnknown +} EFI_BADGING_FORMAT; + +typedef enum { + EfiBadgingDisplayAttributeLeftTop, + EfiBadgingDisplayAttributeCenterTop, + EfiBadgingDisplayAttributeRightTop, + EfiBadgingDisplayAttributeCenterRight, + EfiBadgingDisplayAttributeRightBottom, + EfiBadgingDisplayAttributeCenterBottom, + EfiBadgingDisplayAttributeLeftBottom, + EfiBadgingDisplayAttributeCenterLeft, + EfiBadgingDisplayAttributeCenter, + EfiBadgingDisplayAttributeCustomized +} EFI_BADGING_DISPLAY_ATTRIBUTE; + +/** + + Load an OEM badge image and return its data and attributes. + + @param This The pointer to this protocol instance. + @param Instance The visible image instance is found. + @param Format The format of the image. Examples: BMP, JPEG. + @param ImageData The image data for the badge file. Currently on= ly + supports the .bmp file format. + @param ImageSize The size of the image returned. + @param Attribute The display attributes of the image returned. + @param CoordinateX The X coordinate of the image. + @param CoordinateY The Y coordinate of the image. + + @retval EFI_SUCCESS The image was fetched successfully. + @retval EFI_NOT_FOUND The specified image could not be found. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BADGING_GET_IMAGE)( + IN EFI_OEM_BADGING_PROTOCOL *This, + IN OUT UINT32 *Instance, + OUT EFI_BADGING_FORMAT *Format, + OUT UINT8 **ImageData, + OUT UINTN *ImageSize, + OUT EFI_BADGING_DISPLAY_ATTRIBUTE *Attribute, + OUT UINTN *CoordinateX, + OUT UINTN *CoordinateY +); + + +struct _EFI_OEM_BADGING_PROTOCOL { + EFI_BADGING_GET_IMAGE GetImage; +}; + + +extern EFI_GUID gEfiOemBadgingProtocolGuid; + +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/DxeLoad= LinuxLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/DxeLo= adLinuxLib.inf new file mode 100644 index 0000000000..cdefeebbdd --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/DxeLoadLinuxLi= b.inf @@ -0,0 +1,42 @@ +## @file +# +# Copyright (c) 2008 - 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D DxeLoadLinuxLib + FILE_GUID =3D 63CC8497-C9D0-46A8-AC08-49DF92A2FF62 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D DxeLoadLinuxLib|DXE_DRIVER + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 +# + +[Sources.common] + Linux.c + LinuxGdt.c + +[Sources.IA32] + Ia32/JumpToKernel.nasm + +[Sources.X64] + X64/JumpToKernel.nasm + +[Packages] + MdePkg/MdePkg.dec + SimicsOpenBoardPkg/OpenBoardPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + MemoryAllocationLib + BaseMemoryLib + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/Ju= mpToKernel.nasm b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia= 32/JumpToKernel.nasm new file mode 100644 index 0000000000..c6f1c31a59 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKer= nel.nasm @@ -0,0 +1,41 @@ +; @file +; Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
+; +; SPDX-License-Identifier: BSD-2-Clause-Patent +; + + SECTION .text + +;-------------------------------------------------------------------------= ----- +; VOID +; EFIAPI +; JumpToKernel ( +; VOID *KernelStart, +; VOID *KernelBootParams +; ); +;-------------------------------------------------------------------------= ----- +global ASM_PFX(JumpToKernel) +ASM_PFX(JumpToKernel): + + mov esi, [esp + 8] + call DWORD [esp + 4] + ret + +;-------------------------------------------------------------------------= ----- +; VOID +; EFIAPI +; JumpToUefiKernel ( +; EFI_HANDLE ImageHandle, +; EFI_SYSTEM_TABLE *SystemTable, +; VOID *KernelBootParams, +; VOID *KernelStart +; ); +;-------------------------------------------------------------------------= ----- +global ASM_PFX(JumpToUefiKernel) +ASM_PFX(JumpToUefiKernel): + + mov eax, [esp + 12] + mov eax, [eax + 0x264] + add eax, [esp + 16] + jmp eax + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLin= uxLib.h b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxL= ib.h new file mode 100644 index 0000000000..9c0ab80904 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h @@ -0,0 +1,52 @@ +/** @file + Boot UEFI Linux. + + Copyright (c) 2008 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _LOAD_LINUX_LIB_INCLUDED_ +#define _LOAD_LINUX_LIB_INCLUDED_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +VOID +EFIAPI +JumpToKernel ( + VOID *KernelStart, + VOID *KernelBootParams + ); + +VOID +EFIAPI +JumpToUefiKernel ( + EFI_HANDLE ImageHandle, + EFI_SYSTEM_TABLE *SystemTable, + VOID *KernelBootParams, + VOID *KernelStart + ); + +VOID +InitLinuxDescriptorTables ( + VOID + ); + +VOID +SetLinuxDescriptorTables ( + VOID + ); + +#endif + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/Jum= pToKernel.nasm b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64= /JumpToKernel.nasm new file mode 100644 index 0000000000..2b5395f6f8 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKern= el.nasm @@ -0,0 +1,85 @@ +; @file +; Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
+; +; SPDX-License-Identifier: BSD-2-Clause-Patent +; + + DEFAULT REL + SECTION .text + +;-------------------------------------------------------------------------= ----- +; VOID +; EFIAPI +; JumpToKernel ( +; VOID *KernelStart, // rcx +; VOID *KernelBootParams // rdx +; ); +;-------------------------------------------------------------------------= ----- +global ASM_PFX(JumpToKernel) +ASM_PFX(JumpToKernel): + + ; Set up for executing kernel. BP in %esi, entry point on the stack + ; (64-bit when the 'ret' will use it as 32-bit, but we're little-endia= n) + mov rsi, rdx + push rcx + + ; Jump into the compatibility mode CS + push 0x10 + lea rax, [.0] + push rax + DB 0x48, 0xcb ; retfq + +.0: + ; Now in compatibility mode. + + DB 0xb8, 0x18, 0x0, 0x0, 0x0 ; movl $0x18, %eax + DB 0x8e, 0xd8 ; movl %eax, %ds + DB 0x8e, 0xc0 ; movl %eax, %es + DB 0x8e, 0xe0 ; movl %eax, %fs + DB 0x8e, 0xe8 ; movl %eax, %gs + DB 0x8e, 0xd0 ; movl %eax, %ss + + ; Disable paging + DB 0xf, 0x20, 0xc0 ; movl %cr0, %eax + DB 0xf, 0xba, 0xf8, 0x1f ; btcl $31, %eax + DB 0xf, 0x22, 0xc0 ; movl %eax, %cr0 + + ; Disable long mode in EFER + DB 0xb9, 0x80, 0x0, 0x0, 0xc0 ; movl $0x0c0000080, %ecx + DB 0xf, 0x32 ; rdmsr + DB 0xf, 0xba, 0xf8, 0x8 ; btcl $8, %eax + DB 0xf, 0x30 ; wrmsr + + ; Disable PAE + DB 0xf, 0x20, 0xe0 ; movl %cr4, %eax + DB 0xf, 0xba, 0xf8, 0x5 ; btcl $5, %eax + DB 0xf, 0x22, 0xe0 ; movl %eax, %cr4 + + DB 0x31, 0xed ; xor %ebp, %ebp + DB 0x31, 0xff ; xor %edi, %edi + DB 0x31, 0xdb ; xor %ebx, %ebx + DB 0xc3 ; ret + +;-------------------------------------------------------------------------= ----- +; VOID +; EFIAPI +; JumpToUefiKernel ( +; EFI_HANDLE ImageHandle, // rcx +; EFI_SYSTEM_TABLE *SystemTable, // rdx +; VOID *KernelBootParams // r8 +; VOID *KernelStart, // r9 +; ); +;-------------------------------------------------------------------------= ----- +global ASM_PFX(JumpToUefiKernel) +ASM_PFX(JumpToUefiKernel): + + mov rdi, rcx + mov rsi, rdx + mov rdx, r8 + xor rax, rax + mov eax, [r8 + 0x264] + add r9, rax + add r9, 0x200 + call r9 + ret + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVars= FileLib.h b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsF= ileLib.h new file mode 100644 index 0000000000..80776fd003 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib= .h @@ -0,0 +1,55 @@ +/** @file + Save Non-Volatile Variables to a file system. + + Copyright (c) 2009 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __NV_VARS_FILE_LIB_INSTANCE__ +#define __NV_VARS_FILE_LIB_INSTANCE__ + +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include + +/** + Loads the non-volatile variables from the NvVars file on the + given file system. + + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid ins= tance + + @return EFI_STATUS based on the success or failure of load operation + +**/ +EFI_STATUS +LoadNvVarsFromFs ( + EFI_HANDLE FsHandle + ); + + +/** + Saves the non-volatile variables into the NvVars file on the + given file system. + + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid ins= tance + + @return EFI_STATUS based on the success or failure of load operation + +**/ +EFI_STATUS +SaveNvVarsToFs ( + EFI_HANDLE FsHandle + ); + +#endif + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVars= FileLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVar= sFileLib.inf new file mode 100644 index 0000000000..4731e77865 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib= .inf @@ -0,0 +1,53 @@ +## @file +# NvVarsFileLib +# +# This library saves and restores non-volatile variables in a +# file within a file system. +# +# Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D NvVarsFileLib + FILE_GUID =3D 8ECD4CC0-1772-4583-8A74-83633A15FAA0 + MODULE_TYPE =3D UEFI_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D NvVarsFileLib|DXE_DRIVER DXE_RUNTIME_= DRIVER UEFI_DRIVER + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC +# + +[Sources] + FsAccess.c + NvVarsFileLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ShellPkg/ShellPkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + FileHandleLib + MemoryAllocationLib + SerializeVariablesLib + +[Protocols] + gEfiSimpleFileSystemProtocolGuid ## CONSUMES + +[Guids] + gEfiFileInfoGuid + +[Depex] + gEfiVariableWriteArchProtocolGuid + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/Pci= HostBridge.h b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/P= ciHostBridge.h new file mode 100644 index 0000000000..0c75430260 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBri= dge.h @@ -0,0 +1,68 @@ +/** @file + Header file of OVMF instance of PciHostBridgeLib. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +PCI_ROOT_BRIDGE * +ScanForRootBridges ( + UINTN *NumberOfRootBridges +); + +/** + Initialize a PCI_ROOT_BRIDGE structure. + + @param[in] Supports Supported attributes. + + @param[in] Attributes Initial attributes. + + @param[in] AllocAttributes Allocation attributes. + + @param[in] RootBusNumber The bus number to store in RootBus. + + @param[in] MaxSubBusNumber The inclusive maximum bus number that can be + assigned to any subordinate bus found behin= d any + PCI bridge hanging off this root bus. + + The caller is repsonsible for ensuring that + RootBusNumber <=3D MaxSubBusNumber. If + RootBusNumber equals MaxSubBusNumber, then = the + root bus has no room for subordinate buses. + + @param[in] Io IO aperture. + + @param[in] Mem MMIO aperture. + + @param[in] MemAbove4G MMIO aperture above 4G. + + @param[in] PMem Prefetchable MMIO aperture. + + @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G. + + @param[out] RootBus The PCI_ROOT_BRIDGE structure (allocated by= the + caller) that should be filled in by this + function. + + @retval EFI_SUCCESS Initialization successful. A device path + consisting of an ACPI device path node, wi= th + UID =3D RootBusNumber, has been allocated = and + linked into RootBus. + + @retval EFI_OUT_OF_RESOURCES Memory allocation failed. +**/ +EFI_STATUS +InitRootBridge ( + IN UINT64 Supports, + IN UINT64 Attributes, + IN UINT64 AllocAttributes, + IN UINT8 RootBusNumber, + IN UINT8 MaxSubBusNumber, + IN PCI_ROOT_BRIDGE_APERTURE *Io, + IN PCI_ROOT_BRIDGE_APERTURE *Mem, + IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G, + IN PCI_ROOT_BRIDGE_APERTURE *PMem, + IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G, + OUT PCI_ROOT_BRIDGE *RootBus + ); diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/Pci= HostBridgeLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridge= Lib/PciHostBridgeLib.inf new file mode 100644 index 0000000000..e1920bd2ff --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBri= dgeLib.inf @@ -0,0 +1,51 @@ +## @file +# Simics's instance of the PCI Host Bridge Library. +# +# Copyright (C) 2016, Red Hat, Inc. +# Copyright (c) 2016 - 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D PciHostBridgeLib + FILE_GUID =3D 2F04EC41-C3A0-43EB-AC6A-409F973F4439 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D PciHostBridgeLib + +# +# The following information is for reference only and not required by the = build +# tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC +# + +[Sources] + PciHostBridgeLib.c + PciHostBridge.h + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + SimicsOpenBoardPkg/OpenBoardPkg.dec + SimicsIch10Pkg/Ich10Pkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + DevicePathLib + MemoryAllocationLib + PciLib + +[Pcd] + gBoardModuleTokenSpaceGuid.PcdPciIoBase + gBoardModuleTokenSpaceGuid.PcdPciIoSize + gBoardModuleTokenSpaceGuid.PcdPciMmio32Base + gBoardModuleTokenSpaceGuid.PcdPciMmio32Size + gBoardModuleTokenSpaceGuid.PcdPciMmio64Base + gBoardModuleTokenSpaceGuid.PcdPciMmio64Size + gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId + gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiRe= portFvLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/Pe= iReportFvLib.inf new file mode 100644 index 0000000000..bc85420f97 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvL= ib.inf @@ -0,0 +1,56 @@ +### @file +# Component information file for the Report Firmware Volume (FV) library. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +### + +[Defines] + INF_VERSION =3D 0x00010017 + BASE_NAME =3D PeiReportFvLib + FILE_GUID =3D 44328FA5-E4DD-4A15-ABDF-C6584AC363D9 + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D PEIM + LIBRARY_CLASS =3D ReportFvLib + +[LibraryClasses] + BaseMemoryLib + DebugLib + HobLib + PeiServicesLib + PcdLib + IoLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + MinPlatformPkg/MinPlatformPkg.dec + SimicsOpenBoardPkg/OpenBoardPkg.dec + SimicsX58SktPkg/SktPkg.dec + SimicsIch10Pkg/Ich10Pkg.dec + +[Sources] + PeiReportFvLib.c + Fv.c + +[Pcd] + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryBase ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootBase ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootBase ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityBase ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedBase ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize ## CONSUMES + gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvBase + gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvSize + gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvBase + gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvSize + gBoardModuleTokenSpaceGuid.PcdSimicsDecompressionScratchEnd + gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerL= ib/BdsPlatform.h b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootMa= nagerLib/BdsPlatform.h new file mode 100644 index 0000000000..01ba20d2da --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsP= latform.h @@ -0,0 +1,172 @@ +/** @file + Platform BDS customizations include file. + + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _PLATFORM_SPECIFIC_BDS_PLATFORM_H_ +#define _PLATFORM_SPECIFIC_BDS_PLATFORM_H_ + + +#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 + +extern EFI_DEVICE_PATH_PROTOCOL *gPlatformConnectSequence[]; +extern ACPI_HID_DEVICE_PATH gPnpPs2KeyboardDeviceNode; +extern ACPI_HID_DEVICE_PATH gPnp16550ComPortDeviceNode; +extern UART_DEVICE_PATH gUartDeviceNode; +extern VENDOR_DEVICE_PATH gTerminalTypeDeviceNode; + +#define PCI_DEVICE_PATH_NODE(Func, Dev) \ + { \ + { \ + HARDWARE_DEVICE_PATH, \ + HW_PCI_DP, \ + { \ + (UINT8) (sizeof (PCI_DEVICE_PATH)), \ + (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) \ + } \ + }, \ + (Func), \ + (Dev) \ + } + +#define PNPID_DEVICE_PATH_NODE(PnpId) \ + { \ + { \ + ACPI_DEVICE_PATH, \ + ACPI_DP, \ + { \ + (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \ + (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \ + }, \ + }, \ + EISA_PNP_ID((PnpId)), \ + 0 \ + } + +#define gPciIsaBridge \ + PCI_DEVICE_PATH_NODE(0, 0x1f) + +#define gP2PBridge \ + PCI_DEVICE_PATH_NODE(0, 0x1e) + +#define gPnpPs2Keyboard \ + PNPID_DEVICE_PATH_NODE(0x0303) + +#define gPnp16550ComPort \ + PNPID_DEVICE_PATH_NODE(0x0501) + +#define gUart \ + { \ + { \ + MESSAGING_DEVICE_PATH, \ + MSG_UART_DP, \ + { \ + (UINT8) (sizeof (UART_DEVICE_PATH)), \ + (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8) \ + } \ + }, \ + 0, \ + 115200, \ + 8, \ + 1, \ + 1 \ + } + +#define gPcAnsiTerminal \ + { \ + { \ + MESSAGING_DEVICE_PATH, \ + MSG_VENDOR_DP, \ + { \ + (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \ + (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \ + } \ + }, \ + DEVICE_PATH_MESSAGING_PC_ANSI \ + } + +#define PCI_CLASS_SCC 0x07 +#define PCI_SUBCLASS_SERIAL 0x00 +#define PCI_IF_16550 0x02 +#define IS_PCI_16550SERIAL(_p) IS_CLASS3 (_p, PCI_CLASS_SCC, PCI= _SUBCLASS_SERIAL, PCI_IF_16550) +#define IS_PCI_ISA_PDECODE(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI= _CLASS_BRIDGE_ISA_PDECODE, 0) + +typedef struct { + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + UINTN ConnectType; +} PLATFORM_CONSOLE_CONNECT_ENTRY; + +#define CONSOLE_OUT BIT0 +#define CONSOLE_IN BIT1 +#define STD_ERROR BIT2 +extern PLATFORM_CONSOLE_CONNECT_ENTRY gPlatformConsole[]; + +// +// Platform BDS Functions +// + +VOID +PlatformInitializeConsole ( + IN PLATFORM_CONSOLE_CONNECT_ENTRY *PlatformConsole + ); + +/** + Use SystemTable ConOut to stop video based Simple Text Out consoles from= going + to the video device. Put up LogoFile on every video device that is a con= sole. + + @param[in] LogoFile The file name of logo to display on the center of= the screen. + + @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and = logo displayed. + @retval EFI_UNSUPPORTED Logo not found. + +**/ +EFI_STATUS +EFIAPI +EnableBootLogo( + IN EFI_GUID *LogoFile +); + +#endif // _PLATFORM_SPECIFIC_BDS_PLATFORM_H_ diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerL= ib/PlatformBootManagerLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/P= latformBootManagerLib/PlatformBootManagerLib.inf new file mode 100644 index 0000000000..cdb6e242e8 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/Plat= formBootManagerLib.inf @@ -0,0 +1,72 @@ +## @file +# Platform BDS customizations library. +# +# Copyright (c) 2007 - 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D PlatformBootManagerLib + FILE_GUID =3D 8AE4756F-0C71-4C06-84D4-4C71F204D514 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D PlatformBootManagerLib|DXE_DRIVER + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC +# + +[Sources] + BdsPlatform.c + PlatformData.c + BdsPlatform.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SimicsOpenBoardPkg/OpenBoardPkg.dec + OvmfPkg/OvmfPkg.dec + SimicsIch10Pkg/Ich10Pkg.dec + +[LibraryClasses] + BaseLib + MemoryAllocationLib + UefiBootServicesTableLib + BaseMemoryLib + DebugLib + PcdLib + UefiBootManagerLib + BootLogoLib + DevicePathLib + PciLib + NvVarsFileLib + DxeLoadLinuxLib + UefiLib + LogoLib + +[Pcd] + gBoardModuleTokenSpaceGuid.PcdEmuVariableEvent + gBoardModuleTokenSpaceGuid.PcdOvmfFlashVariablesEnable + gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut + gBoardModuleTokenSpaceGuid.PcdShellFile + gBoardModuleTokenSpaceGuid.PcdLogoFile + +[Pcd.IA32, Pcd.X64] + gEfiMdePkgTokenSpaceGuid.PcdFSBClock + +[Protocols] + gEfiDecompressProtocolGuid + gEfiPciRootBridgeIoProtocolGuid + gEfiS3SaveStateProtocolGuid # PROTOCOL SOMETIMES_CONSU= MED + gEfiDxeSmmReadyToLockProtocolGuid # PROTOCOL SOMETIMES_PRODU= CED + gEfiLoadedImageProtocolGuid # PROTOCOL SOMETIMES_PRODU= CED + gEfiFirmwareVolume2ProtocolGuid # PROTOCOL SOMETIMES_CONSU= MED + +[Guids] + gEfiEndOfDxeEventGroupGuid diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLi= b/SerializeVariablesLib.h b/Platform/Intel/SimicsOpenBoardPkg/Library/Seria= lizeVariablesLib/SerializeVariablesLib.h new file mode 100644 index 0000000000..9b4c2a629a --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/Seria= lizeVariablesLib.h @@ -0,0 +1,33 @@ +/** @file + Serialize Variables Library implementation + + Copyright (c) 2009 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __SERIALIZE_VARIABLES_LIB_INSTANCE__ +#define __SERIALIZE_VARIABLES_LIB_INSTANCE__ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#define SV_FROM_HANDLE(a) CR (a, SV_INSTANCE, Signature, SV_SIGNATUR= E) +#define SV_SIGNATURE SIGNATURE_32 ('S', 'V', 'A', 'R') + +typedef struct { + UINT32 Signature; + VOID *BufferPtr; + UINTN BufferSize; + UINTN DataSize; +} SV_INSTANCE; + +#endif + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLi= b/SerializeVariablesLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/Ser= ializeVariablesLib/SerializeVariablesLib.inf new file mode 100644 index 0000000000..08c561f586 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/Seria= lizeVariablesLib.inf @@ -0,0 +1,36 @@ +## @file +# Serialize Variables Library implementation +# +# This library serializes and deserializes UEFI variables +# +# Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D DxeSerializeVariablesLib + FILE_GUID =3D 266A1434-6B22-441F-A8D2-D54AA8FDF95C + MODULE_TYPE =3D UEFI_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D SerializeVariablesLib|DXE_DRIVER DXE_= RUNTIME_DRIVER UEFI_DRIVER + +[Sources] + SerializeVariablesLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ShellPkg/ShellPkg.dec + SimicsOpenBoardPkg/OpenBoardPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + MemoryAllocationLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicy= InitLib/SiliconPolicyInitLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Policy= /Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf new file mode 100644 index 0000000000..6be3b301ad --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib= /SiliconPolicyInitLib.inf @@ -0,0 +1,38 @@ +## @file +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D SiliconPolicyInitLib + FILE_GUID =3D B494DF39-A5F8-48A1-B2D0-EF523AD91C55 + MODULE_TYPE =3D PEIM + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D SiliconPolicyInitLib + +[Sources] + SiliconPolicyInitLib.c + +##########################################################################= ###### +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +##########################################################################= ###### +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseMemoryLib + BaseLib + DebugLib + DebugPrintErrorLevelLib + HobLib + IoLib + MemoryAllocationLib + PeiServicesLib + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicy= UpdateLib/SiliconPolicyUpdateLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Po= licy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.inf new file mode 100644 index 0000000000..4fde3c75a6 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateL= ib/SiliconPolicyUpdateLib.inf @@ -0,0 +1,35 @@ +## @file +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D SiliconPolicyUpdateLib + FILE_GUID =3D 6EA9585C-3C15-47da-9FFC-25E9E4EA4D0C + MODULE_TYPE =3D PEIM + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D SiliconPolicyUpdateLib + +[Sources] + SiliconPolicyUpdateLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + HobLib + IoLib + PcdLib + +[Pcd] + +[FixedPcd] + +[Ppis] + +[Guids] diff --git a/Platform/Intel/SimicsOpenBoardPkg/SecCore/Ia32/SecEntry.nasm b= /Platform/Intel/SimicsOpenBoardPkg/SecCore/Ia32/SecEntry.nasm new file mode 100644 index 0000000000..adb87de943 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SecCore/Ia32/SecEntry.nasm @@ -0,0 +1,45 @@ +; @file +; Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
+; +; SPDX-License-Identifier: BSD-2-Clause-Patent +; + +#include + + SECTION .text + +extern ASM_PFX(SecCoreStartupWithStack) + +; +; SecCore Entry Point +; +; Processor is in flat protected mode +; +; @param[in] EAX Initial value of the EAX register (BIST: Built-in Self= Test) +; @param[in] DI 'BP': boot-strap processor, or 'AP': application proce= ssor +; @param[in] EBP Pointer to the start of the Boot Firmware Volume +; +; @return None This routine does not return +; +global ASM_PFX(_ModuleEntryPoint) +ASM_PFX(_ModuleEntryPoint): + + ; + ; Load temporary RAM stack based on PCDs + ; + %define SEC_TOP_OF_STACK (FixedPcdGet32 (PcdSimicsSecPeiTempRamBase) += \ + FixedPcdGet32 (PcdSimicsSecPeiTempRamSize)) + mov eax, SEC_TOP_OF_STACK + mov esp, eax + nop + + ; + ; Setup parameters and call SecCoreStartupWithStack + ; [esp] return address for call + ; [esp+4] BootFirmwareVolumePtr + ; [esp+8] TopOfCurrentStack + ; + push eax + push ebp + call ASM_PFX(SecCoreStartupWithStack) + diff --git a/Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.inf b/Platfo= rm/Intel/SimicsOpenBoardPkg/SecCore/SecMain.inf new file mode 100644 index 0000000000..b1d319c5ea --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.inf @@ -0,0 +1,73 @@ +## @file +# SEC Driver +# +# Copyright (c) 2008 - 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D SecMain + FILE_GUID =3D e67f156f-54c5-47f3-a35d-07c045881e14 + MODULE_TYPE =3D SEC + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D SecMain + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC +# + +[Sources] + SecMain.c + +[Sources.IA32] + Ia32/SecEntry.nasm + +[Sources.X64] + X64/SecEntry.nasm + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + SimicsX58SktPkg/SktPkg.dec + SimicsOpenBoardPkg/OpenBoardPkg.dec + SimicsIch10Pkg/Ich10Pkg.dec + +[LibraryClasses] + BaseLib + DebugLib + BaseMemoryLib + PeiServicesLib + PcdLib + UefiCpuLib + DebugAgentLib + IoLib + PeCoffLib + PeCoffGetEntryPointLib + PeCoffExtraActionLib + ExtractGuidedSectionLib + LocalApicLib + PciCf8Lib + +[Ppis] + gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED + +[Pcd] + gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvBase + gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvSize + gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvBase + gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvSize + gBoardModuleTokenSpaceGuid.PcdSimicsSecPageTablesBase + gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamBase + gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamSize + gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress + gBoardModuleTokenSpaceGuid.PcdGuidedExtractHandlerTableSize + gBoardModuleTokenSpaceGuid.PcdSimicsDecompressionScratchEnd + +[FeaturePcd] + gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire diff --git a/Platform/Intel/SimicsOpenBoardPkg/SecCore/X64/SecEntry.nasm b/= Platform/Intel/SimicsOpenBoardPkg/SecCore/X64/SecEntry.nasm new file mode 100644 index 0000000000..2e6d8f618c --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SecCore/X64/SecEntry.nasm @@ -0,0 +1,45 @@ +; @file +; Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
+; +; SPDX-License-Identifier: BSD-2-Clause-Patent +; + +#include + +DEFAULT REL +SECTION .text + +extern ASM_PFX(SecCoreStartupWithStack) + +; +; SecCore Entry Point +; +; Processor is in flat protected mode +; +; @param[in] RAX Initial value of the EAX register (BIST: Built-in Self= Test) +; @param[in] DI 'BP': boot-strap processor, or 'AP': application proce= ssor +; @param[in] RBP Pointer to the start of the Boot Firmware Volume +; +; @return None This routine does not return +; +global ASM_PFX(_ModuleEntryPoint) +ASM_PFX(_ModuleEntryPoint): + + ; + ; Load temporary RAM stack based on PCDs + ; + %define SEC_TOP_OF_STACK (FixedPcdGet32 (PcdSimicsSecPeiTempRamBase) += \ + FixedPcdGet32 (PcdSimicsSecPeiTempRamSize)) + mov rsp, SEC_TOP_OF_STACK + nop + + ; + ; Setup parameters and call SecCoreStartupWithStack + ; rcx: BootFirmwareVolumePtr + ; rdx: TopOfCurrentStack + ; + mov rcx, rbp + mov rdx, rsp + sub rsp, 0x20 + call ASM_PFX(SecCoreStartupWithStack) + diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.h b/Platf= orm/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.h new file mode 100644 index 0000000000..623d8ad2a9 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.h @@ -0,0 +1,38 @@ +/** @file + This driver effectuates QSP platform configuration settings and exposes + them via HII. + + Copyright (C) 2014, Red Hat, Inc. + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _PLATFORM_H_ +#define _PLATFORM_H_ + +// +// Macro and type definitions that connect the form with the HII driver co= de. +// +#define FORMSTATEID_MAIN_FORM 1 +#define FORMID_MAIN_FORM 1 + +#define QUESTION_RES_CUR 1 +#define MAXSIZE_RES_CUR 16 + +#define LABEL_RES_NEXT 1 +#define QUESTION_RES_NEXT 2 + +#define QUESTION_SAVE_EXIT 3 +#define QUESTION_DISCARD_EXIT 4 + +// +// This structure describes the form state. Its fields relate strictly to = the +// visual widgets on the form. +// +typedef struct { + UINT16 CurrentPreferredResolution[MAXSIZE_RES_CUR]; + UINT32 NextPreferredResolution; +} MAIN_FORM_STATE; + +#endif // _PLATFORM_H_ diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.uni b/Pla= tform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.uni new file mode 100644 index 0000000000..3d9af148ec --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.uni @@ -0,0 +1,31 @@ +// *++ +// +// Copyright (C) 2014, Red Hat, Inc. +// Copyright (c) 2019, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// Module Name: +// +// Platform.uni +// +// Abstract: +// +// String definitions for PlatformForms.vfr +// +// --*/ + +/=3D# + +#langdef en-US "English" + +#string STR_FORMSET_TITLE #language en-US "QSP Platform Configurati= on" +#string STR_FORMSET_HELP #language en-US "Change various QSP platf= orm settings." +#string STR_MAIN_FORM_TITLE #language en-US "QSP Settings" +#string STR_RES_CUR #language en-US "Preferred Resolution at = Next Boot" +#string STR_RES_CUR_HELP #language en-US "The preferred resolution= of the Graphics Console at next boot. It might be unset, or even invalid (= hence ignored) wrt. the video RAM size." +#string STR_RES_NEXT #language en-US "Change Preferred Resolut= ion for Next Boot" +#string STR_RES_NEXT_HELP #language en-US "You can specify a new pr= eference for the Graphics Console here. The list is filtered against the vi= deo RAM size." +#string STR_SAVE_EXIT #language en-US "Commit Changes and Exit" +#string STR_DISCARD_EXIT #language en-US "Discard Changes and Exit" + diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.h b= /Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.h new file mode 100644 index 0000000000..c2063c427b --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.h @@ -0,0 +1,52 @@ +/** @file + Utility functions for serializing (persistently storing) and deserializi= ng + Simics's platform configuration. + + Copyright (C) 2014, Red Hat, Inc. + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _PLATFORM_CONFIG_H_ +#define _PLATFORM_CONFIG_H_ + +#include + +// +// This structure participates in driver configuration. It does not +// (necessarily) reflect the wire format in the persistent store. +// +#pragma pack(1) +typedef struct { + // + // preferred graphics console resolution when booting + // + UINT32 HorizontalResolution; + UINT32 VerticalResolution; +} PLATFORM_CONFIG; +#pragma pack() + +// +// Please see the API documentation near the function definitions. +// +EFI_STATUS +EFIAPI +PlatformConfigSave ( + IN PLATFORM_CONFIG *PlatformConfig + ); + +EFI_STATUS +EFIAPI +PlatformConfigLoad ( + OUT PLATFORM_CONFIG *PlatformConfig, + OUT UINT64 *OptionalElements + ); + +// +// Feature flags for OptionalElements. +// +#define PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION BIT0 +#define PLATFORM_CONFIG_F_DOWNGRADE BIT63 + +#endif // _PLATFORM_CONFIG_H_ diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformForms.vfr = b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformForms.vfr new file mode 100644 index 0000000000..a38521e8d3 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformForms.vfr @@ -0,0 +1,67 @@ +// *++ +// +// Copyright (C) 2014, Red Hat, Inc. +// Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// Module Name: +// +// PlatformForms.vfr +// +// Abstract: +// +// Form definitions for exposing some of OVMF's platform knobs via HII. +// +// --*/ + +#include +#include "Platform.h" + +formset + guid =3D SIMICS_BOARD_CONFIG_GUID, + title =3D STRING_TOKEN(STR_FORMSET_TITLE), + help =3D STRING_TOKEN(STR_FORMSET_HELP), + + varstore MAIN_FORM_STATE, + varid =3D FORMSTATEID_MAIN_FORM, + name =3D MainFormState, + guid =3D SIMICS_BOARD_CONFIG_GUID; + + form + formid =3D FORMID_MAIN_FORM, + title =3D STRING_TOKEN(STR_MAIN_FORM_TITLE); + + // + // Display the current preference in a read-only string field. + // + string + varid =3D MainFormState.CurrentPreferredResolution, + questionid =3D QUESTION_RES_CUR, + prompt =3D STRING_TOKEN(STR_RES_CUR), + help =3D STRING_TOKEN(STR_RES_CUR_HELP), + flags =3D READ_ONLY, + minsize =3D 0, + maxsize =3D MAXSIZE_RES_CUR, + endstring; + + // + // We'll dynamically generate a one-of-many selection at this label. + // + label LABEL_RES_NEXT; + + text + help =3D STRING_TOKEN(STR_SAVE_EXIT), + text =3D STRING_TOKEN(STR_SAVE_EXIT), + flags =3D INTERACTIVE, + key =3D QUESTION_SAVE_EXIT; + + text + help =3D STRING_TOKEN(STR_DISCARD_EXIT), + text =3D STRING_TOKEN(STR_DISCARD_EXIT), + flags =3D INTERACTIVE, + key =3D QUESTION_DISCARD_EXIT; + + endform; + +endformset; diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/SimicsDxe.inf b/Pl= atform/Intel/SimicsOpenBoardPkg/SimicsDxe/SimicsDxe.inf new file mode 100644 index 0000000000..eef187d2a7 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/SimicsDxe.inf @@ -0,0 +1,65 @@ +## @file +# This driver effectuates Simics X58 platform configuration settings and = exposes +# them via HII. +# +# Copyright (C) 2014, Red Hat, Inc. +# Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D SimicsDxe + FILE_GUID =3D 74B64DC1-B0B6-4853-A6BD-C6426059AB1E + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D PlatformInit + UNLOAD_IMAGE =3D PlatformUnload + +[Sources] + Platform.c + Platform.uni + PlatformConfig.c + PlatformForms.vfr + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SimicsOpenBoardPkg/OpenBoardPkg.dec + MinPlatformPkg/MinPlatformPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + DevicePathLib + HiiLib + MemoryAllocationLib + PrintLib + UefiBootServicesTableLib + UefiHiiServicesLib + UefiLib + UefiRuntimeServicesTableLib + UefiDriverEntryPoint + DxeServicesTableLib + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution + +[Protocols] + gEfiDevicePathProtocolGuid ## PRODUCES + gEfiGraphicsOutputProtocolGuid ## CONSUMES + gEfiHiiConfigAccessProtocolGuid ## PRODUCES + +[Guids] + gEfiIfrTianoGuid + gSimicsBoardConfigGuid + +[Depex] + gEfiHiiConfigRoutingProtocolGuid AND + gEfiHiiDatabaseProtocolGuid AND + gEfiVariableArchProtocolGuid AND + gEfiVariableWriteArchProtocolGuid diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.h b/Platform/= Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.h new file mode 100644 index 0000000000..07fa2e2d11 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.h @@ -0,0 +1,50 @@ +/** @file + PC/AT CMOS access routines + + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __CMOS_H__ +#define __CMOS_H__ + +/** + Reads 8-bits of CMOS data. + + Reads the 8-bits of CMOS data at the location specified by Index. + The 8-bit read value is returned. + + @param Index The CMOS location to read. + + @return The value read. + +**/ +UINT8 +EFIAPI +CmosRead8 ( + IN UINTN Index + ); + +/** + Writes 8-bits of CMOS data. + + Writes 8-bits of CMOS data to the location specified by Index + with the value specified by Value and returns Value. + + @param Index The CMOS location to write. + @param Value The value to write to CMOS. + + @return The value written to CMOS. + +**/ +UINT8 +EFIAPI +CmosWrite8 ( + IN UINTN Index, + IN UINT8 Value + ); + + +#endif + diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.h b/Platf= orm/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.h new file mode 100644 index 0000000000..102d21cd64 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.h @@ -0,0 +1,88 @@ +/** @file + Platform PEI module include file. + + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _PLATFORM_PEI_H_INCLUDED_ +#define _PLATFORM_PEI_H_INCLUDED_ + +VOID +AddIoMemoryBaseSizeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize + ); + +VOID +AddIoMemoryRangeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + EFI_PHYSICAL_ADDRESS MemoryLimit + ); + +VOID +AddMemoryBaseSizeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize + ); + +VOID +AddMemoryRangeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + EFI_PHYSICAL_ADDRESS MemoryLimit + ); + +VOID +AddUntestedMemoryBaseSizeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize + ); + +VOID +AddReservedMemoryBaseSizeHob ( + EFI_PHYSICAL_ADDRESS MemoryBase, + UINT64 MemorySize, + BOOLEAN Cacheable + ); + +VOID +AddressWidthInitialization ( + VOID + ); + +VOID +X58TsegMbytesInitialization ( + VOID + ); + +EFI_STATUS +PublishPeiMemory ( + VOID + ); + +UINT32 +GetSystemMemorySizeBelow4gb ( + VOID + ); + +VOID +InitializeRamRegions ( + VOID + ); + +VOID +InstallFeatureControlCallback ( + VOID + ); + +extern EFI_BOOT_MODE mBootMode; + +extern BOOLEAN mS3Supported; + +extern UINT8 mPhysMemAddressWidth; + +extern UINT32 mMaxCpuCount; + +extern UINT16 mHostBridgeDevId; +#endif // _PLATFORM_PEI_H_INCLUDED_ diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/SimicsPei.inf b/Pl= atform/Intel/SimicsOpenBoardPkg/SimicsPei/SimicsPei.inf new file mode 100644 index 0000000000..ccc7037d75 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/SimicsPei.inf @@ -0,0 +1,104 @@ +## @file +# Platform PEI driver +# +# This module provides platform specific function to detect boot mode. +# Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D SimicsPei + FILE_GUID =3D 05116218-f9f1-41f8-8d17-c2207006ffff + MODULE_TYPE =3D PEIM + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D InitializePlatform + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC +# + +[Sources] + Cmos.c + FeatureControl.c + MemDetect.c + Platform.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + SimicsOpenBoardPkg/OpenBoardPkg.dec + MinPlatformPkg/MinPlatformPkg.dec + SimicsX58SktPkg/SktPkg.dec + SimicsIch10Pkg/Ich10Pkg.dec + +[Guids] + gEfiMemoryTypeInformationGuid + gEfiSmmPeiSmramMemoryReserveGuid ## CONSUMES + +[LibraryClasses] + BaseLib + DebugLib + HobLib + IoLib + PciLib + PeiResourcePublicationLib + PeiServicesLib + PeiServicesTablePointerLib + PeimEntryPoint + MtrrLib + PcdLib + +[Pcd] + gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvBase + gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvSize + gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvBase + gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvSize + gBoardModuleTokenSpaceGuid.PcdSimicsLockBoxStorageBase + gBoardModuleTokenSpaceGuid.PcdSimicsLockBoxStorageSize + gBoardModuleTokenSpaceGuid.PcdSimicsSecPageTablesBase + gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamBase + gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamSize + gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress + gBoardModuleTokenSpaceGuid.PcdGuidedExtractHandlerTableSize + gBoardModuleTokenSpaceGuid.PcdSimicsDecompressionScratchEnd + gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId + gBoardModuleTokenSpaceGuid.PcdPciIoBase + gBoardModuleTokenSpaceGuid.PcdPciIoSize + gBoardModuleTokenSpaceGuid.PcdPciMmio32Base + gBoardModuleTokenSpaceGuid.PcdPciMmio32Size + gBoardModuleTokenSpaceGuid.PcdPciMmio64Base + gBoardModuleTokenSpaceGuid.PcdPciMmio64Size + gSimicsX58PkgTokenSpaceGuid.PcdX58TsegMbytes + gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire + gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode + gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable + gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress + gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber + gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds + gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdIoApicId + +[FixedPcd] + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress + + +[Ppis] + gEfiPeiMasterBootModePpiGuid + gEfiPeiMpServicesPpiGuid + +[Depex] + TRUE + diff --git a/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlat= formDxe.h b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatf= ormDxe.h new file mode 100644 index 0000000000..f9c641845c --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe= .h @@ -0,0 +1,38 @@ +/** @file + This driver installs SMBIOS information for QSP + + Copyright (c) 2011, Bei Guan + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _SMBIOS_PLATFORM_DXE_H_ +#define _SMBIOS_PLATFORM_DXE_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + Validates the SMBIOS entry point structure + + @param EntryPointStructure SMBIOS entry point structure + + @retval TRUE The entry point structure is valid + @retval FALSE The entry point structure is not valid + +**/ +BOOLEAN +IsEntryPointStructureValid ( + IN SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure + ); + +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlat= formDxe.inf b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPla= tformDxe.inf new file mode 100644 index 0000000000..1420a315cf --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe= .inf @@ -0,0 +1,51 @@ +## @file +# This driver installs SMBIOS information for QSP +# +# Copyright (c) 2011, Bei Guan +# Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D SmbiosPlatformDxe + FILE_GUID =3D 4b18323d-2d42-4afa-b9e5-91516a6fe505 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + + ENTRY_POINT =3D SmbiosTablePublishEntry + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC ARM AARCH64 +# + +[Sources] + SmbiosPlatformDxe.h + SmbiosPlatformDxe.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SimicsOpenBoardPkg/OpenBoardPkg.dec + AdvancedFeaturePkg/AdvancedFeaturePkg.dec + +[LibraryClasses] + UefiBootServicesTableLib + BaseMemoryLib + BaseLib + UefiDriverEntryPoint + DebugLib + HobLib + MemoryAllocationLib + IoLib + +[Protocols] + gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED + +[Depex] + gEfiSmbiosProtocolGuid + --=20 2.16.2.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 (#46946): https://edk2.groups.io/g/devel/message/46946 Mute This Topic: https://groups.io/mt/33159241/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Fri Apr 26 02:55:24 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+46945+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+46945+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1567719524; cv=none; d=zoho.com; s=zohoarc; b=XpiIEUfsIktaqPyG2tft/N9JmELxnZgdND/XIIZTtrxhEiFYtByv6GPxHtC5Z/Wb6DxfoWbp8v5YVIRDbcSyEGiBDmCivlHqvM40W2PogU2JkucF2sieNVZ9zCT3wPTtgj7IPtdRNPllrIHP68vqzIy3YggQo+MS+CPinw2HnXg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1567719524; h=Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To:ARC-Authentication-Results; bh=ksMswpRWcD+MNgNW7ImAefYQh9h/pDZh19RWnUB8PGU=; b=kIBPx+Q8ynuifn0APp7X8yo2jly/s+wctBxnBKBulmyRP9b5ZK+UDa1k5RhLrkCZ66ZjPIneGqb9ulvh0yMeIh5tl/kbhdmfU5hH6edF7tdvN7qVG7lKtFRkhOKQy0t7Y2RK32dybp8KajowtAiQRuZ5Zgt8gfa/sD7JnA339OY= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+46945+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1567719524104806.3187700471017; Thu, 5 Sep 2019 14:38:44 -0700 (PDT) Return-Path: X-Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by groups.io with SMTP; Thu, 05 Sep 2019 14:38:42 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Sep 2019 14:38:42 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,471,1559545200"; d="scan'208";a="267151623" X-Received: from ydwei-desk.amr.corp.intel.com ([10.24.15.168]) by orsmga001.jf.intel.com with ESMTP; 05 Sep 2019 14:38:41 -0700 From: "David Wei" To: devel@edk2.groups.io Cc: Hao Wu , Liming Gao , Ankit Sinha , Agyeman Prince , Kubacki Michael A , Nate DeSimone , Michael D Kinney Subject: [edk2-devel] [edk2-platforms PATCH v5 4/7] SimicsOpenBoardPkg: Add DXE driver for Legacy Sio Date: Thu, 5 Sep 2019 14:38:37 -0700 Message-Id: In-Reply-To: References: In-Reply-To: References: Precedence: Bulk List-Unsubscribe: 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,david.y.wei@intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1567719523; bh=NSaxMQJhbJYNlBEAjfHwSVHpouGsuEldVHFFZi+aT2A=; h=Cc:Date:From:Reply-To:Subject:To; b=l408UOOsNUTTBdWuirMO2Gbbm00nE/JTFO8qVEII2V1vicLu/yt/nlFss/kBZ66dXKC NEfyogLAAGhmklkeoWgiwfqqaZ3A/gxFyqUdZjpandPGykZIewQpIlwynq4cQqZvuumrf a/42u/F+pfyPhtRIHyz9O5mm7VWVsWRS73w= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add DXE driver for Legacy Sio support Cc: Hao Wu Cc: Liming Gao Cc: Ankit Sinha Cc: Agyeman Prince Cc: Kubacki Michael A Cc: Nate DeSimone Cc: Michael D Kinney Signed-off-by: David Wei --- .../LegacySioDxe/ComponentName.c | 173 ++++++ .../SimicsOpenBoardPkg/LegacySioDxe/SioChip.c | 272 ++++++++++ .../SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c | 600 +++++++++++++++++= ++++ .../SimicsOpenBoardPkg/LegacySioDxe/SioService.c | 249 +++++++++ .../LegacySioDxe/ComponentName.h | 87 +++ .../LegacySioDxe/LegacySioDxe.inf | 54 ++ .../SimicsOpenBoardPkg/LegacySioDxe/Register.h | 15 + .../SimicsOpenBoardPkg/LegacySioDxe/SioChip.h | 195 +++++++ .../SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h | 134 +++++ .../SimicsOpenBoardPkg/LegacySioDxe/SioService.h | 143 +++++ 10 files changed, 1922 insertions(+) create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/Componen= tName.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDrive= r.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioServi= ce.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/Componen= tName.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/LegacySi= oDxe.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/Register= .h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDrive= r.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioServi= ce.h diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.c= b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.c new file mode 100644 index 0000000000..4ba02f92c0 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.c @@ -0,0 +1,173 @@ +/** @file + Install Base and Size Info Ppi for Firmware Volume Recovery. + + Copyright (c) 2013 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "SioDriver.h" + +/// +/// Component Name Protocol instance +/// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL mSioComponentNa= me =3D { + SioComponentNameGetDriverName, + SioComponentNameGetControllerName, + "eng" +}; + +/// +/// Component Name 2 Protocol instance +/// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL mSioComponentNa= me2 =3D { + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) SioComponentNameGetDriverName, + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)SioComponentNameGetControllerNa= me, + "en" +}; + +/// +/// Table of driver names +/// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mSioDriverNameTable= [] =3D { + { + "eng;en", + L"Super I/O Driver" + }, + { + NULL, + NULL + } +}; + +/// +/// Table of Controller names +/// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mSioControllerNameT= able[] =3D { + { + "eng;en", + L"Super I/O Controller" + }, + { + NULL, + NULL + } +}; + +/** + Retrieves a Unicode string that is the user-readable name of the EFI Dri= ver. + + @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param Language A pointer to a three-character ISO 639-2 language ide= ntifier. + This is the language of the driver name that that the= caller + is requesting, and it must match one of the languages= specified + in SupportedLanguages. The number of languages suppo= rted by a + driver is up to the driver writer. + @param DriverName A pointer to the Unicode string to return. This Unic= ode string + is the name of the driver specified by This in the la= nguage + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specifie= d by This + and the language specified by Language was= returned + in DriverName. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER DriverName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not supp= ort the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +SioComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mSioDriverNameTable, + DriverName, + (BOOLEAN)(This =3D=3D &mSioComponentName) + ); +} + +/** + Retrieves a Unicode string that is the user readable name of the control= ler + that is being managed by an EFI Driver. + + @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL in= stance. + @param ControllerHandle The handle of a controller that the driver spec= ified by + This is managing. This handle specifies the co= ntroller + whose name is to be returned. + @param ChildHandle The handle of the child controller to retrieve = the name + of. This is an optional parameter that may be = NULL. It + will be NULL for device drivers. It will also = be NULL + for a bus drivers that wish to retrieve the nam= e of the + bus controller. It will not be NULL for a bus = driver + that wishes to retrieve the name of a child con= troller. + @param Language A pointer to a three character ISO 639-2 langua= ge + identifier. This is the language of the contro= ller name + that the caller is requesting, and it must matc= h one + of the languages specified in SupportedLanguage= s. The + number of languages supported by a driver is up= to the + driver writer. + @param ControllerName A pointer to the Unicode string to return. Thi= s Unicode + string is the name of the controller specified = by + ControllerHandle and ChildHandle in the languag= e specified + by Language, from the point of view of the driv= er specified + by This. + + @retval EFI_SUCCESS The Unicode string for the user-readable n= ame in the + language specified by Language for the dri= ver + specified by This was returned in DriverNa= me. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a va= lid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This is not curren= tly managing + the controller specified by ControllerHand= le and + ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not supp= ort the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +SioComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + EFI_STATUS Status; + + // + // Make sure this driver is currently managing ControllHandle + // + Status =3D EfiTestManagedDevice ( + ControllerHandle, + mSioDriver.DriverBindingHandle, + &gEfiPciIoProtocolGuid + ); + if (EFI_ERROR (Status)) { + return Status; + } + // + // ChildHandle must be NULL for a Device Driver + // + if (ChildHandle !=3D NULL) { + return EFI_UNSUPPORTED; + } + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mSioControllerNameTable, + ControllerName, + (BOOLEAN)(This =3D=3D &mSioComponentName) + ); +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.c b/Pla= tform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.c new file mode 100644 index 0000000000..b9a7b9cd24 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.c @@ -0,0 +1,272 @@ +/** @file + Super I/O specific implementation. + + Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "SioDriver.h" +#include + +LOCAL_IO_WRITE8 mIoWrite8 =3D IoWrite8; +// +// System configuration (setup) information +// +// SYSTEM_CONFIGURATION mSystemConfiguration; + +// +// COM 1 UART Controller +// +ACPI_SIO_RESOURCES_IO_IRQ mCom1Resources =3D { + { + { ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR }, + 0x3f8, + 8 + }, + { + { ACPI_IRQ_NOFLAG_DESCRIPTOR }, + BIT4 // IRQ4 + }, + { + ACPI_END_TAG_DESCRIPTOR, + 0 + } +}; + +// +// PS/2 Keyboard Controller +// +ACPI_SIO_RESOURCES_IO_IRQ mKeyboardResources =3D { + { + { ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR }, + 0x60, + 5 + }, + { + { ACPI_IRQ_NOFLAG_DESCRIPTOR }, + BIT1 + }, + { + ACPI_END_TAG_DESCRIPTOR, + 0 + } +}; + +// +// PS/2 Mouse Controller +// +ACPI_SIO_RESOURCES_IO_IRQ mMouseResources =3D { + { + { ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR }, + 0x60, + 5 + }, + { + { ACPI_IRQ_NOFLAG_DESCRIPTOR }, + BIT12 + }, + { + ACPI_END_TAG_DESCRIPTOR, + 0 + } +}; + +// +// Table of SIO Controllers +// +DEVICE_INFO mDeviceInfo[] =3D { + { + { + EISA_PNP_ID(0x501), + 0 + }, + 0, + RESOURCE_IO | RESOURCE_IRQ, + { (ACPI_SMALL_RESOURCE_HEADER *) &mCom1Resources }, + { (ACPI_SMALL_RESOURCE_HEADER *) &mCom1Resources } + }, // COM 1 UART Controller + { + { + EISA_PNP_ID(0x303), + 0 + }, + 0, + 0, // Cannot change resource + { (ACPI_SMALL_RESOURCE_HEADER *) &mKeyboardResources }, + { (ACPI_SMALL_RESOURCE_HEADER *) &mKeyboardResources } + }, // PS/2 Keyboard Controller + { + { + EISA_PNP_ID(0xF03), + 0 + }, + 0, + 0, // Cannot change resource + { (ACPI_SMALL_RESOURCE_HEADER *) &mMouseResources }, + { (ACPI_SMALL_RESOURCE_HEADER *) &mMouseResources } + } // PS/2 Mouse Controller +}; + + +/** + Return the supported devices. + + @param[out] Devices Pointer to pointer of EFI_SIO_ACPI_DEVICE_ID. + Caller is responsible to free the buffer. + @param[out] Count Pointer to UINTN holding the device count. +**/ +VOID +DeviceGetList ( + OUT EFI_SIO_ACPI_DEVICE_ID **Devices, + OUT UINTN *Count + ) +{ + EFI_SIO_ACPI_DEVICE_ID *LocalDevices; + UINTN LocalCount; + UINTN DeviceCount; + UINTN Index; + + // + // Allocate enough memory for simplicity + // + DeviceCount =3D sizeof (mDeviceInfo) / sizeof (mDeviceInfo[0]); + LocalDevices =3D AllocatePool (sizeof (EFI_SIO_ACPI_DEVICE_ID) * DeviceC= ount); + ASSERT (LocalDevices !=3D NULL); + if (LocalDevices =3D=3D NULL) { + return; + } + LocalCount =3D 0; + + for (Index =3D 0; Index < DeviceCount; Index++) { + CopyMem (&LocalDevices[LocalCount], &mDeviceInfo[Index].Device, sizeof= (EFI_SIO_ACPI_DEVICE_ID)); + LocalCount++; + } + + *Devices =3D LocalDevices; + *Count =3D LocalCount; +} + + +/** + Super I/O controller initialization. + + @retval EFI_SUCCESS The super I/O controller is found and init= ialized. + @retval EFI_UNSUPPORTED The super I/O controller is not found. +**/ +EFI_STATUS +SioInit ( + VOID + ) +{ + + return EFI_SUCCESS; +} + + +/** + Find the DEVICE_INFO for specified Device. + + @param[in] Device Pointer to the EFI_SIO_ACPI_DEVICE_ID. + + @retval DEVICE_INFO* Pointer to the DEVICE_INFO. +**/ +DEVICE_INFO * +DeviceSearch ( + IN EFI_SIO_ACPI_DEVICE_ID *Device + ) +{ + UINTN Index; + + for (Index =3D 0; Index < sizeof (mDeviceInfo) / sizeof (mDeviceInfo[0])= ; Index++) { + if (CompareMem (Device, &mDeviceInfo[Index].Device, sizeof (*Device)) = =3D=3D 0) { + return &mDeviceInfo[Index]; + } + } + + ASSERT (FALSE); + return NULL; +} + + +/** + Program the SIO chip to enable the specified device using the default re= source. + + @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID. +**/ +VOID +DeviceEnable ( + IN EFI_SIO_ACPI_DEVICE_ID *Device + ) +{ +} + + +/** + Get the ACPI resources for specified device. + + @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID. + @param[out] Resources Pointer to ACPI_RESOURCE_HEADER_PTR. + + @retval EFI_SUCCESS The resources are returned successfully. +**/ +EFI_STATUS +DeviceGetResources ( + IN EFI_SIO_ACPI_DEVICE_ID *Device, + OUT ACPI_RESOURCE_HEADER_PTR *Resources + ) +{ + DEVICE_INFO *DeviceInfo; + + DeviceInfo =3D DeviceSearch (Device); + + *Resources =3D DeviceInfo->Resources; + + return EFI_SUCCESS; +} + + +/** + Set the ACPI resources for specified device. + + The SIO chip is programmed to use the new resources and the + resources setting are saved. The function assumes the resources + are valid. + + @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID. + @param[in] Resources ACPI_RESOURCE_HEADER_PTR. + + @retval EFI_UNSUPPORTED +**/ +EFI_STATUS +DeviceSetResources ( + IN EFI_SIO_ACPI_DEVICE_ID *Device, + IN ACPI_RESOURCE_HEADER_PTR Resources + ) +{ + return EFI_UNSUPPORTED; +} + + +/** + Get the possible ACPI resources for specified device. + + @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID. + @param[out] Resources Pointer to ACPI_RESOURCE_HEADER_PTR. + + @retval EFI_SUCCESS The resources are returned successfully. +**/ +EFI_STATUS +DevicePossibleResources ( + IN EFI_SIO_ACPI_DEVICE_ID *Device, + OUT ACPI_RESOURCE_HEADER_PTR *Resources + ) +{ + DEVICE_INFO *DeviceInfo; + + DeviceInfo =3D DeviceSearch (Device); + + *Resources =3D DeviceInfo->PossibleResources; + + return EFI_SUCCESS; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c b/P= latform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c new file mode 100644 index 0000000000..408c6ff301 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c @@ -0,0 +1,600 @@ +/** @file + EFI Driver following Driver Binding Protocol. + + Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "SioDriver.h" + + +// +// This driver is for ACPI(PNP0A03,0)/PCI(0x1f,0) +// +// +// Sio Driver Global Variables +// +EFI_DRIVER_BINDING_PROTOCOL mSioDriver =3D { + SioDriverSupported, + SioDriverStart, + SioDriverStop, + 1, + NULL, + NULL +}; + +// +// The list of the created SIO_DEV +// +LIST_ENTRY mSioDevPool =3D INITIALIZE_LIST_HEAD_VARIABLE = (mSioDevPool); + +// +// Template structure to create SIO_DEV +// +SIO_DEV mSioDevTemplate =3D { + SIO_DEV_SIGNATURE, // Signature + NULL, // PciHandle + { + 0x00000000, // HID + 0x00000000 // UID + }, + NULL, // Handle + { // Sio Instance + SioRegisterAccess, + SioGetResources, + SioSetResources, + SioPossibleResources, + SioModify + }, + NULL, // DevicePath + { + NULL, // ForwardLink + NULL, // BackLink + } +}; + +// +// Template ACPI_HID_DEVICE_PATH structure to create device path +// +ACPI_HID_DEVICE_PATH mAcpiNodeTemplate =3D { + { + ACPI_DEVICE_PATH, // Type + ACPI_DP, // SubType + { + sizeof (ACPI_HID_DEVICE_PATH), // Length[0] + 0 // Length[1] + } + }, + 0x00000000, // HID + 0x00000000 // UID +}; + + +/** + The user Entry Point for module Lpc47m17x. The user code starts with thi= s function. + + @param[in] ImageHandle The firmware allocated handle for the EFI ima= ge. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry p= oint. +**/ +EFI_STATUS +EFIAPI +SioDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + if (EFI_ERROR (SioInit())) { + return EFI_UNSUPPORTED; + } else { + + // + // Install protocols + // + return EfiLibInstallDriverBindingComponentName2 ( + ImageHandle, + SystemTable, + &mSioDriver, + ImageHandle, + &mSioComponentName, + &mSioComponentName2 + ); + } +} + + +/** + Test to see if this driver supports Controller Handle. + + @param[in] This Protocol instance pointer. + @param[in] Controller Handle of device to test + @param[in] RemainingDevicePath Optional parameter use to pick a specifi= c child + device to start. + + @retval EFI_SUCCESS This driver supports this device + @retval EFI_ALREADY_STARTED This driver is already running on this d= evice + @retval other This driver does not support this device +**/ +EFI_STATUS +EFIAPI +SioDriverSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + ACPI_HID_DEVICE_PATH *AcpiNode; + PCI_TYPE00 Pci; + UINTN Index; + EFI_SIO_ACPI_DEVICE_ID *Devices; + UINTN Count; + UINTN SegmentNumber; + UINTN BusNumber; + UINTN DeviceNumber; + UINTN FunctionNumber; + + // + // If RemainingDevicePath is not NULL, it should verify that the first d= evice + // path node in RemainingDevicePath is an ACPI Device path node which is= a + // legal Device Path Node for this bus driver's children. + // + if (RemainingDevicePath !=3D NULL) { + if (!IsDevicePathEnd (RemainingDevicePath)) { + if ((RemainingDevicePath->Type !=3D ACPI_DEVICE_PATH) || + (((RemainingDevicePath->SubType !=3D ACPI_DP) || (DevicePathNode= Length (RemainingDevicePath) !=3D sizeof (ACPI_HID_DEVICE_PATH))) && + ((RemainingDevicePath->SubType !=3D ACPI_EXTENDED_DP) || (Device= PathNodeLength (RemainingDevicePath) !=3D sizeof (ACPI_EXTENDED_HID_DEVICE_= PATH)))) + ) { + return EFI_UNSUPPORTED; + } + + DeviceGetList (&Devices, &Count); + if (Devices =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + AcpiNode =3D (ACPI_HID_DEVICE_PATH *) RemainingDevicePath; + for (Index =3D 0; Index < Count; Index++) { + if ((AcpiNode->HID =3D=3D Devices[Index].HID) && + (AcpiNode->UID =3D=3D Devices[Index].UID)) { + break; + } + } + FreePool (Devices); + if (Index =3D=3D Count) { + return EFI_UNSUPPORTED; + } + } + } + + // + // See if the parent device path can be opened BY_DRIVER + // + Status =3D gBS->OpenProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + (VOID **) &ParentDevicePath, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status) && (Status !=3D EFI_ALREADY_STARTED)) { + return Status; + } + + gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + // + // Get PciIo protocol instance + // + Status =3D gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + + if (!EFI_ERROR (Status)) { + Status =3D PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint32, + 0, + sizeof (Pci) / sizeof (UINT32), + &Pci + ); + ASSERT_EFI_ERROR (Status); + + Status =3D EFI_UNSUPPORTED; + if ((Pci.Hdr.Command & (EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND_MEM= ORY_SPACE)) + =3D=3D (EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND= _MEMORY_SPACE) + ) { + if (Pci.Hdr.ClassCode[2] =3D=3D PCI_CLASS_BRIDGE) { + // + // See if this is a standard PCI to ISA Bridge from the Base Code = and Class Code + // + if (Pci.Hdr.ClassCode[1] =3D=3D PCI_CLASS_BRIDGE_ISA) { + Status =3D EFI_SUCCESS; + } + + // + // See if this is an Intel PCI to ISA Bridge in Positive Decode Mo= de + // + if ((Pci.Hdr.ClassCode[1] =3D=3D PCI_CLASS_BRIDGE_ISA_PDECODE) && + (Pci.Hdr.VendorId =3D=3D 0x8086)) { + // + // See if this is on Function #0 to avoid false positive on + // PCI_CLASS_BRIDGE_OTHER that has the same value as + // PCI_CLASS_BRIDGE_ISA_PDECODE + // + Status =3D PciIo->GetLocation ( + PciIo, + &SegmentNumber, + &BusNumber, + &DeviceNumber, + &FunctionNumber + ); + if (!EFI_ERROR (Status) && (FunctionNumber =3D=3D 0)) { + Status =3D EFI_SUCCESS; + } else { + Status =3D EFI_UNSUPPORTED; + } + } + } + } + + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + } + if (EFI_ERROR (Status) && (Status !=3D EFI_ALREADY_STARTED)) { + return Status; + } + + return EFI_SUCCESS; +} + + +/** + Destroy the SIO controller handle. + + @param[in] ChildHandle The SIO controller handle. + + @retval EFI_SUCCESS The SIO controller handle is destroyed succe= ssfully. +**/ +EFI_STATUS +SioDestroyDevice ( + IN EFI_HANDLE ChildHandle + ) +{ + EFI_STATUS Status; + SIO_DEV *SioDev; + EFI_SIO_PROTOCOL *Sio; + EFI_PCI_IO_PROTOCOL *PciIo; + + Status =3D gBS->HandleProtocol ( + ChildHandle, + &gEfiSioProtocolGuid, + (VOID **) &Sio + ); + ASSERT_EFI_ERROR (Status); + + SioDev =3D SIO_DEV_FROM_THIS (Sio); + + Status =3D gBS->CloseProtocol ( + SioDev->PciHandle, + &gEfiPciIoProtocolGuid, + mSioDriver.DriverBindingHandle, + ChildHandle + ); + ASSERT_EFI_ERROR (Status); + + Status =3D gBS->UninstallMultipleProtocolInterfaces ( + ChildHandle, + &gEfiDevicePathProtocolGuid, + SioDev->DevicePath, + &gEfiSioProtocolGuid, + &SioDev->Sio, + NULL + ); + if (EFI_ERROR (Status)) { + gBS->OpenProtocol ( + SioDev->PciHandle, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + mSioDriver.DriverBindingHandle, + ChildHandle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + return Status; + } + + RemoveEntryList (&SioDev->Link); + FreePool (SioDev->DevicePath); + FreePool (SioDev); + return EFI_SUCCESS; +} + + +/** + Create the SIO controller handle. + + @param[in] Controller The parent PCI controller handle. + @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID. + @param[in] ParentDevicePath The device path of the parent controller. + @param[out] PciIo The PciIo instance of the parent controller. +**/ +VOID +SioCreateDevice ( + IN EFI_HANDLE Controller, + IN EFI_SIO_ACPI_DEVICE_ID *Device, + IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, + OUT EFI_PCI_IO_PROTOCOL *PciIo + ) +{ + EFI_STATUS Status; + SIO_DEV *SioDev; + + DeviceEnable (Device); + SioDev =3D AllocateCopyPool (sizeof (SIO_DEV), &mSioDevTemplate); + ASSERT (SioDev !=3D NULL); + if (SioDev =3D=3D NULL) { + return; + } + InsertHeadList (&mSioDevPool, &SioDev->Link); + + SioDev->PciHandle =3D Controller; + + CopyMem (&SioDev->Device, Device, sizeof (*Device)); + + mAcpiNodeTemplate.HID =3D Device->HID; + mAcpiNodeTemplate.UID =3D Device->UID; + SioDev->DevicePath =3D AppendDevicePathNode (ParentDevicePath, (EFI_DEVI= CE_PATH_PROTOCOL *) &mAcpiNodeTemplate); + ASSERT (SioDev->DevicePath !=3D NULL); + + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &SioDev->Handle, + &gEfiSioProtocolGuid, &SioDev->Sio, + &gEfiDevicePathProtocolGuid, SioDev->DevicePath, + NULL + ); + ASSERT_EFI_ERROR (Status); + + Status =3D gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + mSioDriver.DriverBindingHandle, + SioDev->Handle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + ASSERT_EFI_ERROR (Status); +} + + +/** + Start this driver on ControllerHandle. + + @param[in] This Protocol instance pointer. + @param[in] Controller Handle of device to bind driver to + @param[in] RemainingDevicePath Optional parameter use to pick a specif= ic child + device to start. + + @retval EFI_SUCCESS This driver is added to ControllerHandle + @retval EFI_ALREADY_STARTED This driver is already running on Contr= ollerHandle + @retval other This driver does not support this device +**/ +EFI_STATUS +EFIAPI +SioDriverStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + EFI_SIO_ACPI_DEVICE_ID *Devices; + SIO_DEV *SioDev; + UINTN Count; + UINTN Index; + ACPI_HID_DEVICE_PATH *AcpiNode; + BOOLEAN *HasCreated; + BOOLEAN *RequestCreate; + LIST_ENTRY *Node; + + HasCreated =3D NULL; + RequestCreate =3D NULL; + // + // Get the ISA bridge's Device Path + // + Status =3D gBS->OpenProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + (VOID **) &ParentDevicePath, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status) && Status !=3D EFI_ALREADY_STARTED) { + return Status; + } + + // + // Get Pci IO + // + Status =3D gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + + if (EFI_ERROR (Status) && Status !=3D EFI_ALREADY_STARTED) { + gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + return Status; + } + + if ((RemainingDevicePath !=3D NULL) && IsDevicePathEnd (RemainingDeviceP= ath)) { + return EFI_SUCCESS; + } + + DeviceGetList (&Devices, &Count); + if (Devices =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto Exit_Start; + } + HasCreated =3D AllocatePool (sizeof (BOOLEAN) * Count); + ASSERT (HasCreated !=3D NULL); + if (HasCreated =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto Exit_Start; + } + RequestCreate =3D AllocatePool (sizeof (BOOLEAN) * Count); + ASSERT (RequestCreate !=3D NULL); + if (RequestCreate =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto Exit_Start; + } + + // + // Assume no children has been created. + // Assume the SIO interface hasn't been initialized. + // + ZeroMem (HasCreated, sizeof (BOOLEAN) * Count); + + if (Status =3D=3D EFI_ALREADY_STARTED) { + for (Node =3D GetFirstNode (&mSioDevPool); + !IsNull (&mSioDevPool, Node); + Node =3D GetNextNode (&mSioDevPool, Node) + ) { + SioDev =3D CR (Node, SIO_DEV, Link, SIO_DEV_SIGNATURE); + Status =3D gBS->HandleProtocol ( + SioDev->PciHandle, + &gEfiDevicePathProtocolGuid, + (VOID **) &DevicePath + ); + ASSERT_EFI_ERROR (Status); + + // + // See if they are under the same PCI to ISA Bridge + // + if (CompareMem (DevicePath, ParentDevicePath, GetDevicePathSize (Dev= icePath)) =3D=3D 0) { + for (Index =3D 0; Index < Count; Index++) { + if (CompareMem (&SioDev->Device, &Devices[Index], sizeof (EFI_SI= O_ACPI_DEVICE_ID)) =3D=3D 0) { + HasCreated[Index] =3D TRUE; + break; + } + } + } + } + } + + AcpiNode =3D (ACPI_HID_DEVICE_PATH *) RemainingDevicePath; + for (Index =3D 0; Index < Count; Index++) { + if ((AcpiNode =3D=3D NULL) || + ((AcpiNode->HID =3D=3D Devices[Index].HID) && (AcpiNode->UID =3D= =3D Devices[Index].UID)) + ) { + RequestCreate[Index] =3D TRUE; + } else { + RequestCreate[Index] =3D FALSE; + } + } + + for (Index =3D 0; Index < Count; Index++) { + if (RequestCreate[Index] && !HasCreated[Index]) { + SioCreateDevice (Controller, &Devices[Index], ParentDevicePath, PciI= o); + } + } +Exit_Start: + if (Devices !=3D NULL) { + FreePool (Devices); + } + if (HasCreated !=3D NULL) { + FreePool (HasCreated); + } + if (RequestCreate !=3D NULL) { + FreePool (RequestCreate); + } + + return Status; +} + + +/** + Stop this driver on ControllerHandle. + + @param[in] This Protocol instance pointer. + @param[in] Controller Handle of device to stop driver on + @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If= number of + children is zero stop the entire bus drive= r. + @param[in] ChildHandleBuffer List of Child Handles to Stop. + + @retval EFI_SUCCESS This driver is removed ControllerHandle + @retval other This driver was not removed from this devi= ce +**/ +EFI_STATUS +EFIAPI +SioDriverStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +{ + EFI_STATUS Status; + UINTN Index; + BOOLEAN AllChildrenStopped; + + if (NumberOfChildren =3D=3D 0) { + gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + return EFI_SUCCESS; + } + + AllChildrenStopped =3D TRUE; + for (Index =3D 0; Index < NumberOfChildren; Index++) { + Status =3D SioDestroyDevice (ChildHandleBuffer[Index]); + if (EFI_ERROR (Status)) { + AllChildrenStopped =3D FALSE; + } + } + + if (AllChildrenStopped) { + return EFI_SUCCESS; + } else { + return EFI_DEVICE_ERROR; + } +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.c b/= Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.c new file mode 100644 index 0000000000..379002b833 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.c @@ -0,0 +1,249 @@ +/** @file + Super I/O Interface implementation. + + Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "SioDriver.h" + + +/** + Provides an interface to get a list of the current resources consumed by= the device in the ACPI + Resource Descriptor format. + + GetResources() returns a list of resources currently consumed by the dev= ice. The + ResourceList is a pointer to the buffer containing resource descriptors = for the device. The + descriptors are in the format of Small or Large ACPI resource descriptor= as defined by ACPI + specification (2.0 & 3.0). The buffer of resource descriptors is termina= ted with the 'End tag' + resource descriptor. + + @param[in] This Indicates a pointer to the calling con= text. + @param[out] ResourceList A pointer to an ACPI resource descript= or list that defines the current resources + used by the device. Type ACPI_RESOURCE= _HEADER_PTR is defined in the "Related + Definitions" below. + + @retval EFI_SUCCESS The operation completed successfully + @retval EFI_INVALID_PARAMETER ResourceList is NULL +**/ +EFI_STATUS +EFIAPI +SioGetResources ( + IN CONST EFI_SIO_PROTOCOL *This, + OUT ACPI_RESOURCE_HEADER_PTR *ResourceList + ) +{ + SIO_DEV *SioDev; + + if (ResourceList =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + SioDev =3D SIO_DEV_FROM_THIS (This); + + return DeviceGetResources (&SioDev->Device, ResourceList); +} + + +/** + Provides a collection of resource descriptor lists. Each resource descri= ptor list in the collection + defines a combination of resources that can potentially be used by the d= evice. + + @param[in] This Indicates a pointer to the calling= context. + @param[out] ResourceCollection Collection of the resource descrip= tor lists. + + @retval EFI_SUCCESS The operation completed successful= ly + @retval EFI_INVALID_PARAMETER ResourceCollection is NULL +**/ +EFI_STATUS +EFIAPI +SioPossibleResources ( + IN CONST EFI_SIO_PROTOCOL *This, + OUT ACPI_RESOURCE_HEADER_PTR *ResourceCollection + ) +{ + SIO_DEV *SioDev; + + if (ResourceCollection =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + SioDev =3D SIO_DEV_FROM_THIS (This); + + return DevicePossibleResources (&SioDev->Device, ResourceCollection); +} + + +/** + Sets the resources for the device. + + @param[in] This Indicates a pointer to the calling con= text. + @param[in] ResourceList Pointer to the ACPI resource descripto= r list. Type ACPI_RESOURCE_HEADER_PTR + is defined in the "Related Definitions= " section of + EFI_SIO_PROTOCOL.GetResources(). + + @retval EFI_SUCCESS The operation completed successfully + @retval EFI_INVALID_PARAMETER ResourceList is invalid + @retval EFI_ACCESS_DENIED Some of the resources in ResourceList = are in use +**/ +EFI_STATUS +EFIAPI +SioSetResources ( + IN CONST EFI_SIO_PROTOCOL *This, + IN ACPI_RESOURCE_HEADER_PTR ResourceList + ) +{ + SIO_DEV *SioDev; + ACPI_RESOURCE_HEADER_PTR ResourcePtr; + ACPI_RESOURCE_HEADER_PTR ResourceCollection; + ACPI_RESOURCE_HEADER_PTR ResourcePtr2; + BOOLEAN Found; + + ResourcePtr =3D ResourceList; + SioDev =3D SIO_DEV_FROM_THIS (This); + + // + // Check whether the resource is in the possible resource collection + // + DevicePossibleResources (&SioDev->Device, &ResourceCollection); + + while (ResourcePtr.SmallHeader->Byte !=3D ACPI_END_TAG_DESCRIPTOR) { + + Found =3D FALSE; + ResourcePtr2 =3D ResourceCollection; + while (ResourcePtr2.SmallHeader->Byte !=3D ACPI_END_TAG_DESCRIPTOR) { + if (ResourcePtr2.SmallHeader->Bits.Type =3D=3D 0) { + // + // Small Header + // + if (CompareMem ( + ResourcePtr2.SmallHeader, + ResourcePtr.SmallHeader, + ResourcePtr2.SmallHeader->Bits.Length + sizeof (*ResourcePtr= 2.SmallHeader) + ) =3D=3D 0) { + Found =3D TRUE; + break; + } + + ResourcePtr2.SmallHeader =3D (ACPI_SMALL_RESOURCE_HEADER *) ((UINT= 8 *) ResourcePtr2.SmallHeader + + ResourcePtr2.SmallHeader->Bits.Length + + sizeof (*ResourcePtr2.SmallHeader)); + + } else { + // + // Large Header + // + if (CompareMem ( + ResourcePtr2.LargeHeader, + ResourcePtr.LargeHeader, + ResourcePtr2.LargeHeader->Length + sizeof (*ResourcePtr2.Lar= geHeader) + ) =3D=3D 0) { + Found =3D TRUE; + break; + } + + ResourcePtr2.LargeHeader =3D (ACPI_LARGE_RESOURCE_HEADER *) ((UINT= 8 *) ResourcePtr2.LargeHeader + + ResourcePtr2.LargeHeader->Length + + sizeof (*ResourcePtr2.LargeHeader)); + } + } + + if (!Found) { + return EFI_ACCESS_DENIED; + } + + if (ResourcePtr.SmallHeader->Bits.Type =3D=3D 0) { + ResourcePtr.SmallHeader =3D (ACPI_SMALL_RESOURCE_HEADER *) ((UINT8 *= ) ResourcePtr.SmallHeader + + ResourcePtr.SmallHeader->Bits.Length + + sizeof (*ResourcePtr.SmallHeader)); + } else { + ResourcePtr.LargeHeader =3D (ACPI_LARGE_RESOURCE_HEADER *) ((UINT8 *= ) ResourcePtr.LargeHeader + + ResourcePtr.LargeHeader->Length + + sizeof (*ResourcePtr.LargeHeader)); + } + } + + // + // ResourceList can be set + // + return DeviceSetResources (&SioDev->Device, ResourceList); +} + + +/** + Provides a low level access to the registers for the Super I/O. + + @param[in] This Indicates a pointer to the calli= ng context. + @param[in] Write Specifies the type of the regist= er operation. If this parameter is TRUE, + Value is interpreted as an input= parameter and the operation is a register write. + If this parameter is FALSE, Valu= e is interpreted as an output parameter and the + operation is a register read. + @param[in] ExitCfgMode Exit Configuration Mode Indicato= r. If this parameter is set to TRUE, the + Super I/O driver will turn off c= onfiguration mode of the Super I/O prior to returning + from this function. If this para= meter is set to FALSE, the Super I/O driver will + leave Super I/O in the configura= tion mode. + The Super I/O driver must track = the current state of the Super I/O and enable the + configuration mode of Super I/O = if necessary prior to register access. + @param[in] Register Register number. + @param[in, out] Value If Write is TRUE, Value is a poi= nter to the buffer containing the byte of data to be + written to the Super I/O registe= r. If Write is FALSE, Value is a pointer to the + destination buffer for the byte = of data to be read from the Super I/O register. + + @retval EFI_SUCCESS The operation completed successf= ully + @retval EFI_INVALID_PARAMETER The Value is NULL + @retval EFI_INVALID_PARAMETER Invalid Register number +**/ +EFI_STATUS +EFIAPI +SioRegisterAccess ( + IN CONST EFI_SIO_PROTOCOL *This, + IN BOOLEAN Write, + IN BOOLEAN ExitCfgMode, + IN UINT8 Register, + IN OUT UINT8 *Value + ) +{ + if (Value =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + + +/** + Provides an interface for a table based programming of the Super I/O reg= isters. + + The Modify() function provides an interface for table based programming = of the Super I/O + registers. This function can be used to perform programming of multiple = Super I/O registers with a + single function call. For each table entry, the Register is read, its co= ntent is bitwise ANDed with + AndMask, and then ORed with OrMask before being written back to the Regi= ster. The Super + I/O driver must track the current state of the Super I/O and enable the = configuration mode of Super I/ + O if necessary prior to table processing. Once the table is processed, t= he Super I/O device has to be + returned to the original state. + + @param[in] This Indicates a pointer to the calling cont= ext. + @param[in] Command A pointer to an array of NumberOfComman= ds EFI_SIO_REGISTER_MODIFY + structures. Each structure specifies a = single Super I/O register modify operation. + Type EFI_SIO_REGISTER_MODIFY is defined= in the "Related Definitions" below. + @param[in] NumberOfCommands Number of elements in the Command array. + + @retval EFI_SUCCESS The operation completed successfully + @retval EFI_INVALID_PARAMETER Command is NULL +**/ +EFI_STATUS +EFIAPI +SioModify ( + IN CONST EFI_SIO_PROTOCOL *This, + IN CONST EFI_SIO_REGISTER_MODIFY *Command, + IN UINTN NumberOfCommands + ) +{ + + if (Command =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.h= b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.h new file mode 100644 index 0000000000..5368f94bcd --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.h @@ -0,0 +1,87 @@ +/** @file + Install Base and Size Info Ppi for Firmware Volume Recovery. + + Copyright (c) 2013 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +/** + Retrieves a Unicode string that is the user-readable name of the EFI Dri= ver. + + @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param Language A pointer to a three-character ISO 639-2 language ide= ntifier. + This is the language of the driver name that that the= caller + is requesting, and it must match one of the languages= specified + in SupportedLanguages. The number of languages suppo= rted by a + driver is up to the driver writer. + @param DriverName A pointer to the Unicode string to return. This Unic= ode string + is the name of the driver specified by This in the la= nguage + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specifie= d by This + and the language specified by Language was= returned + in DriverName. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER DriverName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not supp= ort the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +SioComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + +/** + Retrieves a Unicode string that is the user readable name of the control= ler + that is being managed by an EFI Driver. + + @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL in= stance. + @param ControllerHandle The handle of a controller that the driver spec= ified by + This is managing. This handle specifies the co= ntroller + whose name is to be returned. + @param ChildHandle The handle of the child controller to retrieve = the name + of. This is an optional parameter that may be = NULL. It + will be NULL for device drivers. It will also = be NULL + for a bus drivers that wish to retrieve the nam= e of the + bus controller. It will not be NULL for a bus = driver + that wishes to retrieve the name of a child con= troller. + @param Language A pointer to a three character ISO 639-2 langua= ge + identifier. This is the language of the contro= ller name + that the caller is requesting, and it must matc= h one + of the languages specified in SupportedLanguage= s. The + number of languages supported by a driver is up= to the + driver writer. + @param ControllerName A pointer to the Unicode string to return. Thi= s Unicode + string is the name of the controller specified = by + ControllerHandle and ChildHandle in the languag= e specified + by Language, from the point of view of the driv= er specified + by This. + + @retval EFI_SUCCESS The Unicode string for the user-readable n= ame in the + language specified by Language for the dri= ver + specified by This was returned in DriverNa= me. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a va= lid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This is not curren= tly managing + the controller specified by ControllerHand= le and + ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not supp= ort the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +SioComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/LegacySioDxe.in= f b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/LegacySioDxe.inf new file mode 100644 index 0000000000..275f36ca47 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/LegacySioDxe.inf @@ -0,0 +1,54 @@ +## @file +# Module information that produces the +# EFI_SIO_PROTOCOL. +# +# Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010017 + BASE_NAME =3D HitachiH8s2113Dxe + FILE_GUID =3D 7807E404-8281-4FF1-8457-0B54BABE263F + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D UEFI_DRIVER + ENTRY_POINT =3D SioDriverEntryPoint +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC +# + +[LibraryClasses] + BaseLib + UefiLib + DebugLib + MemoryAllocationLib + PcdLib + DevicePathLib + IoLib + UefiDriverEntryPoint + UefiBootServicesTableLib + S3BootScriptLib + S3IoLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[Sources] + SioChip.c + SioChip.h + SioService.c + SioService.h + SioDriver.c + SioDriver.h + ComponentName.c + +[Protocols] + gEfiPciIoProtocolGuid ## CONSUMES + gEfiDevicePathProtocolGuid ## PRODUCES + gEfiSioProtocolGuid ## PRODUCES + diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/Register.h b/Pl= atform/Intel/SimicsOpenBoardPkg/LegacySioDxe/Register.h new file mode 100644 index 0000000000..f61f713cf2 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/Register.h @@ -0,0 +1,15 @@ +/** @file + Super I/O register definitions + + Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _REGISTER_H_ +#define _REGISTER_H_ + +#define EC_COMMAND_PORT 0x66 +#define EC_DATA_PORT 0x62 + +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.h b/Pla= tform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.h new file mode 100644 index 0000000000..48e28c44b0 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.h @@ -0,0 +1,195 @@ +/** @file + Super I/O specific header. + + Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _SIO_H_ +#define _SIO_H_ + + +#include "Register.h" + +typedef +UINT8 +(EFIAPI *LOCAL_IO_WRITE8) ( + IN UINTN Port, + IN UINT8 Value + ); + +#define RESOURCE_IO BIT0 +#define RESOURCE_IRQ BIT1 +#define RESOURCE_DMA BIT2 +#define RESOURCE_MEM BIT3 + +#pragma pack(1) + +typedef struct { + EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR Io; + EFI_ACPI_IRQ_NOFLAG_DESCRIPTOR Irq; + EFI_ACPI_END_TAG_DESCRIPTOR End; +} ACPI_SIO_RESOURCES_IO_IRQ; +#pragma pack() + +typedef struct { + UINT32 HID; + UINT32 UID; +} EFI_SIO_ACPI_DEVICE_ID; + +typedef struct { + EFI_SIO_ACPI_DEVICE_ID Device; + UINT8 DeviceId; + UINT8 ResourceMask; + ACPI_RESOURCE_HEADER_PTR Resources; + ACPI_RESOURCE_HEADER_PTR PossibleResources; +} DEVICE_INFO; + + +/** + Initialize the SIO chip for S3. +**/ +VOID +SioInitForS3 ( + VOID + ); + + +/** + Return the supported devices. + + @param[out] Devices Pointer to pointer of EFI_SIO_ACPI_DEVICE_ID. + Caller is responsible to free the buffer. + @param[out] Count Pointer to UINTN holding the device count. +**/ +VOID +DeviceGetList ( + OUT EFI_SIO_ACPI_DEVICE_ID **Devices, + OUT UINTN *Count + ); + + +/** + Program the SIO chip to enable the specified device using the default re= source. + + @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID. +**/ +VOID +DeviceEnable ( + IN EFI_SIO_ACPI_DEVICE_ID *Device + ); + + +/** + Get the possible ACPI resources for specified device. + + @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID. + @param[out] Resources Pointer to ACPI_RESOURCE_HEADER_PTR. + + @retval EFI_SUCCESS The resources are returned successfully. +**/ +EFI_STATUS +DevicePossibleResources ( + IN EFI_SIO_ACPI_DEVICE_ID *Device, + OUT ACPI_RESOURCE_HEADER_PTR *Resources + ); + + +/** + Set the ACPI resources for specified device. + + The SIO chip is programmed to use the new resources and the + resources setting are saved. The function assumes the resources + are valid. + + @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID. + @param[in] Resources ACPI_RESOURCE_HEADER_PTR. + + @retval EFI_SUCCESS The resources are set successfully. +**/ +EFI_STATUS +DeviceSetResources ( + IN EFI_SIO_ACPI_DEVICE_ID *Device, + IN ACPI_RESOURCE_HEADER_PTR Resources + ); + + +/** + Get the ACPI resources for specified device. + + @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID. + @param[out] Resources Pointer to ACPI_RESOURCE_HEADER_PTR. + + @retval EFI_SUCCESS The resources are returned successfully. +**/ +EFI_STATUS +DeviceGetResources ( + IN EFI_SIO_ACPI_DEVICE_ID *Device, + OUT ACPI_RESOURCE_HEADER_PTR *Resources + ); + + +/** + Program the SIO chip to enter the configure mode. +**/ +VOID +EnterConfigMode ( + VOID + ); + + +/** + Program the SIO chip to exit the configure mode. +**/ +VOID +ExitConfigMode ( + VOID + ); + + +/** + Perform a 8-bit I/O write to SIO register. + + @param[in] Index The register index. + @param[in] Data The value to write to register. +**/ +VOID +WriteRegister ( + IN UINT8 Index, + IN UINT8 Data + ); + + +/** + Perform a 8-bit I/O read from SIO register. + + @param[in] Index The register index. + + @retval Value The value written to the register. +**/ +UINT8 +ReadRegister ( + IN UINT8 Index + ); + +// +// Prototypes for the sio internal function +// +// +// Internal function +// + + +/** + Find Super I/O controller. + + @retval EFI_SUCCESS Super I/O controller exists. + @retval EFI_UNSUPPORTED Super I/O controller does not exist. +**/ +EFI_STATUS +SioInit ( + VOID + ); + +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h b/P= latform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h new file mode 100644 index 0000000000..2e75871f7f --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h @@ -0,0 +1,134 @@ +/** @file + Header file for Driver Binding Protocol. + + Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _SIO_DRIVER_H_ +#define _SIO_DRIVER_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// Driver Consumed Protocol Prototypes +// +#include +#include +#include + +// +// Driver Produced Protocol Prototypes +// +#include + + +#include "SioChip.h" +#include "SioService.h" +#include "ComponentName.h" + +// +// Global Variables definitions +// +extern EFI_DRIVER_BINDING_PROTOCOL mSioDriver; +extern EFI_COMPONENT_NAME_PROTOCOL mSioComponentName; +extern EFI_COMPONENT_NAME2_PROTOCOL mSioComponentName2; + +// +// SIO device private data structure +// +#define SIO_DEV_SIGNATURE SIGNATURE_32 ('_', 'S', 'I', 'O') + +typedef struct _SIO_DEV { + UINT32 Signature; + EFI_HANDLE PciHandle; + EFI_SIO_ACPI_DEVICE_ID Device; + EFI_HANDLE Handle; + EFI_SIO_PROTOCOL Sio; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + LIST_ENTRY Link; +} SIO_DEV; + +#define SIO_DEV_FROM_THIS(a) CR (a, SIO_DEV, Sio, SIO_DEV_SIGNATURE) + +// +// Prototypes for Driver model protocol interface +// + + +/** + Test to see if this driver supports Controller Handle. + + @param[in] This Protocol instance pointer. + @param[in] Controller Handle of device to test + @param[in] RemainingDevicePath Optional parameter use to pick a specifi= c child + device to start. + + @retval EFI_SUCCESS This driver supports this device + @retval EFI_ALREADY_STARTED This driver is already running on this d= evice + @retval other This driver does not support this device +**/ +EFI_STATUS +EFIAPI +SioDriverSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + + +/** + Start this driver on ControllerHandle. + + @param[in] This Protocol instance pointer. + @param[in] Controller Handle of device to bind driver to + @param[in] RemainingDevicePath Optional parameter use to pick a specif= ic child + device to start. + + @retval EFI_SUCCESS This driver is added to ControllerHandle + @retval EFI_ALREADY_STARTED This driver is already running on Contr= ollerHandle + @retval other This driver does not support this device +**/ +EFI_STATUS +EFIAPI +SioDriverStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + + +/** + Stop this driver on ControllerHandle. + + @param[in] This Protocol instance pointer. + @param[in] Controller Handle of device to stop driver on + @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If= number of + children is zero stop the entire bus drive= r. + @param[in] ChildHandleBuffer List of Child Handles to Stop. + + @retval EFI_SUCCESS This driver is removed ControllerHandle + @retval other This driver was not removed from this devi= ce +**/ +EFI_STATUS +EFIAPI +SioDriverStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ); +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.h b/= Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.h new file mode 100644 index 0000000000..6a8081dc6e --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.h @@ -0,0 +1,143 @@ +/** @file + Super I/O Interface function declarations. + + Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _SIO_ACPI_H_ +#define _SIO_ACPI_H_ + +// +// Prototypes for the SIO protocol interface +// + + +/** + Provides an interface to get a list of the current resources consumed by= the device in the ACPI + Resource Descriptor format. + + GetResources() returns a list of resources currently consumed by the dev= ice. The + ResourceList is a pointer to the buffer containing resource descriptors = for the device. The + descriptors are in the format of Small or Large ACPI resource descriptor= as defined by ACPI + specification (2.0 & 3.0). The buffer of resource descriptors is termina= ted with the 'End tag' + resource descriptor. + + @param[in] This Indicates a pointer to the calling c= ontext. + @param[out] ResourceList A pointer to an ACPI resource descri= ptor list that defines the current resources + used by the device. Type ACPI_RESOUR= CE_HEADER_PTR is defined in the "Related + Definitions" below. + + @retval EFI_SUCCESS The operation completed successfully + @retval EFI_INVALID_PARAMETER ResourceList is NULL +**/ +EFI_STATUS +EFIAPI +SioGetResources ( + IN CONST EFI_SIO_PROTOCOL *This, + OUT ACPI_RESOURCE_HEADER_PTR *ResourceList + ); + + +/** + Sets the resources for the device. + + @param[in] This Indicates a pointer to the calling con= text. + @param[in] ResourceList Pointer to the ACPI resource descripto= r list. Type ACPI_RESOURCE_HEADER_PTR + is defined in the "Related Definitions= " section of + EFI_SIO_PROTOCOL.GetResources(). + + @retval EFI_SUCCESS The operation completed successfully + @retval EFI_INVALID_PARAMETER ResourceList is invalid + @retval EFI_ACCESS_DENIED Some of the resources in ResourceList = are in use +**/ +EFI_STATUS +EFIAPI +SioSetResources ( + IN CONST EFI_SIO_PROTOCOL *This, + IN ACPI_RESOURCE_HEADER_PTR ResourceList + ); + + +/** + Provides a collection of resource descriptor lists. Each resource descri= ptor list in the collection + defines a combination of resources that can potentially be used by the d= evice. + + @param[in] This Indicates a pointer to the calling= context. + @param[out] ResourceCollection Collection of the resource descrip= tor lists. + + @retval EFI_SUCCESS The operation completed successful= ly + @retval EFI_INVALID_PARAMETER ResourceCollection is NULL +**/ +EFI_STATUS +EFIAPI +SioPossibleResources ( + IN CONST EFI_SIO_PROTOCOL *This, + OUT ACPI_RESOURCE_HEADER_PTR *ResourceCollection + ); + + +/** + Provides a low level access to the registers for the Super I/O. + + @param[in] This Indicates a pointer to the calli= ng context. + @param[in] Write Specifies the type of the regist= er operation. If this parameter is TRUE, + Value is interpreted as an input= parameter and the operation is a register write. + If this parameter is FALSE, Valu= e is interpreted as an output parameter and the + operation is a register read. + @param[in] ExitCfgMode Exit Configuration Mode Indicato= r. If this parameter is set to TRUE, the=20 + Super I/O driver will turn off c= onfiguration mode of the Super I/O prior to returning + from this function. If this para= meter is set to FALSE, the Super I/O driver will + leave Super I/O in the configura= tion mode. + The Super I/O driver must track = the current state of the Super I/O and enable the + configuration mode of Super I/O = if necessary prior to register access. + @param[in] Register Register number. + @param[in, out] Value If Write is TRUE, Value is a poi= nter to the buffer containing the byte of data to be + written to the Super I/O registe= r. If Write is FALSE, Value is a pointer to the + destination buffer for the byte = of data to be read from the Super I/O register. + + @retval EFI_SUCCESS The operation completed successf= ully + @retval EFI_INVALID_PARAMETER The Value is NULL + @retval EFI_INVALID_PARAMETER Invalid Register number +**/ +EFI_STATUS +EFIAPI +SioRegisterAccess ( + IN CONST EFI_SIO_PROTOCOL *This, + IN BOOLEAN Write, + IN BOOLEAN ExitCfgMode, + IN UINT8 Register, + IN OUT UINT8 *Value + ); + + +/** + Provides an interface for a table based programming of the Super I/O reg= isters. + + The Modify() function provides an interface for table based programming = of the Super I/O + registers. This function can be used to perform programming of multiple = Super I/O registers with a + single function call. For each table entry, the Register is read, its co= ntent is bitwise ANDed with + AndMask, and then ORed with OrMask before being written back to the Regi= ster. The Super + I/O driver must track the current state of the Super I/O and enable the = configuration mode of Super I/ + O if necessary prior to table processing. Once the table is processed, t= he Super I/O device has to be + returned to the original state. + + @param[in] This Indicates a pointer to the calling cont= ext. + @param[in] Command A pointer to an array of NumberOfComman= ds EFI_SIO_REGISTER_MODIFY + structures. Each structure specifies a = single Super I/O register modify operation. + Type EFI_SIO_REGISTER_MODIFY is defined= in the "Related Definitions" below. + @param[in] NumberOfCommands Number of elements in the Command array. + + @retval EFI_SUCCESS The operation completed successfully + @retval EFI_INVALID_PARAMETER Command is NULL +**/ +EFI_STATUS +EFIAPI +SioModify ( + IN CONST EFI_SIO_PROTOCOL *This, + IN CONST EFI_SIO_REGISTER_MODIFY *Command, + IN UINTN NumberOfCommands + ); + +#endif --=20 2.16.2.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 (#46945): https://edk2.groups.io/g/devel/message/46945 Mute This Topic: https://groups.io/mt/33159240/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Fri Apr 26 02:55:24 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+46949+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+46949+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1567719525; cv=none; d=zoho.com; s=zohoarc; b=gWAy/jhLk1xiLpW9JvnbYLsr+pV7PdJqvpjmlXFkpKzTtli7x4PiL4L0qzkaZ7nbnKveWLIzw82PDVMShh7u3cA0HGxBb7s55MOo4nHIlLptE4zI9OK4WaYqokyWV/Xf5LSBEBCR5zlfNQlH8uzAIWZ/8i5HANmovrLLliWetDM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1567719525; h=Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To:ARC-Authentication-Results; bh=GgOVHYDqy3ZbvPasaf51OOvLG1jBCa5ESwAT7beXDO0=; b=mM224w7P13jaDCeG5pwdTGVN0L9OMFeohZIzH8s59LwPEO+9492WCbXFXNPbiY9FgpXt49BQPw4aVrPQOsApfrJWWBuSpNTPF/48xEq5Md0i3d2h7zP+iw7GE/VxOvoHBvso4j8iyzoB+67ihiSZkfHMRtEzHmwGcxrramLPf5A= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+46949+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1567719525881915.4246886193322; Thu, 5 Sep 2019 14:38:45 -0700 (PDT) Return-Path: X-Received: from mga02.intel.com (mga02.intel.com []) by groups.io with SMTP; Thu, 05 Sep 2019 14:38:44 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Sep 2019 14:38:42 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,471,1559545200"; d="scan'208";a="267151626" X-Received: from ydwei-desk.amr.corp.intel.com ([10.24.15.168]) by orsmga001.jf.intel.com with ESMTP; 05 Sep 2019 14:38:41 -0700 From: "David Wei" To: devel@edk2.groups.io Cc: Hao Wu , Liming Gao , Ankit Sinha , Agyeman Prince , Kubacki Michael A , Nate DeSimone , Michael D Kinney Subject: [edk2-devel] [edk2-platforms PATCH v5 5/7] SimicsOpenBoardPkg: Add modules and dec file under SimicsOpenBoardPkg Date: Thu, 5 Sep 2019 14:38:38 -0700 Message-Id: <312574bd6bc09dc0b741b0a5d69d9207e630edae.1567718650.git.david.y.wei@intel.com> In-Reply-To: References: In-Reply-To: References: Precedence: Bulk List-Unsubscribe: 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,david.y.wei@intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1567719525; bh=OiVNPRDngTAxBnrxwgh1sQfgJpDsEKbr23Ot92A4XFA=; h=Cc:Date:From:Reply-To:Subject:To; b=jzZ+SGw2MFgIv2WXWWo6InsZC4FTJIQn07o2VnM6t2AfT/TPUHAzj4AneZvEP5TifiK WEktGD9mJRqHHQ4sVbMb/aox7gbK6MeRKQFTZ2L4KftgVevThe0lgisTZbXJXKH3p0To1 gG1ONxgnE5DxDzibc+jOpTBFhw23n8U6UfQ= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add AcpiTable, Logo image, dec file and GOP driver Cc: Hao Wu Cc: Liming Gao Cc: Ankit Sinha Cc: Agyeman Prince Cc: Kubacki Michael A Cc: Nate DeSimone Cc: Michael D Kinney Signed-off-by: David Wei --- .../MinPlatformAcpiTables/AcpiPlatform.c | 1579 ++++++++++++++++= ++++ .../AcpiTables/MinPlatformAcpiTables/Facs/Facs.c | 84 ++ .../AcpiTables/MinPlatformAcpiTables/Fadt/Fadt.c | 359 +++++ .../AcpiTables/MinPlatformAcpiTables/Hpet/Hpet.c | 78 + .../AcpiTables/MinPlatformAcpiTables/Wsmt/Wsmt.c | 46 + .../SimicsVideoDxe/ComponentName.c | 205 +++ .../SimicsOpenBoardPkg/SimicsVideoDxe/Driver.c | 1011 +++++++++++++ .../SimicsVideoDxe/DriverSupportedEfiVersion.c | 15 + .../Intel/SimicsOpenBoardPkg/SimicsVideoDxe/Gop.c | 416 ++++++ .../SimicsOpenBoardPkg/SimicsVideoDxe/Initialize.c | 341 +++++ .../SimicsOpenBoardPkg/SimicsVideoDxe/VbeShim.c | 302 ++++ .../SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf | 31 + .../Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl | 821 ++++++++++ .../MinPlatformAcpiTables/AcpiPlatform.h | 45 + .../MinPlatformAcpiTables/AcpiPlatform.inf | 105 ++ .../Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h | 75 + Platform/Intel/SimicsOpenBoardPkg/Logo/Logo.bmp | Bin 0 -> 141078 bytes Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec | 152 ++ .../SimicsOpenBoardPkg/SimicsVideoDxe/Simics.h | 507 +++++++ .../SimicsVideoDxe/SimicsVideoDxe.inf | 74 + .../SimicsOpenBoardPkg/SimicsVideoDxe/VbeShim.asm | 279 ++++ .../SimicsOpenBoardPkg/SimicsVideoDxe/VbeShim.h | 701 +++++++++ .../SimicsOpenBoardPkg/SimicsVideoDxe/VbeShim.sh | 79 + 23 files changed, 7305 insertions(+) create mode 100644 Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatfor= mAcpiTables/AcpiPlatform.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatfor= mAcpiTables/Facs/Facs.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatfor= mAcpiTables/Fadt/Fadt.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatfor= mAcpiTables/Hpet/Hpet.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatfor= mAcpiTables/Wsmt/Wsmt.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/Compon= entName.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/Driver= .c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/Driver= SupportedEfiVersion.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/Gop.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/Initia= lize.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/VbeShi= m.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/AcpiTables/AcpiTables= .inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl create mode 100644 Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatfor= mAcpiTables/AcpiPlatform.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatfor= mAcpiTables/AcpiPlatform.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Logo/Logo.bmp create mode 100644 Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/Simics= .h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/Simics= VideoDxe.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/VbeShi= m.asm create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/VbeShi= m.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/VbeShi= m.sh diff --git a/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatformAcpiTa= bles/AcpiPlatform.c b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatf= ormAcpiTables/AcpiPlatform.c new file mode 100644 index 0000000000..1edac89240 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatformAcpiTables/Ac= piPlatform.c @@ -0,0 +1,1579 @@ +/** @file + ACPI Platform Driver + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "AcpiPlatform.h" + +#define MAX_CPU_NUM (FixedPcdGet32(PcdMaxCpuThreadCount) * FixedPcdGet32(P= cdMaxCpuCoreCount) * FixedPcdGet32(PcdMaxCpuSocketCount)) + +#pragma pack(1) + +typedef struct { + UINT32 AcpiProcessorId; + UINT32 ApicId; + UINT32 Flags; + UINT32 SwProcApicId; + UINT32 SocketNum; +} EFI_CPU_ID_ORDER_MAP; + +// +// Private Driver Data +// +// +// Define Union of IO APIC & Local APIC structure; +// +typedef union { + EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE AcpiLocalApic; + EFI_ACPI_4_0_IO_APIC_STRUCTURE AcpiIoApic; + EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE AcpiLocalx2Apic; + struct { + UINT8 Type; + UINT8 Length; + } AcpiApicCommon; +} ACPI_APIC_STRUCTURE_PTR; + +#pragma pack() + +extern EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE Facs; +extern EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE Fadt; +extern EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER Hpet; +extern EFI_ACPI_WSMT_TABLE Wsmt; + +VOID *mLocalTable[] =3D { + &Facs, + &Fadt, + &Hpet, + &Wsmt, +}; + +EFI_ACPI_TABLE_PROTOCOL *mAcpiTable; + +UINT32 mNumOfBitShift =3D 6; +BOOLEAN mForceX2ApicId; +BOOLEAN mX2ApicEnabled; + +EFI_MP_SERVICES_PROTOCOL *mMpService; +BOOLEAN mCpuOrderSorted; +EFI_CPU_ID_ORDER_MAP mCpuApicIdOrderTable[MAX_CPU_NUM]; +UINTN mNumberOfCPUs =3D 0; +UINTN mNumberOfEnabledCPUs =3D 0; +// +// following are possible APICID Map for SKX +// +static const UINT32 ApicIdMapA[] =3D { //for SKUs have number of core > 16 + //it is 14 + 14 + 14 + 14 format + 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, = 0x00000006, 0x00000007, + 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, = 0x00000010, 0x00000011, + 0x00000012, 0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017, = 0x00000018, 0x00000019, + 0x0000001A, 0x0000001B, 0x0000001C, 0x0000001D, 0x00000020, 0x00000021, = 0x00000022, 0x00000023, + 0x00000024, 0x00000025, 0x00000026, 0x00000027, 0x00000028, 0x00000029, = 0x0000002A, 0x0000002B, + 0x0000002C, 0x0000002D, 0x00000030, 0x00000031, 0x00000032, 0x00000033, = 0x00000034, 0x00000035, + 0x00000036, 0x00000037, 0x00000038, 0x00000039, 0x0000003A, 0x0000003B, = 0x0000003C, 0x0000003D +}; + +static const UINT32 ApicIdMapB[] =3D { //for SKUs have number of cores <= =3D 16 use 32 ID space + // + //it is 16+16 format + // + 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, = 0x00000006, 0x00000007, + 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, = 0x0000000E, 0x0000000F, + 0x00000010, 0x00000011, 0x00000012, 0x00000013, 0x00000014, 0x00000015, = 0x00000016, 0x00000017, + 0x00000018, 0x00000019, 0x0000001A, 0x0000001B, 0x0000001C, 0x0000001D, = 0x0000001E, 0x0000001F, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, = 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, = 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, = 0xFFFFFFFF, 0xFFFFFFFF +}; + + +static const UINT32 ApicIdMapC[] =3D { //for SKUs have number of cores <= =3D 16 use 64 ID space + // + //it is 16+0+16+0 format + // + 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, = 0x00000006, 0x00000007, + 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, = 0x0000000E, 0x0000000F, + 0x00000020, 0x00000021, 0x00000022, 0x00000023, 0x00000024, 0x00000025, = 0x00000026, 0x00000027, + 0x00000028, 0x00000029, 0x0000002A, 0x0000002B, 0x0000002C, 0x0000002D, = 0x0000002E, 0x0000002F, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, = 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, = 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, = 0xFFFFFFFF, 0xFFFFFFFF +}; + +static const UINT32 ApicIdMapD[] =3D { //for SKUs have number of cores <= =3D 8 use 16 ID space + // + //it is 16 format + // + 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, = 0x00000006, 0x00000007, + 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, = 0x0000000E, 0x0000000F, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, = 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, = 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, = 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, = 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, = 0xFFFFFFFF, 0xFFFFFFFF +}; + +const UINT32 *mApicIdMap =3D NULL; + +/** + This function detect the APICID map and update ApicID Map pointer + + @param None + + @retval VOID + +**/ +VOID DetectApicIdMap(VOID) +{ + UINTN CoreCount; + + CoreCount =3D 0; + + if(mApicIdMap !=3D NULL) { + return; //aleady initialized + } + + mApicIdMap =3D ApicIdMapA; // default to > 16C SKUs + + CoreCount =3D mNumberOfEnabledCPUs / 2; + DEBUG ((DEBUG_INFO, "CoreCount - %d\n", CoreCount)); + + if(CoreCount <=3D 16) { + + if(mNumOfBitShift =3D=3D 4) { + mApicIdMap =3D ApicIdMapD; + } + + if(mNumOfBitShift =3D=3D 5) { + mApicIdMap =3D ApicIdMapB; + } + + if(mNumOfBitShift =3D=3D 6) { + mApicIdMap =3D ApicIdMapC; + } + + } + + return; +} + +/** + This function return the CoreThreadId of ApicId from ACPI ApicId Map arr= ay + + @param ApicId + + @retval Index of ACPI ApicId Map array + +**/ +UINT32 +GetIndexFromApicId ( + UINT32 ApicId + ) +{ + UINT32 CoreThreadId; + UINT32 i; + + ASSERT (mApicIdMap !=3D NULL); + + CoreThreadId =3D ApicId & ((1 << mNumOfBitShift) - 1); + + for(i =3D 0; i < (FixedPcdGet32(PcdMaxCpuCoreCount) * FixedPcdGet32(PcdM= axCpuThreadCount)); i++) { + if(mApicIdMap[i] =3D=3D CoreThreadId) { + break; + } + } + + ASSERT (i <=3D (FixedPcdGet32(PcdMaxCpuCoreCount) * FixedPcdGet32(PcdMax= CpuThreadCount))); + + return i; +} + +UINT32 +ApicId2SwProcApicId ( + UINT32 ApicId + ) +{ + UINT32 Index; + + for (Index =3D 0; Index < MAX_CPU_NUM; Index++) { + if ((mCpuApicIdOrderTable[Index].Flags =3D=3D 1) && (mCpuApicIdOrderTa= ble[Index].ApicId =3D=3D ApicId)) { + return Index; + } + } + + return (UINT32) -1; + +} + +VOID +DebugDisplayReOrderTable( + VOID + ) +{ + UINT32 Index; + + DEBUG ((EFI_D_ERROR, "Index AcpiProcId ApicId Flags SwApicId Skt\n"= )); + for (Index=3D0; IndexAcpiApicCommon.Type; + LocalApicPtr =3D (EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE *)(&((ACPI= _APIC_STRUCTURE_PTR *)ApicPtr)->AcpiLocalApic); + LocalX2ApicPtr =3D (EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE *)(&((= ACPI_APIC_STRUCTURE_PTR *)ApicPtr)->AcpiLocalx2Apic); + + if(Type =3D=3D EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC) { + if(!mX2ApicEnabled) { + LocalApicPtr->Flags =3D (UINT8)mCpuApicIdOrderTable[LocalA= picCounter].Flags; + LocalApicPtr->ApicId =3D (UINT8)mCpuApicIdOrderTable[LocalA= picCounter].ApicId; + LocalApicPtr->AcpiProcessorId =3D (UINT8)mCpuApicIdOrderTable[LocalA= picCounter].AcpiProcessorId; + } else { + LocalApicPtr->Flags =3D 0; + LocalApicPtr->ApicId =3D 0xFF; + LocalApicPtr->AcpiProcessorId =3D (UINT8)0xFF; + Status =3D EFI_UNSUPPORTED; + } + } else if(Type =3D=3D EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC) { + if(mX2ApicEnabled) { + LocalX2ApicPtr->Flags =3D (UINT8)mCpuApicIdOrderTable[Loc= alApicCounter].Flags; + LocalX2ApicPtr->X2ApicId =3D mCpuApicIdOrderTable[LocalApicC= ounter].ApicId; + LocalX2ApicPtr->AcpiProcessorUid =3D mCpuApicIdOrderTable[LocalApicC= ounter].AcpiProcessorId; + } else { + LocalX2ApicPtr->Flags =3D 0; + LocalX2ApicPtr->X2ApicId =3D (UINT32)-1; + LocalX2ApicPtr->AcpiProcessorUid =3D (UINT32)-1; + Status =3D EFI_UNSUPPORTED; + } + } else { + Status =3D EFI_UNSUPPORTED; + } + + return Status; + +} + +EFI_STATUS +SortCpuLocalApicInTable ( + VOID + ) +{ + EFI_STATUS Status; + EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer; + UINT32 Index; + UINT32 CurrProcessor; + UINT32 BspApicId; + UINT32 TempVal =3D 0; + EFI_CPU_ID_ORDER_MAP *CpuIdMapPtr; + UINT32 CoreThreadMask; + + Index =3D 0; + Status =3D EFI_SUCCESS; + + CoreThreadMask =3D (UINT32) ((1 << mNumOfBitShift) - 1); + + if(!mCpuOrderSorted) { + + Index =3D 0; + + for (CurrProcessor =3D 0; CurrProcessor < mNumberOfCPUs; CurrProcessor= ++) { + Status =3D mMpService->GetProcessorInfo ( + mMpService, + CurrProcessor, + &ProcessorInfoBuffer + ); + + if ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) !=3D 0)= { + if(ProcessorInfoBuffer.ProcessorId & 1) { //is 2nd thread + CpuIdMapPtr =3D (EFI_CPU_ID_ORDER_MAP *)&mCpuApicIdOrderTable[(I= ndex - 1) + MAX_CPU_NUM / 2]; + } else { //is primary thread + CpuIdMapPtr =3D (EFI_CPU_ID_ORDER_MAP *)&mCpuApicIdOrderTable[In= dex]; + Index++; + } + CpuIdMapPtr->ApicId =3D (UINT32)ProcessorInfoBuffer.ProcessorId; + CpuIdMapPtr->Flags =3D ((ProcessorInfoBuffer.StatusFlag & PROCES= SOR_ENABLED_BIT) !=3D 0); + CpuIdMapPtr->SocketNum =3D (UINT32)ProcessorInfoBuffer.Location.Pa= ckage; + CpuIdMapPtr->AcpiProcessorId =3D (CpuIdMapPtr->SocketNum * FixedPc= dGet32(PcdMaxCpuCoreCount) * FixedPcdGet32(PcdMaxCpuThreadCount)) + GetInde= xFromApicId(CpuIdMapPtr->ApicId); //CpuIdMapPtr->ApicId; + CpuIdMapPtr->SwProcApicId =3D ((UINT32)(ProcessorInfoBuffer.Locati= on.Package << mNumOfBitShift) + (((UINT32)ProcessorInfoBuffer.ProcessorId) = & CoreThreadMask)); + if(mX2ApicEnabled) { //if X2Apic, re-order the socket # so it star= ts from base 0 and contiguous + //may not necessory!!!!! + } + + //update processorbitMask + if (CpuIdMapPtr->Flags =3D=3D 1) { + + if(mForceX2ApicId) { + CpuIdMapPtr->SocketNum &=3D 0x7; + CpuIdMapPtr->AcpiProcessorId &=3D 0xFF; //keep lower 8bit due = to use Proc obj in dsdt + CpuIdMapPtr->SwProcApicId &=3D 0xFF; + } + } + } else { //not enabled + CpuIdMapPtr =3D (EFI_CPU_ID_ORDER_MAP *)&mCpuApicIdOrderTable[Inde= x]; + CpuIdMapPtr->ApicId =3D (UINT32)-1; + CpuIdMapPtr->Flags =3D 0; + CpuIdMapPtr->AcpiProcessorId =3D (UINT32)-1; + CpuIdMapPtr->SwProcApicId =3D (UINT32)-1; + CpuIdMapPtr->SocketNum =3D (UINT32)-1; + } //end if PROC ENABLE + } //end for CurrentProcessor + // + //keep for debug purpose + // + DEBUG(( EFI_D_ERROR, "::ACPI:: APIC ID Order Table Init. CoreThread= Mask =3D %x, mNumOfBitShift =3D %x\n", CoreThreadMask, mNumOfBitShift)); + DebugDisplayReOrderTable(); + // + //make sure 1st entry is BSP + // + if(mX2ApicEnabled) { + BspApicId =3D (UINT32)AsmReadMsr64(0x802); + } else { + BspApicId =3D (*(volatile UINT32 *)(UINTN)0xFEE00020) >> 24; + } + DEBUG ((EFI_D_INFO, "BspApicId - 0x%x\n", BspApicId)); + + if(mCpuApicIdOrderTable[0].ApicId !=3D BspApicId) { + // + //check to see if 1st entry is BSP, if not swap it + // + Index =3D ApicId2SwProcApicId(BspApicId); + + if(MAX_CPU_NUM <=3D Index) { + DEBUG ((EFI_D_ERROR, "Asserting the SortCpuLocalApicInTable Index = Bufferflow\n")); + ASSERT_EFI_ERROR(EFI_INVALID_PARAMETER); + } + + TempVal =3D mCpuApicIdOrderTable[Index].ApicId; + mCpuApicIdOrderTable[Index].ApicId =3D mCpuApicIdOrderTable[0].ApicI= d; + mCpuApicIdOrderTable[0].ApicId =3D TempVal; + mCpuApicIdOrderTable[Index].Flags =3D mCpuApicIdOrderTable[0].Flags; + mCpuApicIdOrderTable[0].Flags =3D 1; + TempVal =3D mCpuApicIdOrderTable[Index].SwProcApicId; + mCpuApicIdOrderTable[Index].SwProcApicId =3D mCpuApicIdOrderTable[0]= .SwProcApicId; + mCpuApicIdOrderTable[0].SwProcApicId =3D TempVal; + // + //swap AcpiProcId + // + TempVal =3D mCpuApicIdOrderTable[Index].AcpiProcessorId; + mCpuApicIdOrderTable[Index].AcpiProcessorId =3D mCpuApicIdOrderTable= [0].AcpiProcessorId; + mCpuApicIdOrderTable[0].AcpiProcessorId =3D TempVal; + + } + // + //Make sure no holes between enabled threads + // + for(CurrProcessor =3D 0; CurrProcessor < MAX_CPU_NUM; CurrProcessor++)= { + + if(mCpuApicIdOrderTable[CurrProcessor].Flags =3D=3D 0) { + // + //make sure disabled entry has ProcId set to FFs + // + mCpuApicIdOrderTable[CurrProcessor].ApicId =3D (UINT32)-1; + mCpuApicIdOrderTable[CurrProcessor].AcpiProcessorId =3D (UINT32)-1; + mCpuApicIdOrderTable[CurrProcessor].SwProcApicId =3D (UINT32)-1; + + for(Index =3D CurrProcessor+1; Index < MAX_CPU_NUM; Index++) { + if(mCpuApicIdOrderTable[Index].Flags =3D=3D 1) { + // + //move enabled entry up + // + mCpuApicIdOrderTable[CurrProcessor].Flags =3D 1; + mCpuApicIdOrderTable[CurrProcessor].ApicId =3D mCpuApicIdOrder= Table[Index].ApicId; + mCpuApicIdOrderTable[CurrProcessor].AcpiProcessorId =3D mCpuAp= icIdOrderTable[Index].AcpiProcessorId; + mCpuApicIdOrderTable[CurrProcessor].SwProcApicId =3D mCpuApicI= dOrderTable[Index].SwProcApicId; + mCpuApicIdOrderTable[CurrProcessor].SocketNum =3D mCpuApicIdOr= derTable[Index].SocketNum; + // + //disable moved entry + // + mCpuApicIdOrderTable[Index].Flags =3D 0; + mCpuApicIdOrderTable[Index].ApicId =3D (UINT32)-1; + mCpuApicIdOrderTable[Index].AcpiProcessorId =3D (UINT32)-1; + mCpuApicIdOrderTable[Index].SwProcApicId =3D (UINT32)-1; + break; + } + } + } + } + // + //keep for debug purpose + // + DEBUG ((EFI_D_ERROR, "APIC ID Order Table ReOrdered\n")); + DebugDisplayReOrderTable(); + + mCpuOrderSorted =3D TRUE; + } + + return Status; +} + + +/** Structure of a sub-structure of the ACPI header. + + This structure contains the type and length fields, which are common to = every + sub-structure of the ACPI tables. A pointer to any structure can be cast= as this. +**/ +typedef struct { + UINT8 Type; + UINT8 Length; +} STRUCTURE_HEADER; + +STRUCTURE_HEADER mMadtStructureTable[] =3D { + {EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC, sizeof (EFI_ACPI_4_0_PROCES= SOR_LOCAL_APIC_STRUCTURE)}, + {EFI_ACPI_4_0_IO_APIC, sizeof (EFI_ACPI_4_0_IO_API= C_STRUCTURE)}, + {EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE, sizeof (EFI_ACPI_4_0_INTERR= UPT_SOURCE_OVERRIDE_STRUCTURE)}, + {EFI_ACPI_4_0_NON_MASKABLE_INTERRUPT_SOURCE, sizeof (EFI_ACPI_4_0_NON_MA= SKABLE_INTERRUPT_SOURCE_STRUCTURE)}, + {EFI_ACPI_4_0_LOCAL_APIC_NMI, sizeof (EFI_ACPI_4_0_LOCAL_= APIC_NMI_STRUCTURE)}, + {EFI_ACPI_4_0_LOCAL_APIC_ADDRESS_OVERRIDE, sizeof (EFI_ACPI_4_0_LOCAL_= APIC_ADDRESS_OVERRIDE_STRUCTURE)}, + {EFI_ACPI_4_0_IO_SAPIC, sizeof (EFI_ACPI_4_0_IO_SAP= IC_STRUCTURE)}, + {EFI_ACPI_4_0_LOCAL_SAPIC, sizeof (EFI_ACPI_4_0_PROCES= SOR_LOCAL_SAPIC_STRUCTURE)}, + {EFI_ACPI_4_0_PLATFORM_INTERRUPT_SOURCES, sizeof (EFI_ACPI_4_0_PLATFO= RM_INTERRUPT_SOURCES_STRUCTURE)}, + {EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC, sizeof (EFI_ACPI_4_0_PROCES= SOR_LOCAL_X2APIC_STRUCTURE)}, + {EFI_ACPI_4_0_LOCAL_X2APIC_NMI, sizeof (EFI_ACPI_4_0_LOCAL_= X2APIC_NMI_STRUCTURE)} +}; + +/** + Get the size of the ACPI table. + + This function calculates the size needed for the ACPI Table based on the= number and + size of the sub-structures that will compose it. + + @param[in] TableSpecificHdrLength Size of the table specific header, n= ot the ACPI standard header size. + @param[in] Structures Pointer to an array of sub-structure= pointers. + @param[in] StructureCount Number of structure pointers in the = array. + + @return Total size needed for the ACPI table. +**/ +UINT32 +GetTableSize ( + IN UINTN TableSpecificHdrLength, + IN STRUCTURE_HEADER **Structures, + IN UINTN StructureCount + ) +{ + UINT32 TableLength; + UINT32 Index; + + // + // Compute size of the ACPI table; header plus all structures needed. + // + TableLength =3D (UINT32) TableSpecificHdrLength; + + for (Index =3D 0; Index < StructureCount; Index++) { + ASSERT (Structures[Index] !=3D NULL); + if (Structures[Index] =3D=3D NULL) { + return 0; + } + + TableLength +=3D Structures[Index]->Length; + } + + return TableLength; +} + +/** + Allocate the ACPI Table. + + This function allocates space for the ACPI table based on the number and= size of + the sub-structures that will compose it. + + @param[in] TableSpecificHdrLength Size of the table specific header, n= ot the ACPI standard header size. + @param[in] Structures Pointer to an array of sub-structure pointers. + @param[in] StructureCount Number of structure pointers in the array. + @param[out] Table Newly allocated ACPI Table pointer. + + @retval EFI_SUCCESS Successfully allocated the Table. + @retval EFI_OUT_OF_RESOURCES Space for the Table could not be allocated. +**/ +EFI_STATUS +AllocateTable ( + IN UINTN TableSpecificHdrLength, + IN STRUCTURE_HEADER **Structures, + IN UINTN StructureCount, + OUT EFI_ACPI_DESCRIPTION_HEADER **Table + ) +{ + EFI_STATUS Status; + UINT32 Size; + EFI_ACPI_DESCRIPTION_HEADER *InternalTable; + + // + // Get the size of the ACPI table and allocate memory. + // + Size =3D GetTableSize (TableSpecificHdrLength, Structures, StructureCoun= t); + InternalTable =3D (EFI_ACPI_DESCRIPTION_HEADER *) AllocatePool (Size); + + if (InternalTable =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + DEBUG (( + DEBUG_ERROR, + "Failed to allocate %d bytes for ACPI Table\n", + Size + )); + } else { + Status =3D EFI_SUCCESS; + DEBUG (( + DEBUG_INFO, + "Successfully allocated %d bytes for ACPI Table at 0x%p\n", + Size, + InternalTable + )); + *Table =3D InternalTable; + } + + return Status; +} + +/** + Initialize the header. + + This function fills in the standard table header with correct values, + except for the length and checksum fields, which are filled in later. + + @param[in,out] Header Pointer to the header structure. + + @retval EFI_SUCCESS Successfully initialized the header. + @retval EFI_INVALID_PARAMETER Pointer parameter was null. +**/ +EFI_STATUS +InitializeHeader ( + IN OUT EFI_ACPI_DESCRIPTION_HEADER *Header, + IN UINT32 Signature, + IN UINT8 Revision, + IN UINT32 OemRevision + ) +{ + UINT64 AcpiTableOemId; + + if (Header =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "Header pointer is NULL\n")); + return EFI_INVALID_PARAMETER; + } + + Header->Signature =3D Signature; + Header->Length =3D 0; // filled in by Build function + Header->Revision =3D Revision; + Header->Checksum =3D 0; // filled in by InstallAcpiTable + + CopyMem ( + (VOID *) &Header->OemId, + PcdGetPtr (PcdAcpiDefaultOemId), + sizeof (Header->OemId) + ); + + AcpiTableOemId =3D PcdGet64 (PcdAcpiDefaultOemTableId); + CopyMem ( + (VOID *) &Header->OemTableId, + (VOID *) &AcpiTableOemId, + sizeof (Header->OemTableId) + ); + + Header->OemRevision =3D OemRevision; + Header->CreatorId =3D 0; + Header->CreatorRevision =3D 0; + + return EFI_SUCCESS; +} + +/** + Initialize the MADT header. + + This function fills in the MADT's standard table header with correct val= ues, + except for the length and checksum fields, which are filled in later. + + @param[in,out] MadtHeader Pointer to the MADT header structure. + + @retval EFI_SUCCESS Successfully initialized the MADT header. + @retval EFI_INVALID_PARAMETER Pointer parameter was null. +**/ +EFI_STATUS +InitializeMadtHeader ( + IN OUT EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *MadtHeader + ) +{ + EFI_STATUS Status; + + if (MadtHeader =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "MADT header pointer is NULL\n")); + return EFI_INVALID_PARAMETER; + } + + Status =3D InitializeHeader ( + &MadtHeader->Header, + EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION, + 0 + ); + if (EFI_ERROR (Status)) { + return Status; + } + + MadtHeader->LocalApicAddress =3D PcdGet32(PcdLocalApicAddress); + MadtHeader->Flags =3D EFI_ACPI_4_0_PCAT_COMPAT; + + return EFI_SUCCESS; +} + +/** + Copy an ACPI sub-structure; MADT and SRAT supported + + This function validates the structure type and size of a sub-structure + and returns a newly allocated copy of it. + + @param[in] Header Pointer to the header of the table. + @param[in] Structure Pointer to the structure to copy. + @param[in] NewStructure Newly allocated copy of the structure. + + @retval EFI_SUCCESS Successfully copied the structure. + @retval EFI_INVALID_PARAMETER Pointer parameter was null. + @retval EFI_INVALID_PARAMETER Structure type was unknown. + @retval EFI_INVALID_PARAMETER Structure length was wrong for its type. + @retval EFI_UNSUPPORTED Header passed in is not supported. +**/ +EFI_STATUS +CopyStructure ( + IN EFI_ACPI_DESCRIPTION_HEADER *Header, + IN STRUCTURE_HEADER *Structure, + OUT STRUCTURE_HEADER **NewStructure + ) +{ + STRUCTURE_HEADER *NewStructureInternal; + STRUCTURE_HEADER *StructureTable; + UINTN TableNumEntries; + BOOLEAN EntryFound; + UINT8 Index; + + // + // Initialize the number of table entries and the table based on the tab= le header passed in. + // + if (Header->Signature =3D=3D EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABL= E_SIGNATURE) { + TableNumEntries =3D sizeof (mMadtStructureTable) / sizeof (STRUCTURE_H= EADER); + StructureTable =3D mMadtStructureTable; + } else { + return EFI_UNSUPPORTED; + } + + // + // Check the incoming structure against the table of supported structure= s. + // + EntryFound =3D FALSE; + for (Index =3D 0; Index < TableNumEntries; Index++) { + if (Structure->Type =3D=3D StructureTable[Index].Type) { + if (Structure->Length =3D=3D StructureTable[Index].Length) { + EntryFound =3D TRUE; + } else { + DEBUG (( + DEBUG_ERROR, + "Invalid length for structure type %d: expected %d, actually %d\= n", + Structure->Type, + StructureTable[Index].Length, + Structure->Length + )); + return EFI_INVALID_PARAMETER; + } + } + } + + // + // If no entry in the table matches the structure type and length passed= in + // then return invalid parameter. + // + if (!EntryFound) { + DEBUG (( + DEBUG_ERROR, + "Unknown structure type: %d\n", + Structure->Type + )); + return EFI_INVALID_PARAMETER; + } + + NewStructureInternal =3D (STRUCTURE_HEADER *) AllocatePool (Structure->L= ength); + if (NewStructureInternal =3D=3D NULL) { + DEBUG (( + DEBUG_ERROR, + "Failed to allocate %d bytes for type %d structure\n", + Structure->Length, + Structure->Type + )); + return EFI_OUT_OF_RESOURCES; + } else { + DEBUG (( + DEBUG_INFO, + "Successfully allocated %d bytes for type %d structure at 0x%p\n", + Structure->Length, + Structure->Type, + NewStructureInternal + )); + } + + CopyMem ( + (VOID *) NewStructureInternal, + (VOID *) Structure, + Structure->Length + ); + + *NewStructure =3D NewStructureInternal; + return EFI_SUCCESS; +} + +/** + Build ACPI Table. MADT tables supported. + + This function builds the ACPI table from the header plus the list of sub= -structures + passed in. The table returned by this function is ready to be installed = using + the ACPI table protocol's InstallAcpiTable function, which copies it into + ACPI memory. After that, the caller should free the memory returned by t= his + function. + + @param[in] AcpiHeader Pointer to the header structure. + @param[in] TableSpecificHdrLength Size of the table specific header, no= t the ACPI standard header size. + @param[in] Structures Pointer to an array of sub-structure = pointers. + @param[in] StructureCount Number of structure pointers in the a= rray. + @param[out] NewTable Newly allocated and initialized point= er to the ACPI Table. + + @retval EFI_SUCCESS Successfully built the ACPI table. + @retval EFI_INVALID_PARAMETER Pointer parameter was null. + @retval EFI_INVALID_PARAMETER Header parameter had the wrong signature. + @retval EFI_OUT_OF_RESOURCES Space for the ACPI Table could not be allo= cated. +**/ +EFI_STATUS +BuildAcpiTable ( + IN EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader, + IN UINTN TableSpecificHdrLength, + IN STRUCTURE_HEADER **Structures, + IN UINTN StructureCount, + OUT UINT8 **NewTable + ) +{ + EFI_STATUS Status; + EFI_ACPI_DESCRIPTION_HEADER *InternalTable; + UINTN Index; + UINT8 *CurrPtr; + UINT8 *EndOfTablePtr; + + if (AcpiHeader =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "AcpiHeader pointer is NULL\n")); + return EFI_INVALID_PARAMETER; + } + + if (AcpiHeader->Signature !=3D EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TA= BLE_SIGNATURE) { + DEBUG (( + DEBUG_ERROR, + "MADT header signature is expected, actually 0x%08x\n", + AcpiHeader->Signature + )); + return EFI_INVALID_PARAMETER; + } + + if (Structures =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "Structure array pointer is NULL\n")); + return EFI_INVALID_PARAMETER; + } + + for (Index =3D 0; Index < StructureCount; Index++) { + if (Structures[Index] =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "Structure pointer %d is NULL\n", Index)); + return EFI_INVALID_PARAMETER; + } + } + + // + // Allocate the memory needed for the table. + // + Status =3D AllocateTable ( + TableSpecificHdrLength, + Structures, + StructureCount, + &InternalTable + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Copy Header and patch in structure length, checksum is programmed lat= er + // after all structures are populated. + // + CopyMem ( + (VOID *) InternalTable, + (VOID *) AcpiHeader, + TableSpecificHdrLength + ); + + InternalTable->Length =3D GetTableSize (TableSpecificHdrLength, Structur= es, StructureCount); + + // + // Copy all the sub structures to the table. + // + CurrPtr =3D ((UINT8 *) InternalTable) + TableSpecificHdrLength; + EndOfTablePtr =3D ((UINT8 *) InternalTable) + InternalTable->Length; + + for (Index =3D 0; Index < StructureCount; Index++) { + ASSERT (Structures[Index] !=3D NULL); + if (Structures[Index] =3D=3D NULL) { + break; + } + + CopyMem ( + (VOID *) CurrPtr, + (VOID *) Structures[Index], + Structures[Index]->Length + ); + + CurrPtr +=3D Structures[Index]->Length; + ASSERT (CurrPtr <=3D EndOfTablePtr); + if (CurrPtr > EndOfTablePtr) { + break; + } + } + + // + // Update the return pointer. + // + *NewTable =3D (UINT8 *) InternalTable; + return EFI_SUCCESS; +} + +/** + Build from scratch and install the MADT. + + @retval EFI_SUCCESS The MADT was installed successfully. + @retval EFI_OUT_OF_RESOURCES Could not allocate required structures. +**/ +EFI_STATUS +InstallMadtFromScratch ( + VOID + ) +{ + EFI_STATUS Status; + UINTN Index; + EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *NewMadtTable; + UINTN TableHandle; + EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER MadtTableHeader; + EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE ProcLocalApicStruct; + EFI_ACPI_4_0_IO_APIC_STRUCTURE IoApicStruct; + EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE IntSrcOverrideStruct; + EFI_ACPI_4_0_LOCAL_APIC_NMI_STRUCTURE LocalApciNmiStruct; + EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE ProcLocalX2ApicStruc= t; + EFI_ACPI_4_0_LOCAL_X2APIC_NMI_STRUCTURE LocalX2ApicNmiStruct; + STRUCTURE_HEADER **MadtStructs; + UINTN MaxMadtStructCount; + UINTN MadtStructsIndex; + UINT32 CurrentIoApicAddress= =3D (UINT32)(PcdGet32(PcdPcIoApicAddressBase)); + UINT32 PcIoApicEnable; + UINT32 PcIoApicMask; + UINTN PcIoApicIndex; + + DetectApicIdMap(); + + // Call for Local APIC ID Reorder + SortCpuLocalApicInTable (); + + NewMadtTable =3D NULL; + + MaxMadtStructCount =3D (UINT32) ( + MAX_CPU_NUM + // processor local APIC structures + MAX_CPU_NUM + // processor local x2APIC structures + 1 + PcdGet8(PcdPcIoApicCount) + // I/O APIC structures + 2 + // interrupt source override structures + 1 + // local APIC NMI structures + 1 // local x2APIC NMI structures + ); // other structures are not used + + MadtStructs =3D (STRUCTURE_HEADER **) AllocateZeroPool (MaxMadtStructCou= nt * sizeof (STRUCTURE_HEADER *)); + if (MadtStructs =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "Could not allocate MADT structure pointer array\= n")); + return EFI_OUT_OF_RESOURCES; + } + + // + // Initialize the next index into the structure pointer array. It is + // incremented every time a structure of any type is copied to the array. + // + MadtStructsIndex =3D 0; + + // + // Initialize MADT Header Structure + // + Status =3D InitializeMadtHeader (&MadtTableHeader); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "InitializeMadtHeader failed: %r\n", Status)); + goto Done; + } + + DEBUG ((EFI_D_INFO, "Number of CPUs detected =3D %d \n", mNumberOfCPUs)); + + // + // Build Processor Local APIC Structures and Processor Local X2APIC Stru= ctures + // + ProcLocalApicStruct.Type =3D EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC; + ProcLocalApicStruct.Length =3D sizeof (EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC= _STRUCTURE); + + ProcLocalX2ApicStruct.Type =3D EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC; + ProcLocalX2ApicStruct.Length =3D sizeof (EFI_ACPI_4_0_PROCESSOR_LOCAL_X2= APIC_STRUCTURE); + ProcLocalX2ApicStruct.Reserved[0] =3D 0; + ProcLocalX2ApicStruct.Reserved[1] =3D 0; + + for (Index =3D 0; Index < MAX_CPU_NUM; Index++) { + // + // If x2APIC mode is not enabled, and if it is possible to express the + // APIC ID as a UINT8, use a processor local APIC structure. Otherwise, + // use a processor local x2APIC structure. + // + if (!mX2ApicEnabled && mCpuApicIdOrderTable[Index].ApicId < MAX_UINT8)= { + ProcLocalApicStruct.Flags =3D (UINT8) mCpuApicIdOrderTable= [Index].Flags; + ProcLocalApicStruct.ApicId =3D (UINT8) mCpuApicIdOrderTable= [Index].ApicId; + ProcLocalApicStruct.AcpiProcessorId =3D (UINT8) mCpuApicIdOrderTable= [Index].AcpiProcessorId; + + ASSERT (MadtStructsIndex < MaxMadtStructCount); + Status =3D CopyStructure ( + &MadtTableHeader.Header, + (STRUCTURE_HEADER *) &ProcLocalApicStruct, + &MadtStructs[MadtStructsIndex++] + ); + } else if (mCpuApicIdOrderTable[Index].ApicId !=3D 0xFFFFFFFF) { + ProcLocalX2ApicStruct.Flags =3D (UINT8) mCpuApicIdOrderTa= ble[Index].Flags; + ProcLocalX2ApicStruct.X2ApicId =3D mCpuApicIdOrderTable[Inde= x].ApicId; + ProcLocalX2ApicStruct.AcpiProcessorUid =3D mCpuApicIdOrderTable[Inde= x].AcpiProcessorId; + + ASSERT (MadtStructsIndex < MaxMadtStructCount); + Status =3D CopyStructure ( + &MadtTableHeader.Header, + (STRUCTURE_HEADER *) &ProcLocalX2ApicStruct, + &MadtStructs[MadtStructsIndex++] + ); + } + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "CopyMadtStructure (local APIC/x2APIC) failed: = %r\n", Status)); + goto Done; + } + } + + // + // Build I/O APIC Structures + // + IoApicStruct.Type =3D EFI_ACPI_4_0_IO_APIC; + IoApicStruct.Length =3D sizeof (EFI_ACPI_4_0_IO_APIC_STRUCTURE); + IoApicStruct.Reserved =3D 0; + + PcIoApicEnable =3D PcdGet32(PcdPcIoApicEnable); + + if (FixedPcdGet32(PcdMaxCpuSocketCount) <=3D 4) { + IoApicStruct.IoApicId =3D PcdGet8(PcdIoApicId); + IoApicStruct.IoApicAddress =3D PcdGet32(PcdIoApicAddress); + IoApicStruct.GlobalSystemInterruptBase =3D 0; + ASSERT (MadtStructsIndex < MaxMadtStructCount); + Status =3D CopyStructure ( + &MadtTableHeader.Header, + (STRUCTURE_HEADER *) &IoApicStruct, + &MadtStructs[MadtStructsIndex++] + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "CopyMadtStructure (I/O APIC) failed: %r\n", St= atus)); + goto Done; + } + } + + for (PcIoApicIndex =3D 0; PcIoApicIndex < PcdGet8(PcdPcIoApicCount); PcI= oApicIndex++) { + PcIoApicMask =3D (1 << PcIoApicIndex); + if ((PcIoApicEnable & PcIoApicMask) =3D=3D 0) { + continue; + } + + IoApicStruct.IoApicId =3D (UINT8)(PcdGet8(PcdPcIoAp= icIdBase) + PcIoApicIndex); + IoApicStruct.IoApicAddress =3D CurrentIoApicAddress; + CurrentIoApicAddress =3D (CurrentIoApicAddress & 0= xFFFF8000) + 0x8000; + IoApicStruct.GlobalSystemInterruptBase =3D (UINT32)(24 + (PcIoApicIn= dex * 8)); + ASSERT (MadtStructsIndex < MaxMadtStructCount); + Status =3D CopyStructure ( + &MadtTableHeader.Header, + (STRUCTURE_HEADER *) &IoApicStruct, + &MadtStructs[MadtStructsIndex++] + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "CopyMadtStructure (I/O APIC) failed: %r\n", = Status)); + goto Done; + } + } + + // + // Build Interrupt Source Override Structures + // + IntSrcOverrideStruct.Type =3D EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE; + IntSrcOverrideStruct.Length =3D sizeof (EFI_ACPI_4_0_INTERRUPT_SOURCE_OV= ERRIDE_STRUCTURE); + + // + // IRQ0=3D>IRQ2 Interrupt Source Override Structure + // + IntSrcOverrideStruct.Bus =3D 0x0; // Bus - ISA + IntSrcOverrideStruct.Source =3D 0x0; // Source - IRQ0 + IntSrcOverrideStruct.GlobalSystemInterrupt =3D 0x2; // Global System Int= errupt - IRQ2 + IntSrcOverrideStruct.Flags =3D 0x0; // Flags - Conforms = to specifications of the bus + + ASSERT (MadtStructsIndex < MaxMadtStructCount); + Status =3D CopyStructure ( + &MadtTableHeader.Header, + (STRUCTURE_HEADER *) &IntSrcOverrideStruct, + &MadtStructs[MadtStructsIndex++] + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "CopyMadtStructure (IRQ2 source override) failed:= %r\n", Status)); + goto Done; + } + + // + // IRQ9 (SCI Active High) Interrupt Source Override Structure + // + IntSrcOverrideStruct.Bus =3D 0x0; // Bus - ISA + IntSrcOverrideStruct.Source =3D 0x9; // Source - IRQ9 + IntSrcOverrideStruct.GlobalSystemInterrupt =3D 0x9; // Global System Int= errupt - IRQ9 + IntSrcOverrideStruct.Flags =3D 0xD; // Flags - Level-tig= gered, Active High + + ASSERT (MadtStructsIndex < MaxMadtStructCount); + Status =3D CopyStructure ( + &MadtTableHeader.Header, + (STRUCTURE_HEADER *) &IntSrcOverrideStruct, + &MadtStructs[MadtStructsIndex++] + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "CopyMadtStructure (IRQ9 source override) failed:= %r\n", Status)); + goto Done; + } + + // + // Build Local APIC NMI Structures + // + LocalApciNmiStruct.Type =3D EFI_ACPI_4_0_LOCAL_APIC_NMI; + LocalApciNmiStruct.Length =3D sizeof (EFI_ACPI_4_0_LOCAL_APIC_NMI_STRUCT= URE); + LocalApciNmiStruct.AcpiProcessorId =3D 0xFF; // Applies to all proc= essors + LocalApciNmiStruct.Flags =3D 0x000D; // Flags - Level-tigge= red, Active High + LocalApciNmiStruct.LocalApicLint =3D 0x1; + + ASSERT (MadtStructsIndex < MaxMadtStructCount); + Status =3D CopyStructure ( + &MadtTableHeader.Header, + (STRUCTURE_HEADER *) &LocalApciNmiStruct, + &MadtStructs[MadtStructsIndex++] + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "CopyMadtStructure (APIC NMI) failed: %r\n", Stat= us)); + goto Done; + } + + // + // Build Local x2APIC NMI Structure + // + LocalX2ApicNmiStruct.Type =3D EFI_ACPI_4_0_LOCAL_X2APIC_NMI; + LocalX2ApicNmiStruct.Length =3D sizeof (EFI_ACPI_4_0_LOCAL_X2APIC_NMI_ST= RUCTURE); + LocalX2ApicNmiStruct.Flags =3D 0x000D; // Flags - Level-= tiggered, Active High + LocalX2ApicNmiStruct.AcpiProcessorUid =3D 0xFFFFFFFF; // Applies to all= processors + LocalX2ApicNmiStruct.LocalX2ApicLint =3D 0x01; + LocalX2ApicNmiStruct.Reserved[0] =3D 0x00; + LocalX2ApicNmiStruct.Reserved[1] =3D 0x00; + LocalX2ApicNmiStruct.Reserved[2] =3D 0x00; + + ASSERT (MadtStructsIndex < MaxMadtStructCount); + Status =3D CopyStructure ( + &MadtTableHeader.Header, + (STRUCTURE_HEADER *) &LocalX2ApicNmiStruct, + &MadtStructs[MadtStructsIndex++] + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "CopyMadtStructure (x2APIC NMI) failed: %r\n", St= atus)); + goto Done; + } + + // + // Build Madt Structure from the Madt Header and collection of pointers = in MadtStructs[] + // + Status =3D BuildAcpiTable ( + (EFI_ACPI_DESCRIPTION_HEADER *) &MadtTableHeader, + sizeof (EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER), + MadtStructs, + MadtStructsIndex, + (UINT8 **)&NewMadtTable + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "BuildAcpiTable failed: %r\n", Status)); + goto Done; + } + + // + // Publish Madt Structure to ACPI + // + Status =3D mAcpiTable->InstallAcpiTable ( + mAcpiTable, + NewMadtTable, + NewMadtTable->Header.Length, + &TableHandle + ); + +Done: + // + // Free memory + // + for (MadtStructsIndex =3D 0; MadtStructsIndex < MaxMadtStructCount; Madt= StructsIndex++) { + if (MadtStructs[MadtStructsIndex] !=3D NULL) { + FreePool (MadtStructs[MadtStructsIndex]); + } + } + + FreePool (MadtStructs); + + if (NewMadtTable !=3D NULL) { + FreePool (NewMadtTable); + } + + return Status; +} + +EFI_STATUS +InstallMcfgFromScratch ( + VOID + ) +{ + EFI_STATUS = Status; + EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER = *McfgTable; + EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCAT= ION_STRUCTURE *Segment; + UINTN = Index; + UINTN = SegmentCount; + PCI_SEGMENT_INFO = *PciSegmentInfo; + UINTN = TableHandle; + + PciSegmentInfo =3D GetPciSegmentInfo (&SegmentCount); + + McfgTable =3D AllocateZeroPool ( + sizeof(EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_T= ABLE_HEADER) + + sizeof(EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE= _BASE_ADDRESS_ALLOCATION_STRUCTURE) * SegmentCount + ); + if (McfgTable =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "Could not allocate MCFG structure\n")); + return EFI_OUT_OF_RESOURCES; + } + + Status =3D InitializeHeader ( + &McfgTable->Header, + EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRES= S_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION, + 0 + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Set MCFG table "Length" field based on the number of PCIe segments en= umerated so far + // + McfgTable->Header.Length =3D (UINT32)(sizeof (EFI_ACPI_MEMORY_MAPPED_CON= FIGURATION_BASE_ADDRESS_TABLE_HEADER) +=20 + sizeof (EFI_ACPI_MEMORY_MAPPED_ENHAN= CED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE) * SegmentCount); + + Segment =3D (VOID *)(McfgTable + 1); + + for (Index =3D 0; Index < SegmentCount; Index++) { + Segment[Index].PciSegmentGroupNumber =3D PciSegmentInfo[Index].Segmen= tNumber; + Segment[Index].BaseAddress =3D PciSegmentInfo[Index].BaseAddress; + Segment[Index].StartBusNumber =3D PciSegmentInfo[Index].StartBusNumber; + Segment[Index].EndBusNumber =3D PciSegmentInfo[Index].EndBusNumber; + } + + // + // Publish Madt Structure to ACPI + // + Status =3D mAcpiTable->InstallAcpiTable ( + mAcpiTable, + McfgTable, + McfgTable->Header.Length, + &TableHandle + ); + + return Status; +} + +/** + This function will update any runtime platform specific information. + This currently includes: + Setting OEM table values, ID, table ID, creator ID and creator revisio= n. + Enabling the proper processor entries in the APIC tables + It also indicates with which ACPI table version the table belongs. + + @param[in] Table The table to update + @param[in] Version Where to install this table + + @retval EFI_SUCCESS Updated tables commplete. +**/ +EFI_STATUS +PlatformUpdateTables ( + IN OUT EFI_ACPI_COMMON_HEADER *Table, + IN OUT EFI_ACPI_TABLE_VERSION *Version + ) +{ + EFI_ACPI_DESCRIPTION_HEADER *TableHeader; + UINT8 *TempOemId; + UINT64 TempOemTableId; + EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader; + EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *HpetTable; + UINT32 HpetBaseAddress; + EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_BLOCK_ID HpetBlockId; + UINT32 HpetCapabilitiesData; + HPET_GENERAL_CAPABILITIES_ID_REGISTER HpetCapabilities; + + TableHeader =3D NULL; + + // + // By default, a table belongs in all ACPI table versions published. + // Some tables will override this because they have different versions o= f the table. + // + TableHeader =3D (EFI_ACPI_DESCRIPTION_HEADER *) Table; + + // + // Update the OEM and creator information for every table except FACS. + // + if (Table->Signature !=3D EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_S= IGNATURE) { + TempOemId =3D (UINT8 *)PcdGetPtr(PcdAcpiDefaultOemId); + CopyMem (&TableHeader->OemId, TempOemId, 6); + + // + // Skip OEM table ID and creator information for DSDT, SSDT and PSDT t= ables, since these are + // created by an ASL compiler and the creator information is useful. + // + if (Table->Signature !=3D EFI_ACPI_1_0_DIFFERENTIATED_SYSTEM_DESCRIPTI= ON_TABLE_SIGNATURE && + Table->Signature !=3D EFI_ACPI_1_0_SECONDARY_SYSTEM_DESCRIPTION_TA= BLE_SIGNATURE && + Table->Signature !=3D EFI_ACPI_1_0_PERSISTENT_SYSTEM_DESCRIPTION_T= ABLE_SIGNATURE + ) { + TempOemTableId =3D PcdGet64(PcdAcpiDefaultOemTableId); + CopyMem (&TableHeader->OemTableId, &TempOemTableId, 8); + + // + // Update the creator ID + // + TableHeader->CreatorId =3D PcdGet32(PcdAcpiDefaultCreatorId); + + // + // Update the creator revision + // + TableHeader->CreatorRevision =3D PcdGet32(PcdAcpiDefaultCreatorRevis= ion); + } + } + + + // + // By default, a table belongs in all ACPI table versions published. + // Some tables will override this because they have different versions o= f the table. + // + *Version =3D EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | = EFI_ACPI_TABLE_VERSION_3_0; + + // + // Update the various table types with the necessary updates + // + switch (Table->Signature) { + + case EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE: + ASSERT(FALSE); + break; + + case EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE: + FadtHeader =3D (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *) Table; + + FadtHeader->PreferredPmProfile =3D PcdGet8 (PcdFadtPreferredPmProfile); + FadtHeader->IaPcBootArch =3D PcdGet16 (PcdFadtIaPcBootArch); + FadtHeader->Flags =3D PcdGet32 (PcdFadtFlags); + + FadtHeader->AcpiEnable =3D PcdGet8 (PcdAcpiEnableSwSmi); + FadtHeader->AcpiDisable =3D PcdGet8 (PcdAcpiDisableSwSmi); + + FadtHeader->Pm1aEvtBlk =3D PcdGet16 (PcdAcpiPm1AEventBlockAddress); + FadtHeader->Pm1bEvtBlk =3D PcdGet16 (PcdAcpiPm1BEventBlockAddress); + FadtHeader->Pm1aCntBlk =3D PcdGet16 (PcdAcpiPm1AControlBlockAddress); + FadtHeader->Pm1bCntBlk =3D PcdGet16 (PcdAcpiPm1BControlBlockAddress); + FadtHeader->Pm2CntBlk =3D PcdGet16 (PcdAcpiPm2ControlBlockAddress); + FadtHeader->PmTmrBlk =3D PcdGet16 (PcdAcpiPmTimerBlockAddress); + FadtHeader->Gpe0Blk =3D PcdGet16 (PcdAcpiGpe0BlockAddress); + FadtHeader->Gpe1Blk =3D PcdGet16 (PcdAcpiGpe1BlockAddress); + + FadtHeader->XPm1aEvtBlk.Address =3D PcdGet16 (PcdAcpiPm1AEventBlockAdd= ress); + FadtHeader->XPm1bEvtBlk.Address =3D PcdGet16 (PcdAcpiPm1BEventBlockAdd= ress); + if (FadtHeader->XPm1bEvtBlk.Address =3D=3D 0) { + FadtHeader->XPm1bEvtBlk.AccessSize =3D 0; + } + FadtHeader->XPm1aCntBlk.Address =3D PcdGet16 (PcdAcpiPm1AControlBlockA= ddress); + FadtHeader->XPm1bCntBlk.Address =3D PcdGet16 (PcdAcpiPm1BControlBlockA= ddress); + if (FadtHeader->XPm1bCntBlk.Address =3D=3D 0) { + FadtHeader->XPm1bCntBlk.AccessSize =3D 0; + } + FadtHeader->XPm2CntBlk.Address =3D PcdGet16 (PcdAcpiPm2ControlBlockAd= dress); + //if (FadtHeader->XPm2CntBlk.Address =3D=3D 0) { + FadtHeader->XPm2CntBlk.AccessSize =3D 0; + //} + FadtHeader->XPmTmrBlk.Address =3D PcdGet16 (PcdAcpiPmTimerBlockAddre= ss); + FadtHeader->XGpe0Blk.Address =3D PcdGet16 (PcdAcpiGpe0BlockAddress); + FadtHeader->XGpe1Blk.Address =3D PcdGet16 (PcdAcpiGpe1BlockAddress); + if (FadtHeader->XGpe1Blk.Address =3D=3D 0) { + FadtHeader->XGpe1Blk.AccessSize =3D 0; + } + + DEBUG(( EFI_D_ERROR, "ACPI FADT table @ address 0x%x\n", Table )); + DEBUG(( EFI_D_ERROR, " IaPcBootArch 0x%x\n", FadtHeader->IaPcBootArch= )); + DEBUG(( EFI_D_ERROR, " Flags 0x%x\n", FadtHeader->Flags )); + break; + + case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE: + HpetTable =3D (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *)Tabl= e; + HpetBaseAddress =3D PcdGet32 (PcdHpetBaseAddress); + HpetTable->BaseAddressLower32Bit.Address =3D HpetBaseAddress; + HpetTable->BaseAddressLower32Bit.RegisterBitWidth =3D 0; + HpetCapabilitiesData =3D MmioRead32 (HpetBaseAddress + HPET_GENERA= L_CAPABILITIES_ID_OFFSET); + HpetCapabilities.Uint64 =3D HpetCapabilitiesData; + HpetCapabilitiesData =3D MmioRead32 (HpetBaseAddress + HPET_GENERA= L_CAPABILITIES_ID_OFFSET + 4); + HpetCapabilities.Uint64 |=3D LShiftU64 (HpetCapabilitiesData, 32); + HpetBlockId.Bits.Revision =3D HpetCapabilities.Bits.Revision; + HpetBlockId.Bits.NumberOfTimers =3D HpetCapabilities.Bits.NumberOfTime= rs; + HpetBlockId.Bits.CounterSize =3D HpetCapabilities.Bits.CounterSize; + HpetBlockId.Bits.Reserved =3D 0; + HpetBlockId.Bits.LegacyRoute =3D HpetCapabilities.Bits.LegacyRoute; + HpetBlockId.Bits.VendorId =3D HpetCapabilities.Bits.VendorId; + HpetTable->EventTimerBlockId =3D HpetBlockId.Uint32; + HpetTable->MainCounterMinimumClockTickInPeriodicMode =3D (UINT16)HpetC= apabilities.Bits.CounterClockPeriod; + DEBUG(( EFI_D_ERROR, "ACPI HPET table @ address 0x%x\n", Table )); + DEBUG(( EFI_D_ERROR, " HPET base 0x%x\n", PcdGet32 (PcdHpetBaseAddres= s) )); + break; + + case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADD= RESS_DESCRIPTION_TABLE_SIGNATURE: + ASSERT(FALSE); + break; + + default: + break; + } + return EFI_SUCCESS; +} + +/** + This function calculates RCR based on PCI Device ID and Vendor ID from t= he devices + available on the platform. + It also includes other instances of BIOS change to calculate CRC and pro= vides as + HWSignature filed in FADT table. +**/ +VOID +IsHardwareChange ( + VOID + ) +{ + EFI_STATUS Status; + UINTN Index; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + EFI_PCI_IO_PROTOCOL *PciIo; + UINT32 CRC; + UINT32 *HWChange; + UINTN HWChangeSize; + UINT32 PciId; + UINTN Handle; + EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *FacsPtr; + EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *pFADT; + + HandleCount =3D 0; + HandleBuffer =3D NULL; + + Status =3D gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiPciIoProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return; // PciIO protocol not installed yet! + } + + // + // Allocate memory for HWChange and add additional entrie for + // pFADT->XDsdt + // + HWChangeSize =3D HandleCount + 1; + HWChange =3D AllocateZeroPool( sizeof(UINT32) * HWChangeSize ); + ASSERT( HWChange !=3D NULL ); + + if (HWChange =3D=3D NULL) return; + + // + // add HWChange inputs: PCI devices + // + for (Index =3D 0; HandleCount > 0; HandleCount--) { + PciId =3D 0; + Status =3D gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtoco= lGuid, (VOID **) &PciIo); + if (!EFI_ERROR (Status)) { + Status =3D PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0, 1, &PciId= ); + if (EFI_ERROR (Status)) { + continue; + } + HWChange[Index++] =3D PciId; + } + } + + // + // Locate FACP Table + // + Handle =3D 0; + Status =3D LocateAcpiTableBySignature ( + EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, + (EFI_ACPI_DESCRIPTION_HEADER **) &pFADT, + &Handle + ); + if (EFI_ERROR (Status) || (pFADT =3D=3D NULL)) { + return; //Table not found or out of memory resource for pFADT table + } + + // + // add HWChange inputs: others + // + HWChange[Index++] =3D (UINT32)pFADT->XDsdt; + + // + // Calculate CRC value with HWChange data. + // + Status =3D gBS->CalculateCrc32(HWChange, HWChangeSize, &CRC); + DEBUG((DEBUG_INFO, "CRC =3D %x and Status =3D %r\n", CRC, Status)); + + // + // Set HardwareSignature value based on CRC value. + // + FacsPtr =3D (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)pFADT= ->FirmwareCtrl; + FacsPtr->HardwareSignature =3D CRC; + FreePool( HWChange ); +} + +VOID +UpdateLocalTable ( + VOID + ) +{ + EFI_STATUS Status; + EFI_ACPI_COMMON_HEADER *CurrentTable; + EFI_ACPI_TABLE_VERSION Version; + UINTN TableHandle; + UINTN Index; + + for (Index =3D 0; Index < sizeof(mLocalTable)/sizeof(mLocalTable[0]); In= dex++) { + CurrentTable =3D mLocalTable[Index]; + + PlatformUpdateTables (CurrentTable, &Version); + + TableHandle =3D 0; + + if (Version !=3D EFI_ACPI_TABLE_VERSION_NONE) { + Status =3D mAcpiTable->InstallAcpiTable ( + mAcpiTable, + CurrentTable, + CurrentTable->Length, + &TableHandle + ); + ASSERT_EFI_ERROR (Status); + } + } +} + + +VOID +EFIAPI +AcpiEndOfDxeEvent ( + EFI_EVENT Event, + VOID *ParentImageHandle + ) +{ + + if (Event !=3D NULL) { + gBS->CloseEvent(Event); + } + + + // + // Calculate Hardware Signature value based on current platform configur= ations + // + IsHardwareChange(); +} + +/** + ACPI Platform driver installation function. + + @param[in] ImageHandle Handle for this drivers loaded image protocol. + @param[in] SystemTable EFI system table. + + @retval EFI_SUCCESS The driver installed without error. + @retval EFI_ABORTED The driver encountered an error and could not= complete installation of + the ACPI tables. + +**/ +EFI_STATUS +EFIAPI +InstallAcpiPlatform ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_EVENT EndOfDxeEvent; + + + Status =3D gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID = **)&mMpService); + ASSERT_EFI_ERROR (Status); + + Status =3D gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID = **)&mAcpiTable); + ASSERT_EFI_ERROR (Status); + + // + // Create an End of DXE event. + // + Status =3D gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + AcpiEndOfDxeEvent, + NULL, + &gEfiEndOfDxeEventGroupGuid, + &EndOfDxeEvent + ); + ASSERT_EFI_ERROR (Status); + + // + // Determine the number of processors + // + mMpService->GetNumberOfProcessors ( + mMpService, + &mNumberOfCPUs, + &mNumberOfEnabledCPUs + ); + ASSERT (mNumberOfCPUs <=3D MAX_CPU_NUM && mNumberOfEnabledCPUs >=3D 1); + DEBUG ((DEBUG_INFO, "mNumberOfCPUs - %d\n", mNumberOfCPUs)); + DEBUG ((DEBUG_INFO, "mNumberOfEnabledCPUs - %d\n", mNumberOfEnabledCPUs)= ); + + DEBUG ((DEBUG_INFO, "mX2ApicEnabled - 0x%x\n", mX2ApicEnabled)); + DEBUG ((DEBUG_INFO, "mForceX2ApicId - 0x%x\n", mForceX2ApicId)); + + // support up to 64 threads/socket + AsmCpuidEx(CPUID_EXTENDED_TOPOLOGY, 1, &mNumOfBitShift, NULL, NULL, NULL= ); + mNumOfBitShift &=3D 0x1F; + DEBUG ((DEBUG_INFO, "mNumOfBitShift - 0x%x\n", mNumOfBitShift)); + + UpdateLocalTable (); + + InstallMadtFromScratch (); + InstallMcfgFromScratch (); + + return EFI_SUCCESS; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatformAcpiTa= bles/Facs/Facs.c b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatform= AcpiTables/Facs/Facs.c new file mode 100644 index 0000000000..e649b5b89c --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatformAcpiTables/Fa= cs/Facs.c @@ -0,0 +1,84 @@ +/** @file + This file contains a structure definition for the ACPI 5.0 Firmware ACPI + Control Structure (FACS). The contents of this file should only be modi= fied + for bug fixes, no porting is required. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// Statements that include other files +// + +#include + +// +// FACS Definitions +// +#define EFI_ACPI_FIRMWARE_WAKING_VECTOR 0x00000000 +#define EFI_ACPI_GLOBAL_LOCK 0x00000000 + +// +// Firmware Control Structure Feature Flags are defined in AcpiX.0.h +// +#define EFI_ACPI_FIRMWARE_CONTROL_STRUCTURE_FLAGS 0x00000000 + +#define EFI_ACPI_X_FIRMWARE_WAKING_VECTOR 0x0000000000000000 + +#define EFI_ACPI_OSPM_FLAGS 0x00000000 + + +// +// Firmware ACPI Control Structure +// Please modify all values in Facs.h only. +// + +EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE Facs =3D { + EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE, + sizeof (EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE), + + // + // Hardware Signature will be updated at runtime + // + 0x00000000, + + EFI_ACPI_FIRMWARE_WAKING_VECTOR, + EFI_ACPI_GLOBAL_LOCK, + EFI_ACPI_FIRMWARE_CONTROL_STRUCTURE_FLAGS, + EFI_ACPI_X_FIRMWARE_WAKING_VECTOR, + EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION, + { + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE + }, + EFI_ACPI_OSPM_FLAGS, + { + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE + } +}; diff --git a/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatformAcpiTa= bles/Fadt/Fadt.c b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatform= AcpiTables/Fadt/Fadt.c new file mode 100644 index 0000000000..d1fe98e24b --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatformAcpiTables/Fa= dt/Fadt.c @@ -0,0 +1,359 @@ +/** @file + This file contains a structure definition for the ACPI 5.0 Fixed ACPI + Description Table (FADT). The contents of this file should only be modi= fied + for bug fixes, no porting is required. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// Statements that include other files +// +#include + +// +// FADT Definitions +// +#define EFI_ACPI_OEM_FADT_REVISION 0x00000000 + +#define EFI_ACPI_PREFERRED_PM_PROFILE 0x00 // To be fixed + +#define EFI_ACPI_SCI_INT 0x0009 +#define EFI_ACPI_SMI_CMD 0x000000B2 + +#define EFI_ACPI_ACPI_ENABLE 0 // To be fixed +#define EFI_ACPI_ACPI_DISABLE 0 // To be fixed +#define EFI_ACPI_S4_BIOS_REQ 0x00 +#define EFI_ACPI_CST_CNT 0x00 + +#define EFI_ACPI_PSTATE_CNT 0x00 +#define EFI_ACPI_GPE1_BASE (EFI_ACPI_GPE1_BLK_BIT_WIDTH / 2) +#define EFI_ACPI_P_LVL2_LAT 0x0065 // 101 +#define EFI_ACPI_P_LVL3_LAT 0x03E9 // 1001 +#define EFI_ACPI_FLUSH_SIZE 0x0000 +#define EFI_ACPI_FLUSH_STRIDE 0x0000 +#define EFI_ACPI_DUTY_OFFSET 0x01 +#define EFI_ACPI_DUTY_WIDTH 0x00 + +#define EFI_ACPI_DAY_ALRM 0x0D +#define EFI_ACPI_MON_ALRM 0x00 +#define EFI_ACPI_CENTURY 0x32 + +// +// IA-PC Boot Architecture Flags +// + +#define EFI_ACPI_IAPC_BOOT_ARCH 0 // To be fixed + +// +// Fixed Feature Flags +// +#define EFI_ACPI_FIXED_FEATURE_FLAGS 0 // To be fixed + +// +// PM1A Event Register Block Generic Address Information +// +#define EFI_ACPI_PM1A_EVT_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO +#define EFI_ACPI_PM1A_EVT_BLK_BIT_WIDTH 0x20 +#define EFI_ACPI_PM1A_EVT_BLK_BIT_OFFSET 0x00 +#define EFI_ACPI_PM1A_EVT_BLK_ADDRESS 0 // To be fixed + +// +// PM1B Event Register Block Generic Address Information +// +#define EFI_ACPI_PM1B_EVT_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO +#define EFI_ACPI_PM1B_EVT_BLK_BIT_WIDTH 0x00 +#define EFI_ACPI_PM1B_EVT_BLK_BIT_OFFSET 0x00 +#define EFI_ACPI_PM1B_EVT_BLK_ADDRESS 0 // To be fixed + +// +// PM1A Control Register Block Generic Address Information +// +#define EFI_ACPI_PM1A_CNT_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO +#define EFI_ACPI_PM1A_CNT_BLK_BIT_WIDTH 0x10 +#define EFI_ACPI_PM1A_CNT_BLK_BIT_OFFSET 0x00 +#define EFI_ACPI_PM1A_CNT_BLK_ADDRESS 0 // To be fixed + +// +// PM1B Control Register Block Generic Address Information +// +#define EFI_ACPI_PM1B_CNT_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO +#define EFI_ACPI_PM1B_CNT_BLK_BIT_WIDTH 0x00 +#define EFI_ACPI_PM1B_CNT_BLK_BIT_OFFSET 0x00 +#define EFI_ACPI_PM1B_CNT_BLK_ADDRESS 0 // To be fixed + +// +// PM2 Control Register Block Generic Address Information +// +#define EFI_ACPI_PM2_CNT_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO +#define EFI_ACPI_PM2_CNT_BLK_BIT_WIDTH 0x08 +#define EFI_ACPI_PM2_CNT_BLK_BIT_OFFSET 0x00 +#define EFI_ACPI_PM2_CNT_BLK_ADDRESS 0 // To be fixed + +// +// Power Management Timer Control Register Block Generic Address +// Information +// +#define EFI_ACPI_PM_TMR_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO +#define EFI_ACPI_PM_TMR_BLK_BIT_WIDTH 0x20 +#define EFI_ACPI_PM_TMR_BLK_BIT_OFFSET 0x00 +#define EFI_ACPI_PM_TMR_BLK_ADDRESS 0 // To be fixed + +// +// General Purpose Event 0 Register Block Generic Address +// Information +// +#define EFI_ACPI_GPE0_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO +#define EFI_ACPI_GPE0_BLK_BIT_WIDTH 0 // size of R_PCH_ACPI_GPE0_= STS_127_96 + R_PCH_ACPI_GPE0_EN_127_96 +#define EFI_ACPI_GPE0_BLK_BIT_OFFSET 0x00 +#define EFI_ACPI_GPE0_BLK_ADDRESS 0 // To be fixed + +// +// General Purpose Event 1 Register Block Generic Address +// Information +// +#define EFI_ACPI_GPE1_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO +#define EFI_ACPI_GPE1_BLK_BIT_WIDTH 0x0 +#define EFI_ACPI_GPE1_BLK_BIT_OFFSET 0x0 +#define EFI_ACPI_GPE1_BLK_ADDRESS 0 // To be fixed +// +// Reset Register Generic Address Information +// +#define EFI_ACPI_RESET_REG_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO +#define EFI_ACPI_RESET_REG_BIT_WIDTH 0x08 +#define EFI_ACPI_RESET_REG_BIT_OFFSET 0x00 +#define EFI_ACPI_RESET_REG_ADDRESS 0x00000CF9 +#define EFI_ACPI_RESET_VALUE 0x06 + +// +// Number of bytes decoded by PM1 event blocks (a and b) +// +#define EFI_ACPI_PM1_EVT_LEN ((EFI_ACPI_PM1A_EVT_BLK_BIT_WIDTH + EFI_ACPI= _PM1B_EVT_BLK_BIT_WIDTH) / 8) + +// +// Number of bytes decoded by PM1 control blocks (a and b) +// +#define EFI_ACPI_PM1_CNT_LEN ((EFI_ACPI_PM1A_CNT_BLK_BIT_WIDTH + EFI_ACPI= _PM1B_CNT_BLK_BIT_WIDTH) / 8) + +// +// Number of bytes decoded by PM2 control block +// +#define EFI_ACPI_PM2_CNT_LEN (EFI_ACPI_PM2_CNT_BLK_BIT_WIDTH / 8) + +// +// Number of bytes decoded by PM timer block +// +#define EFI_ACPI_PM_TMR_LEN (EFI_ACPI_PM_TMR_BLK_BIT_WIDTH / 8) + +// +// Number of bytes decoded by GPE0 block +// +#define EFI_ACPI_GPE0_BLK_LEN (EFI_ACPI_GPE0_BLK_BIT_WIDTH / 8) + +// +// Number of bytes decoded by GPE1 block +// +#define EFI_ACPI_GPE1_BLK_LEN (EFI_ACPI_GPE1_BLK_BIT_WIDTH / 8) + +// +// Fixed ACPI Description Table +// Please modify all values in Fadt.h only. +// + +EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE Fadt =3D { + { + EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, + sizeof (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE), + EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION, + + // + // Checksum will be updated at runtime + // + 0x00, + + // + // It is expected that these values will be updated at runtime + // + { ' ', ' ', ' ', ' ', ' ', ' ' }, + + 0, + EFI_ACPI_OEM_FADT_REVISION, + 0, + 0 + }, + + // + // These addresses will be updated at runtime + // + 0x00000000, + 0x00000000, + + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_PREFERRED_PM_PROFILE, + EFI_ACPI_SCI_INT, + EFI_ACPI_SMI_CMD, + EFI_ACPI_ACPI_ENABLE, + EFI_ACPI_ACPI_DISABLE, + EFI_ACPI_S4_BIOS_REQ, + EFI_ACPI_PSTATE_CNT, + + EFI_ACPI_PM1A_EVT_BLK_ADDRESS, + EFI_ACPI_PM1B_EVT_BLK_ADDRESS, + EFI_ACPI_PM1A_CNT_BLK_ADDRESS, + EFI_ACPI_PM1B_CNT_BLK_ADDRESS, + EFI_ACPI_PM2_CNT_BLK_ADDRESS, + EFI_ACPI_PM_TMR_BLK_ADDRESS, + EFI_ACPI_GPE0_BLK_ADDRESS, + EFI_ACPI_GPE1_BLK_ADDRESS, + EFI_ACPI_PM1_EVT_LEN, + EFI_ACPI_PM1_CNT_LEN, + EFI_ACPI_PM2_CNT_LEN, + EFI_ACPI_PM_TMR_LEN, + EFI_ACPI_GPE0_BLK_LEN, + EFI_ACPI_GPE1_BLK_LEN, + EFI_ACPI_GPE1_BASE, + + // + // Latest OS have C-State capability and CST_CNT SMI doesn't need to be = defined. + // CST_CNT SMI is not handled in BIOS and it can be removed safely. + // + EFI_ACPI_CST_CNT, + EFI_ACPI_P_LVL2_LAT, + EFI_ACPI_P_LVL3_LAT, + EFI_ACPI_FLUSH_SIZE, + EFI_ACPI_FLUSH_STRIDE, + EFI_ACPI_DUTY_OFFSET, + EFI_ACPI_DUTY_WIDTH, + EFI_ACPI_DAY_ALRM, + EFI_ACPI_MON_ALRM, + EFI_ACPI_CENTURY, + EFI_ACPI_IAPC_BOOT_ARCH, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_FIXED_FEATURE_FLAGS, + + // + // Reset Register Block + // + { + EFI_ACPI_RESET_REG_ADDRESS_SPACE_ID, + EFI_ACPI_RESET_REG_BIT_WIDTH, + EFI_ACPI_RESET_REG_BIT_OFFSET, + EFI_ACPI_5_0_BYTE, + EFI_ACPI_RESET_REG_ADDRESS + }, + EFI_ACPI_RESET_VALUE, + { + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE + }, + + // + // These addresses will be updated at runtime + // + 0x0000000000000000, // X_FIRMWARE_CTRL + 0x0000000000000000, // X_DSDT + + { + // + // X_PM1a Event Register Block + // + EFI_ACPI_PM1A_EVT_BLK_ADDRESS_SPACE_ID, + EFI_ACPI_PM1A_EVT_BLK_BIT_WIDTH, + EFI_ACPI_PM1A_EVT_BLK_BIT_OFFSET, + EFI_ACPI_5_0_WORD, + EFI_ACPI_PM1A_EVT_BLK_ADDRESS + }, + { + // + // X_PM1b Event Register Block + // + EFI_ACPI_PM1B_EVT_BLK_ADDRESS_SPACE_ID, + EFI_ACPI_PM1B_EVT_BLK_BIT_WIDTH, + EFI_ACPI_PM1B_EVT_BLK_BIT_OFFSET, + EFI_ACPI_5_0_WORD, + EFI_ACPI_PM1B_EVT_BLK_ADDRESS + }, + { + // + // X_PM1a Control Register Block + // + EFI_ACPI_PM1A_CNT_BLK_ADDRESS_SPACE_ID, + EFI_ACPI_PM1A_CNT_BLK_BIT_WIDTH, + EFI_ACPI_PM1A_CNT_BLK_BIT_OFFSET, + EFI_ACPI_5_0_WORD, + EFI_ACPI_PM1A_CNT_BLK_ADDRESS + }, + { + // + // X_PM1b Control Register Block + // + EFI_ACPI_PM1B_CNT_BLK_ADDRESS_SPACE_ID, + EFI_ACPI_PM1B_CNT_BLK_BIT_WIDTH, + EFI_ACPI_PM1B_CNT_BLK_BIT_OFFSET, + EFI_ACPI_5_0_WORD, + EFI_ACPI_PM1B_CNT_BLK_ADDRESS + }, + { + // + // X_PM2 Control Register Block + // + EFI_ACPI_PM2_CNT_BLK_ADDRESS_SPACE_ID, + EFI_ACPI_PM2_CNT_BLK_BIT_WIDTH, + EFI_ACPI_PM2_CNT_BLK_BIT_OFFSET, + EFI_ACPI_5_0_BYTE, + EFI_ACPI_PM2_CNT_BLK_ADDRESS + }, + { + // + // X_PM Timer Control Register Block + // + EFI_ACPI_PM_TMR_BLK_ADDRESS_SPACE_ID, + EFI_ACPI_PM_TMR_BLK_BIT_WIDTH, + EFI_ACPI_PM_TMR_BLK_BIT_OFFSET, + EFI_ACPI_5_0_DWORD, + EFI_ACPI_PM_TMR_BLK_ADDRESS + }, + { + // + // X_General Purpose Event 0 Register Block + // + EFI_ACPI_GPE0_BLK_ADDRESS_SPACE_ID, + EFI_ACPI_GPE0_BLK_BIT_WIDTH, + EFI_ACPI_GPE0_BLK_BIT_OFFSET, + EFI_ACPI_5_0_BYTE, + EFI_ACPI_GPE0_BLK_ADDRESS + }, + { + // + // X_General Purpose Event 1 Register Block + // + EFI_ACPI_GPE1_BLK_ADDRESS_SPACE_ID, + EFI_ACPI_GPE1_BLK_BIT_WIDTH, + EFI_ACPI_GPE1_BLK_BIT_OFFSET, + EFI_ACPI_5_0_BYTE, + EFI_ACPI_GPE1_BLK_ADDRESS + }, + { + // + // Sleep Control Reg - update in DXE driver + // + 0, + 0, + 0, + 0, + 0 + }, + { + // + // Sleep Status Reg - update in DXE driver + // + 0, + 0, + 0, + 0, + 0 + } +}; diff --git a/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatformAcpiTa= bles/Hpet/Hpet.c b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatform= AcpiTables/Hpet/Hpet.c new file mode 100644 index 0000000000..e9528b0ec3 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatformAcpiTables/Hp= et/Hpet.c @@ -0,0 +1,78 @@ +/** @file + This file contains a structure definition for the ACPI 1.0 High Precisio= n Event Timer + Description Table (HPET). The contents of this file should only be modi= fied + for bug fixes, no porting is required. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// Statements that include other files +// + +#include +#include + +// +// HPET Definitions +// +#define EFI_ACPI_OEM_HPET_REVISION 0x00000001 + +#define EFI_ACPI_EVENT_TIMER_BLOCK_ID 0x0 // To be filled + +// +// Event Timer Block Base Address Information +// +#define EFI_ACPI_EVENT_TIMER_BLOCK_ADDRESS_SPACE_ID EFI_ACPI_3_0_SYSTEM_ME= MORY +#define EFI_ACPI_EVENT_TIMER_BLOCK_BIT_WIDTH 0x40 +#define EFI_ACPI_EVENT_TIMER_BLOCK_BIT_OFFSET 0x00 +#define EFI_ACPI_EVENT_TIMER_ACCESS_SIZE 0x00 +#define EFI_ACPI_EVENT_TIMER_BLOCK_ADDRESS 0x0 // To be filled + +#define EFI_ACPI_HPET_NUMBER 0x00 + +#define EFI_ACPI_MIN_CLOCK_TICK 0x0080 + +#define EFI_ACPI_HPET_ATTRIBUTES 0x00 + +// +// High Precision Event Timer Table +// Please modify all values in Hpet.h only. +// + +EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER Hpet =3D { + { + EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE, + sizeof (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER), + EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_REVISION, + + // + // Checksum will be updated at runtime + // + 0x00, + + // + // It is expected that these values will be updated at runtime + // + { ' ', ' ', ' ', ' ', ' ', ' ' }, + + 0, + EFI_ACPI_OEM_HPET_REVISION, + 0, + 0 + }, + + EFI_ACPI_EVENT_TIMER_BLOCK_ID, + { + EFI_ACPI_EVENT_TIMER_BLOCK_ADDRESS_SPACE_ID, + EFI_ACPI_EVENT_TIMER_BLOCK_BIT_WIDTH, + EFI_ACPI_EVENT_TIMER_BLOCK_BIT_OFFSET, + EFI_ACPI_EVENT_TIMER_ACCESS_SIZE, + EFI_ACPI_EVENT_TIMER_BLOCK_ADDRESS + }, + EFI_ACPI_HPET_NUMBER, + EFI_ACPI_MIN_CLOCK_TICK, + EFI_ACPI_HPET_ATTRIBUTES +}; diff --git a/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatformAcpiTa= bles/Wsmt/Wsmt.c b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatform= AcpiTables/Wsmt/Wsmt.c new file mode 100644 index 0000000000..625b7560bb --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatformAcpiTables/Ws= mt/Wsmt.c @@ -0,0 +1,46 @@ +/** @file + ACPI WSMT table + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// Statements that include other files +// + +#include +#include +#include + +// +// WSMT Definitions +// + +#define EFI_ACPI_OEM_WSMT_REVISION 0x00000001 + +EFI_ACPI_WSMT_TABLE Wsmt =3D { + { + EFI_ACPI_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE, + sizeof (EFI_ACPI_WSMT_TABLE), + EFI_WSMT_TABLE_REVISION, + + // + // Checksum will be updated at runtime + // + 0x00, + + // + // It is expected that these values will be updated at runtime + // + { ' ', ' ', ' ', ' ', ' ', ' ' }, + + 0, + EFI_ACPI_OEM_WSMT_REVISION, + 0, + 0 + }, + + FixedPcdGet32(PcdWsmtProtectionFlags) +}; diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/ComponentName= .c b/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/ComponentName.c new file mode 100644 index 0000000000..b1286b0b64 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/ComponentName.c @@ -0,0 +1,205 @@ +/** @file + Component name for the QEMU video controller. + + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "Simics.h" + +// +// EFI Component Name Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gQemuVideoCompo= nentName =3D { + QemuVideoComponentNameGetDriverName, + QemuVideoComponentNameGetControllerName, + "eng" +}; + +// +// EFI Component Name 2 Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gQemuVideoCompo= nentName2 =3D { + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) QemuVideoComponentNameGetDriverNam= e, + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) QemuVideoComponentNameGetContr= ollerName, + "en" +}; + + +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mQemuVideoDriverNam= eTable[] =3D { + { "eng;en", L"QEMU Video Driver" }, + { NULL , NULL } +}; + +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mQemuVideoControlle= rNameTable[] =3D { + { "eng;en", L"QEMU Video PCI Adapter" }, + { NULL , NULL } +}; + +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form o= f a + Unicode string. If the driver specified by This has a user readable name= in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver speci= fied + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTO= COL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the calle= r is + requesting, and it must match one of the + languages specified in SupportedLanguages.= The + number of languages supported by a driver = is up + to the driver writer. Language is specified + in RFC 4646 or ISO 639-2 language code for= mat. + + @param DriverName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specifie= d by + This and the language specified by Languag= e was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not supp= ort + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +QemuVideoComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mQemuVideoDriverNameTable, + DriverName, + (BOOLEAN)(This =3D=3D &gQemuVideoComponentName) + ); +} + +/** + Retrieves a Unicode string that is the user readable name of the control= ler + that is being managed by a driver. + + This function retrieves the user readable name of the controller specifi= ed by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specif= ied by + Language, then a pointer to the controller name is returned in Controlle= rName, + and EFI_SUCCESS is returned. If the driver specified by This is not cur= rently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does = not + support the language specified by Language, then EFI_UNSUPPORTED is retu= rned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTO= COL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param ControllerHandle[in] The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to = be + returned. + + @param ChildHandle[in] The handle of the child controller to retr= ieve + the name of. This is an optional paramete= r that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus d= rivers + that wish to retrieve the name of the bus + controller. It will not be NULL for a bus + driver that wishes to retrieve the name of= a + child controller. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the calle= r is + requesting, and it must match one of the + languages specified in SupportedLanguages.= The + number of languages supported by a driver = is up + to the driver writer. Language is specifie= d in + RFC 4646 or ISO 639-2 language code format. + + @param ControllerName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + controller specified by ControllerHandle a= nd + ChildHandle in the language specified by + Language from the point of view of the dri= ver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable n= ame in + the language specified by Language for the + driver specified by This was returned in + DriverName. + + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a va= lid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not curren= tly + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not supp= ort + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +QemuVideoComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle O= PTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + EFI_STATUS Status; + + // + // This is a device driver, so ChildHandle must be NULL. + // + if (ChildHandle !=3D NULL) { + return EFI_UNSUPPORTED; + } + + // + // Make sure this driver is currently managing ControllHandle + // + Status =3D EfiTestManagedDevice ( + ControllerHandle, + gQemuVideoDriverBinding.DriverBindingHandle, + &gEfiPciIoProtocolGuid + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get the QEMU Video's Device structure + // + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mQemuVideoControllerNameTable, + ControllerName, + (BOOLEAN)(This =3D=3D &gQemuVideoComponentName) + ); +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/Driver.c b/Pl= atform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/Driver.c new file mode 100644 index 0000000000..15f03812bf --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/Driver.c @@ -0,0 +1,1011 @@ +/** @file + This driver is a sample implementation of the Graphics Output Protocol f= or + the QEMU (Cirrus Logic 5446) video controller. + + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "Simics.h" +#include + +EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding =3D { + QemuVideoControllerDriverSupported, + QemuVideoControllerDriverStart, + QemuVideoControllerDriverStop, + 0x10, + NULL, + NULL +}; + +QEMU_VIDEO_CARD gQemuVideoCardList[] =3D { + { + PCI_CLASS_DISPLAY_VGA, + CIRRUS_LOGIC_VENDOR_ID, + CIRRUS_LOGIC_5430_DEVICE_ID, + QEMU_VIDEO_CIRRUS_5430, + L"Cirrus 5430" + },{ + PCI_CLASS_DISPLAY_VGA, + CIRRUS_LOGIC_VENDOR_ID, + CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID, + QEMU_VIDEO_CIRRUS_5430, + L"Cirrus 5430" + },{ + PCI_CLASS_DISPLAY_VGA, + CIRRUS_LOGIC_VENDOR_ID, + CIRRUS_LOGIC_5446_DEVICE_ID, + QEMU_VIDEO_CIRRUS_5446, + L"Cirrus 5446" + },{ + PCI_CLASS_DISPLAY_VGA, + 0x4321, + 0x1111, + QEMU_VIDEO_BOCHS_MMIO, + L"QEMU Standard VGA" + },{ + PCI_CLASS_DISPLAY_OTHER, + 0x1234, + 0x1111, + QEMU_VIDEO_BOCHS_MMIO, + L"QEMU Standard VGA (secondary)" + },{ + PCI_CLASS_DISPLAY_VGA, + 0x1b36, + 0x0100, + QEMU_VIDEO_BOCHS, + L"QEMU QXL VGA" + },{ + PCI_CLASS_DISPLAY_VGA, + 0x1af4, + 0x1050, + QEMU_VIDEO_BOCHS_MMIO, + L"QEMU VirtIO VGA" + },{ + 0 /* end of list */ + } +}; + +static QEMU_VIDEO_CARD* +QemuVideoDetect( + IN UINT8 SubClass, + IN UINT16 VendorId, + IN UINT16 DeviceId + ) +{ + UINTN Index =3D 0; + + while (gQemuVideoCardList[Index].VendorId !=3D 0) { + if (gQemuVideoCardList[Index].SubClass =3D=3D SubClass && + gQemuVideoCardList[Index].VendorId =3D=3D VendorId && + gQemuVideoCardList[Index].DeviceId =3D=3D DeviceId) { + return gQemuVideoCardList + Index; + } + Index++; + } + return NULL; +} + +/** + Check if this device is supported. + + @param This The driver binding protocol. + @param Controller The controller handle to check. + @param RemainingDevicePath The remaining device path. + + @retval EFI_SUCCESS The bus supports this controller. + @retval EFI_UNSUPPORTED This device isn't supported. + +**/ +EFI_STATUS +EFIAPI +QemuVideoControllerDriverSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + PCI_TYPE00 Pci; + QEMU_VIDEO_CARD *Card; + + // + // Open the PCI I/O Protocol + // + Status =3D gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Read the PCI Configuration Header from the PCI Device + // + Status =3D PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint32, + 0, + sizeof (Pci) / sizeof (UINT32), + &Pci + ); + if (EFI_ERROR (Status)) { + goto Done; + } + + Status =3D EFI_UNSUPPORTED; + if (!IS_PCI_DISPLAY (&Pci)) { + goto Done; + } + Card =3D QemuVideoDetect(Pci.Hdr.ClassCode[1], Pci.Hdr.VendorId, Pci.Hdr= .DeviceId); + if (Card !=3D NULL) { + DEBUG ((EFI_D_INFO, "QemuVideo: %s detected\n", Card->Name)); + Status =3D EFI_SUCCESS; + } + +Done: + // + // Close the PCI I/O Protocol + // + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + return Status; +} + +/** + Start to process the controller. + + @param This The USB bus driver binding instance. + @param Controller The controller to check. + @param RemainingDevicePath The remaining device patch. + + @retval EFI_SUCCESS The controller is controlled by the usb b= us. + @retval EFI_ALREADY_STARTED The controller is already controlled by t= he usb + bus. + @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. + +**/ +EFI_STATUS +EFIAPI +QemuVideoControllerDriverStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_TPL OldTpl; + EFI_STATUS Status; + QEMU_VIDEO_PRIVATE_DATA *Private; + BOOLEAN IsQxl; + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + ACPI_ADR_DEVICE_PATH AcpiDeviceNode; + PCI_TYPE00 Pci; + QEMU_VIDEO_CARD *Card; + EFI_PCI_IO_PROTOCOL *ChildPciIo; + + OldTpl =3D gBS->RaiseTPL (TPL_CALLBACK); + + // + // Allocate Private context data for GOP inteface. + // + Private =3D AllocateZeroPool (sizeof (QEMU_VIDEO_PRIVATE_DATA)); + if (Private =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto RestoreTpl; + } + + // + // Set up context record + // + Private->Signature =3D QEMU_VIDEO_PRIVATE_DATA_SIGNATURE; + + // + // Open PCI I/O Protocol + // + Status =3D gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &Private->PciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + goto FreePrivate; + } + + // + // Read the PCI Configuration Header from the PCI Device + // + Status =3D Private->PciIo->Pci.Read ( + Private->PciIo, + EfiPciIoWidthUint32, + 0, + sizeof (Pci) / sizeof (UINT32), + &Pci + ); + if (EFI_ERROR (Status)) { + goto ClosePciIo; + } + + // + // Determine card variant. + // + Card =3D QemuVideoDetect(Pci.Hdr.ClassCode[1], Pci.Hdr.VendorId, Pci.Hdr= .DeviceId); + if (Card =3D=3D NULL) { + Status =3D EFI_DEVICE_ERROR; + goto ClosePciIo; + } + Private->Variant =3D Card->Variant; + + // + // IsQxl is based on the detected Card->Variant, which at a later point = might + // not match Private->Variant. + // + IsQxl =3D (BOOLEAN)(Card->Variant =3D=3D QEMU_VIDEO_BOCHS); + + // + // Save original PCI attributes + // + Status =3D Private->PciIo->Attributes ( + Private->PciIo, + EfiPciIoAttributeOperationGet, + 0, + &Private->OriginalPciAttributes + ); + + if (EFI_ERROR (Status)) { + goto ClosePciIo; + } + + // + // Set new PCI attributes + // + Status =3D Private->PciIo->Attributes ( + Private->PciIo, + EfiPciIoAttributeOperationEnable, + EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_V= GA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO, + NULL + ); + if (EFI_ERROR (Status)) { + goto ClosePciIo; + } + + // + // Check whenever the qemu stdvga mmio bar is present (qemu 1.3+). + // + if (Private->Variant =3D=3D QEMU_VIDEO_BOCHS_MMIO) { + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *MmioDesc; + + Status =3D Private->PciIo->GetBarAttributes ( + Private->PciIo, + PCI_BAR_IDX2, + NULL, + (VOID**) &MmioDesc + ); + if (EFI_ERROR (Status) || + MmioDesc->ResType !=3D ACPI_ADDRESS_SPACE_TYPE_MEM) { + DEBUG ((EFI_D_INFO, "QemuVideo: No mmio bar, fallback to port io\n")= ); + Private->Variant =3D QEMU_VIDEO_BOCHS; + } else { + DEBUG ((EFI_D_INFO, "QemuVideo: Using mmio bar @ 0x%lx\n", + MmioDesc->AddrRangeMin)); + } + + if (!EFI_ERROR (Status)) { + FreePool (MmioDesc); + } + } + + // + // Check if accessing the bochs interface works. + // + if (Private->Variant =3D=3D QEMU_VIDEO_BOCHS_MMIO || + Private->Variant =3D=3D QEMU_VIDEO_BOCHS) { + UINT16 BochsId; + BochsId =3D BochsRead(Private, VBE_DISPI_INDEX_ID); + if ((BochsId & 0xFFF0) !=3D VBE_DISPI_ID0) { + DEBUG ((EFI_D_INFO, "QemuVideo: BochsID mismatch (got 0x%x)\n", Boch= sId)); + Status =3D EFI_DEVICE_ERROR; + goto RestoreAttributes; + } + } + + // + // Get ParentDevicePath + // + Status =3D gBS->HandleProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + (VOID **) &ParentDevicePath + ); + if (EFI_ERROR (Status)) { + goto RestoreAttributes; + } + + // + // Set Gop Device Path + // + ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH)); + AcpiDeviceNode.Header.Type =3D ACPI_DEVICE_PATH; + AcpiDeviceNode.Header.SubType =3D ACPI_ADR_DP; + AcpiDeviceNode.ADR =3D ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY= _TYPE_VGA, 0, 0); + SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE= _PATH)); + + Private->GopDevicePath =3D AppendDevicePathNode ( + ParentDevicePath, + (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDe= viceNode + ); + if (Private->GopDevicePath =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto RestoreAttributes; + } + + // + // Create new child handle and install the device path protocol on it. + // + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &Private->Handle, + &gEfiDevicePathProtocolGuid, + Private->GopDevicePath, + NULL + ); + if (EFI_ERROR (Status)) { + goto FreeGopDevicePath; + } + + // + // Construct video mode buffer + // + switch (Private->Variant) { + case QEMU_VIDEO_CIRRUS_5430: + case QEMU_VIDEO_CIRRUS_5446: + Status =3D QemuVideoCirrusModeSetup (Private); + break; + case QEMU_VIDEO_BOCHS_MMIO: + case QEMU_VIDEO_BOCHS: + Status =3D QemuVideoBochsModeSetup (Private, IsQxl); + break; + default: + ASSERT (FALSE); + Status =3D EFI_DEVICE_ERROR; + break; + } + if (EFI_ERROR (Status)) { + goto UninstallGopDevicePath; + } + + // + // Start the GOP software stack. + // + Status =3D QemuVideoGraphicsOutputConstructor (Private); + if (EFI_ERROR (Status)) { + goto FreeModeData; + } + + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &Private->Handle, + &gEfiGraphicsOutputProtocolGuid, + &Private->GraphicsOutput, + NULL + ); + if (EFI_ERROR (Status)) { + goto DestructQemuVideoGraphics; + } + + // + // Reference parent handle from child handle. + // + Status =3D gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &ChildPciIo, + This->DriverBindingHandle, + Private->Handle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + if (EFI_ERROR (Status)) { + goto UninstallGop; + } + +#if defined MDE_CPU_IA32 || defined MDE_CPU_X64 + if (Private->Variant =3D=3D QEMU_VIDEO_BOCHS_MMIO || + Private->Variant =3D=3D QEMU_VIDEO_BOCHS) { + InstallVbeShim (Card->Name, Private->GraphicsOutput.Mode->FrameBufferB= ase); + } +#endif + + gBS->RestoreTPL (OldTpl); + return EFI_SUCCESS; + +UninstallGop: + gBS->UninstallProtocolInterface (Private->Handle, + &gEfiGraphicsOutputProtocolGuid, &Private->GraphicsOutput); + +DestructQemuVideoGraphics: + QemuVideoGraphicsOutputDestructor (Private); + +FreeModeData: + FreePool (Private->ModeData); + +UninstallGopDevicePath: + gBS->UninstallProtocolInterface (Private->Handle, + &gEfiDevicePathProtocolGuid, Private->GopDevicePath); + +FreeGopDevicePath: + FreePool (Private->GopDevicePath); + +RestoreAttributes: + Private->PciIo->Attributes (Private->PciIo, EfiPciIoAttributeOperationSe= t, + Private->OriginalPciAttributes, NULL); + +ClosePciIo: + gBS->CloseProtocol (Controller, &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, Controller); + +FreePrivate: + FreePool (Private); + +RestoreTpl: + gBS->RestoreTPL (OldTpl); + + return Status; +} + +/** + Stop this device + + @param This The USB bus driver binding protocol. + @param Controller The controller to release. + @param NumberOfChildren The number of children of this device that + opened the controller BY_CHILD. + @param ChildHandleBuffer The array of child handle. + + @retval EFI_SUCCESS The controller or children are stopped. + @retval EFI_DEVICE_ERROR Failed to stop the driver. + +**/ +EFI_STATUS +EFIAPI +QemuVideoControllerDriverStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +{ + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; + + EFI_STATUS Status; + QEMU_VIDEO_PRIVATE_DATA *Private; + + if (NumberOfChildren =3D=3D 0) { + // + // Close the PCI I/O Protocol + // + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + return EFI_SUCCESS; + } + + // + // free all resources for whose access we need the child handle, because= the + // child handle is going away + // + ASSERT (NumberOfChildren =3D=3D 1); + Status =3D gBS->OpenProtocol ( + ChildHandleBuffer[0], + &gEfiGraphicsOutputProtocolGuid, + (VOID **) &GraphicsOutput, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get our private context information + // + Private =3D QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (GraphicsO= utput); + ASSERT (Private->Handle =3D=3D ChildHandleBuffer[0]); + + QemuVideoGraphicsOutputDestructor (Private); + // + // Remove the GOP protocol interface from the system + // + Status =3D gBS->UninstallMultipleProtocolInterfaces ( + Private->Handle, + &gEfiGraphicsOutputProtocolGuid, + &Private->GraphicsOutput, + NULL + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Restore original PCI attributes + // + Private->PciIo->Attributes ( + Private->PciIo, + EfiPciIoAttributeOperationSet, + Private->OriginalPciAttributes, + NULL + ); + + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Private->Handle + ); + + FreePool (Private->ModeData); + gBS->UninstallProtocolInterface (Private->Handle, + &gEfiDevicePathProtocolGuid, Private->GopDevicePath); + FreePool (Private->GopDevicePath); + + // + // Free our instance data + // + gBS->FreePool (Private); + + return EFI_SUCCESS; +} + +/** + TODO: Add function description + + @param Private TODO: add argument description + @param Address TODO: add argument description + @param Data TODO: add argument description + + TODO: add return values + +**/ +VOID +outb ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINTN Address, + UINT8 Data + ) +{ + EFI_STATUS Status; + VOID *Interface; + Private->PciIo->Io.Write ( + Private->PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + Address, + 1, + &Data + ); + Status =3D gBS->LocateProtocol(&gEfiDxeSmmReadyToLockProtocolGuid, NULL,= &Interface); + if (!EFI_ERROR(Status)) { + return; + } + + Status =3D S3BootScriptSaveIoWrite( + S3BootScriptWidthUint8, + Address, + (UINTN)1, + &Data + ); +} + +/** + TODO: Add function description + + @param Private TODO: add argument description + @param Address TODO: add argument description + @param Data TODO: add argument description + + TODO: add return values + +**/ +VOID +outw ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINTN Address, + UINT16 Data + ) +{ + EFI_STATUS Status; + VOID *Interface; + + Private->PciIo->Io.Write ( + Private->PciIo, + EfiPciIoWidthUint16, + EFI_PCI_IO_PASS_THROUGH_BAR, + Address, + 1, + &Data + ); + + Status =3D gBS->LocateProtocol(&gEfiDxeSmmReadyToLockProtocolGuid, NULL,= &Interface); + if (!EFI_ERROR(Status)) { + return; + } + Status =3D S3BootScriptSaveIoWrite( + S3BootScriptWidthUint16, + Address, + 1, + &Data + ); +} + +/** + TODO: Add function description + + @param Private TODO: add argument description + @param Address TODO: add argument description + + TODO: add return values + +**/ +UINT8 +inb ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINTN Address + ) +{ + UINT8 Data; + + Private->PciIo->Io.Read ( + Private->PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + Address, + 1, + &Data + ); + return Data; +} + +/** + TODO: Add function description + + @param Private TODO: add argument description + @param Address TODO: add argument description + + TODO: add return values + +**/ +UINT16 +inw ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINTN Address + ) +{ + UINT16 Data; + + Private->PciIo->Io.Read ( + Private->PciIo, + EfiPciIoWidthUint16, + EFI_PCI_IO_PASS_THROUGH_BAR, + Address, + 1, + &Data + ); + return Data; +} + +/** + TODO: Add function description + + @param Private TODO: add argument description + @param Index TODO: add argument description + @param Red TODO: add argument description + @param Green TODO: add argument description + @param Blue TODO: add argument description + + TODO: add return values + +**/ +VOID +SetPaletteColor ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINTN Index, + UINT8 Red, + UINT8 Green, + UINT8 Blue + ) +{ + VgaOutb (Private, PALETTE_INDEX_REGISTER, (UINT8) Index); + VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8) (Red >> 2)); + VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8) (Green >> 2)); + VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8) (Blue >> 2)); +} + +/** + TODO: Add function description + + @param Private TODO: add argument description + + TODO: add return values + +**/ +VOID +SetDefaultPalette ( + QEMU_VIDEO_PRIVATE_DATA *Private + ) +{ + UINTN Index; + UINTN RedIndex; + UINTN GreenIndex; + UINTN BlueIndex; + + Index =3D 0; + for (RedIndex =3D 0; RedIndex < 8; RedIndex++) { + for (GreenIndex =3D 0; GreenIndex < 8; GreenIndex++) { + for (BlueIndex =3D 0; BlueIndex < 4; BlueIndex++) { + SetPaletteColor (Private, Index, (UINT8) (RedIndex << 5), (UINT8) = (GreenIndex << 5), (UINT8) (BlueIndex << 6)); + Index++; + } + } + } +} + +/** + TODO: Add function description + + @param Private TODO: add argument description + + TODO: add return values + +**/ +VOID +ClearScreen ( + QEMU_VIDEO_PRIVATE_DATA *Private + ) +{ + UINT32 Color; + + Color =3D 0; + Private->PciIo->Mem.Write ( + Private->PciIo, + EfiPciIoWidthFillUint32, + 0, + 0, + 0x400000 >> 2, + &Color + ); +} + +/** + TODO: Add function description + + @param Private TODO: add argument description + + TODO: add return values + +**/ +VOID +DrawLogo ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINTN ScreenWidth, + UINTN ScreenHeight + ) +{ +} + +/** + TODO: Add function description + + @param Private TODO: add argument description + @param ModeData TODO: add argument description + + TODO: add return values + +**/ +VOID +InitializeCirrusGraphicsMode ( + QEMU_VIDEO_PRIVATE_DATA *Private, + QEMU_VIDEO_CIRRUS_MODES *ModeData + ) +{ + UINT8 Byte; + UINTN Index; + + outw (Private, SEQ_ADDRESS_REGISTER, 0x1206); + outw (Private, SEQ_ADDRESS_REGISTER, 0x0012); + + for (Index =3D 0; Index < 15; Index++) { + outw (Private, SEQ_ADDRESS_REGISTER, ModeData->SeqSettings[Index]); + } + + if (Private->Variant =3D=3D QEMU_VIDEO_CIRRUS_5430) { + outb (Private, SEQ_ADDRESS_REGISTER, 0x0f); + Byte =3D (UINT8) ((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30); + outb (Private, SEQ_DATA_REGISTER, Byte); + } + + outb (Private, MISC_OUTPUT_REGISTER, ModeData->MiscSetting); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0506); + outw (Private, SEQ_ADDRESS_REGISTER, 0x0300); + outw (Private, CRTC_ADDRESS_REGISTER, 0x2011); + + for (Index =3D 0; Index < 28; Index++) { + outw (Private, CRTC_ADDRESS_REGISTER, (UINT16) ((ModeData->CrtcSetting= s[Index] << 8) | Index)); + } + + for (Index =3D 0; Index < 9; Index++) { + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((GraphicsController[I= ndex] << 8) | Index)); + } + + inb (Private, INPUT_STATUS_1_REGISTER); + + for (Index =3D 0; Index < 21; Index++) { + outb (Private, ATT_ADDRESS_REGISTER, (UINT8) Index); + outb (Private, ATT_ADDRESS_REGISTER, AttributeController[Index]); + } + + outb (Private, ATT_ADDRESS_REGISTER, 0x20); + + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0009); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x000a); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x000b); + outb (Private, DAC_PIXEL_MASK_REGISTER, 0xff); + + SetDefaultPalette (Private); + ClearScreen (Private); +} + +VOID +BochsWrite ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINT16 Reg, + UINT16 Data + ) +{ + EFI_STATUS Status; + + if (Private->Variant =3D=3D QEMU_VIDEO_BOCHS_MMIO) { + Status =3D Private->PciIo->Mem.Write ( + Private->PciIo, + EfiPciIoWidthUint16, + PCI_BAR_IDX2, + 0x500 + (Reg << 1), + 1, + &Data + ); + ASSERT_EFI_ERROR (Status); + } else { + outw (Private, VBE_DISPI_IOPORT_INDEX, Reg); + outw (Private, VBE_DISPI_IOPORT_DATA, Data); + } +} + +UINT16 +BochsRead ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINT16 Reg + ) +{ + EFI_STATUS Status; + UINT16 Data; + + if (Private->Variant =3D=3D QEMU_VIDEO_BOCHS_MMIO) { + Status =3D Private->PciIo->Mem.Read ( + Private->PciIo, + EfiPciIoWidthUint16, + PCI_BAR_IDX2, + 0x500 + (Reg << 1), + 1, + &Data + ); + ASSERT_EFI_ERROR (Status); + } else { + outw (Private, VBE_DISPI_IOPORT_INDEX, Reg); + Data =3D inw (Private, VBE_DISPI_IOPORT_DATA); + } + return Data; +} + +VOID +VgaOutb ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINTN Reg, + UINT8 Data + ) +{ + EFI_STATUS Status; + + if (Private->Variant =3D=3D QEMU_VIDEO_BOCHS_MMIO) { + Status =3D Private->PciIo->Mem.Write ( + Private->PciIo, + EfiPciIoWidthUint8, + PCI_BAR_IDX2, + 0x400 - 0x3c0 + Reg, + 1, + &Data + ); + ASSERT_EFI_ERROR (Status); + } else { + outb (Private, Reg, Data); + } +} + +VOID +InitializeBochsGraphicsMode ( + QEMU_VIDEO_PRIVATE_DATA *Private, + QEMU_VIDEO_BOCHS_MODES *ModeData + ) +{ + DEBUG ((EFI_D_INFO, "InitializeBochsGraphicsMode: %dx%d @ %d\n", + ModeData->Width, ModeData->Height, ModeData->ColorDepth)); + + /* unblank */ + VgaOutb (Private, ATT_ADDRESS_REGISTER, 0x20); + + BochsWrite (Private, VBE_DISPI_INDEX_ENABLE, 0); + BochsWrite (Private, VBE_DISPI_INDEX_BANK, 0); + BochsWrite (Private, VBE_DISPI_INDEX_X_OFFSET, 0); + BochsWrite (Private, VBE_DISPI_INDEX_Y_OFFSET, 0); + + BochsWrite (Private, VBE_DISPI_INDEX_BPP, (UINT16) ModeData->Col= orDepth); + BochsWrite (Private, VBE_DISPI_INDEX_XRES, (UINT16) ModeData->Wid= th); + BochsWrite (Private, VBE_DISPI_INDEX_VIRT_WIDTH, (UINT16) ModeData->Wid= th); + BochsWrite (Private, VBE_DISPI_INDEX_YRES, (UINT16) ModeData->Hei= ght); + BochsWrite (Private, VBE_DISPI_INDEX_VIRT_HEIGHT, (UINT16) ModeData->Hei= ght); + + BochsWrite (Private, VBE_DISPI_INDEX_ENABLE, + VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED); + + SetDefaultPalette (Private); + ClearScreen (Private); +} + +EFI_STATUS +EFIAPI +InitializeQemuVideo ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status =3D EfiLibInstallDriverBindingComponentName2 ( + ImageHandle, + SystemTable, + &gQemuVideoDriverBinding, + ImageHandle, + &gQemuVideoComponentName, + &gQemuVideoComponentName2 + ); + ASSERT_EFI_ERROR (Status); + + // + // Install EFI Driver Supported EFI Version Protocol required for + // EFI drivers that are on PCI and other plug in cards. + // + gQemuVideoDriverSupportedEfiVersion.FirmwareVersion =3D PcdGet32 (PcdDri= verSupportedEfiVersion); + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &ImageHandle, + &gEfiDriverSupportedEfiVersionProtocolGuid, + &gQemuVideoDriverSupportedEfiVersion, + NULL + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/DriverSupport= edEfiVersion.c b/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/DriverSup= portedEfiVersion.c new file mode 100644 index 0000000000..a743056382 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/DriverSupportedEfiVe= rsion.c @@ -0,0 +1,15 @@ +/** @file + Driver supported version protocol for the QEMU video driver. + + Copyright (c) 2007 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "Simics.h" + +EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL gQemuVideoDriverSupportedEfiVers= ion =3D { + sizeof (EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL), // Size of Protocol = structure. + 0 // Version number to= be filled at start up. +}; + diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/Gop.c b/Platf= orm/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/Gop.c new file mode 100644 index 0000000000..bbb82fe867 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/Gop.c @@ -0,0 +1,416 @@ +/** @file + Graphics Output Protocol functions for the QEMU video controller. + + Copyright (c) 2007 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "Simics.h" + +STATIC +VOID +QemuVideoCompleteModeInfo ( + IN QEMU_VIDEO_MODE_DATA *ModeData, + OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info + ) +{ + Info->Version =3D 0; + if (ModeData->ColorDepth =3D=3D 8) { + Info->PixelFormat =3D PixelBitMask; + Info->PixelInformation.RedMask =3D PIXEL_RED_MASK; + Info->PixelInformation.GreenMask =3D PIXEL_GREEN_MASK; + Info->PixelInformation.BlueMask =3D PIXEL_BLUE_MASK; + Info->PixelInformation.ReservedMask =3D 0; + } else if (ModeData->ColorDepth =3D=3D 24) { + Info->PixelFormat =3D PixelBitMask; + Info->PixelInformation.RedMask =3D PIXEL24_RED_MASK; + Info->PixelInformation.GreenMask =3D PIXEL24_GREEN_MASK; + Info->PixelInformation.BlueMask =3D PIXEL24_BLUE_MASK; + Info->PixelInformation.ReservedMask =3D 0; + } else if (ModeData->ColorDepth =3D=3D 32) { + DEBUG ((EFI_D_INFO, "PixelBlueGreenRedReserved8BitPerColor\n")); + Info->PixelFormat =3D PixelBlueGreenRedReserved8BitPerColor; + } + Info->PixelsPerScanLine =3D Info->HorizontalResolution; +} + + +STATIC +EFI_STATUS +QemuVideoCompleteModeData ( + IN QEMU_VIDEO_PRIVATE_DATA *Private, + OUT EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode + ) +{ + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *FrameBufDesc; + QEMU_VIDEO_MODE_DATA *ModeData; + + ModeData =3D &Private->ModeData[Mode->Mode]; + Info =3D Mode->Info; + QemuVideoCompleteModeInfo (ModeData, Info); + + Private->PciIo->GetBarAttributes ( + Private->PciIo, + 0, + NULL, + (VOID**) &FrameBufDesc + ); + + Mode->FrameBufferBase =3D FrameBufDesc->AddrRangeMin; + Mode->FrameBufferSize =3D Info->HorizontalResolution * Info->VerticalRes= olution; + Mode->FrameBufferSize =3D Mode->FrameBufferSize * ((ModeData->ColorDepth= + 7) / 8); + Mode->FrameBufferSize =3D EFI_PAGES_TO_SIZE ( + EFI_SIZE_TO_PAGES (Mode->FrameBufferSize) + ); + DEBUG ((EFI_D_INFO, "FrameBufferBase: 0x%Lx, FrameBufferSize: 0x%Lx\n", + Mode->FrameBufferBase, (UINT64)Mode->FrameBufferSize)); + + FreePool (FrameBufDesc); + return EFI_SUCCESS; +} + +// +// Graphics Output Protocol Member Functions +// +EFI_STATUS +EFIAPI +QemuVideoGraphicsOutputQueryMode ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber, + OUT UINTN *SizeOfInfo, + OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info + ) +/*++ + +Routine Description: + + Graphics Output protocol interface to query video mode + + Arguments: + This - Protocol instance pointer. + ModeNumber - The mode number to return information on. + Info - Caller allocated buffer that returns informati= on about ModeNumber. + SizeOfInfo - A pointer to the size, in bytes, of the Info b= uffer. + + Returns: + EFI_SUCCESS - Mode information returned. + EFI_BUFFER_TOO_SMALL - The Info buffer was too small. + EFI_DEVICE_ERROR - A hardware error occurred trying to retrieve t= he video mode. + EFI_NOT_STARTED - Video display is not initialized. Call SetMode= () + EFI_INVALID_PARAMETER - One of the input args was NULL. + +--*/ +{ + QEMU_VIDEO_PRIVATE_DATA *Private; + QEMU_VIDEO_MODE_DATA *ModeData; + + Private =3D QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This); + + if (Info =3D=3D NULL || SizeOfInfo =3D=3D NULL || ModeNumber >=3D This->= Mode->MaxMode) { + return EFI_INVALID_PARAMETER; + } + + *Info =3D AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION)); + if (*Info =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + *SizeOfInfo =3D sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); + + ModeData =3D &Private->ModeData[ModeNumber]; + (*Info)->HorizontalResolution =3D ModeData->HorizontalResolution; + (*Info)->VerticalResolution =3D ModeData->VerticalResolution; + QemuVideoCompleteModeInfo (ModeData, *Info); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +QemuVideoGraphicsOutputSetMode ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber + ) +/*++ + +Routine Description: + + Graphics Output protocol interface to set video mode + + Arguments: + This - Protocol instance pointer. + ModeNumber - The mode number to be set. + + Returns: + EFI_SUCCESS - Graphics mode was changed. + EFI_DEVICE_ERROR - The device had an error and could not complete the = request. + EFI_UNSUPPORTED - ModeNumber is not supported by this device. + +--*/ +{ + QEMU_VIDEO_PRIVATE_DATA *Private; + QEMU_VIDEO_MODE_DATA *ModeData; + RETURN_STATUS Status; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black; + + Private =3D QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This); + + if (ModeNumber >=3D This->Mode->MaxMode) { + return EFI_UNSUPPORTED; + } + + ModeData =3D &Private->ModeData[ModeNumber]; + + switch (Private->Variant) { + case QEMU_VIDEO_CIRRUS_5430: + case QEMU_VIDEO_CIRRUS_5446: + InitializeCirrusGraphicsMode (Private, &QemuVideoCirrusModes[ModeData-= >InternalModeIndex]); + break; + case QEMU_VIDEO_BOCHS_MMIO: + case QEMU_VIDEO_BOCHS: + InitializeBochsGraphicsMode (Private, &QemuVideoBochsModes[ModeData->I= nternalModeIndex]); + break; + default: + ASSERT (FALSE); + return EFI_DEVICE_ERROR; + } + + This->Mode->Mode =3D ModeNumber; + This->Mode->Info->HorizontalResolution =3D ModeData->HorizontalResolutio= n; + This->Mode->Info->VerticalResolution =3D ModeData->VerticalResolution; + This->Mode->SizeOfInfo =3D sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); + + QemuVideoCompleteModeData (Private, This->Mode); + + // + // Re-initialize the frame buffer configure when mode changes. + // + Status =3D FrameBufferBltConfigure ( + (VOID*) (UINTN) This->Mode->FrameBufferBase, + This->Mode->Info, + Private->FrameBufferBltConfigure, + &Private->FrameBufferBltConfigureSize + ); + if (Status =3D=3D RETURN_BUFFER_TOO_SMALL) { + // + // Frame buffer configure may be larger in new mode. + // + if (Private->FrameBufferBltConfigure !=3D NULL) { + FreePool (Private->FrameBufferBltConfigure); + } + Private->FrameBufferBltConfigure =3D + AllocatePool (Private->FrameBufferBltConfigureSize); + ASSERT (Private->FrameBufferBltConfigure !=3D NULL); + + // + // Create the configuration for FrameBufferBltLib + // + Status =3D FrameBufferBltConfigure ( + (VOID*) (UINTN) This->Mode->FrameBufferBase, + This->Mode->Info, + Private->FrameBufferBltConfigure, + &Private->FrameBufferBltConfigureSize + ); + } + ASSERT (Status =3D=3D RETURN_SUCCESS); + + // + // Per UEFI Spec, need to clear the visible portions of the output displ= ay to black. + // + ZeroMem (&Black, sizeof (Black)); + Status =3D FrameBufferBlt ( + Private->FrameBufferBltConfigure, + &Black, + EfiBltVideoFill, + 0, 0, + 0, 0, + This->Mode->Info->HorizontalResolution, This->Mode->Info->Ver= ticalResolution, + 0 + ); + ASSERT_RETURN_ERROR (Status); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +QemuVideoGraphicsOutputBlt ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL + IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta + ) +/*++ + +Routine Description: + + Graphics Output protocol instance to block transfer for CirrusLogic devi= ce + +Arguments: + + This - Pointer to Graphics Output protocol instance + BltBuffer - The data to transfer to screen + BltOperation - The operation to perform + SourceX - The X coordinate of the source for BltOperation + SourceY - The Y coordinate of the source for BltOperation + DestinationX - The X coordinate of the destination for BltOperation + DestinationY - The Y coordinate of the destination for BltOperation + Width - The width of a rectangle in the blt rectangle in pixels + Height - The height of a rectangle in the blt rectangle in pixels + Delta - Not used for EfiBltVideoFill and EfiBltVideoToVideo oper= ation. + If a Delta of 0 is used, the entire BltBuffer will be op= erated on. + If a subrectangle of the BltBuffer is used, then Delta r= epresents + the number of bytes in a row of the BltBuffer. + +Returns: + + EFI_INVALID_PARAMETER - Invalid parameter passed in + EFI_SUCCESS - Blt operation success + +--*/ +{ + EFI_STATUS Status; + EFI_TPL OriginalTPL; + QEMU_VIDEO_PRIVATE_DATA *Private; + + Private =3D QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This); + // + // We have to raise to TPL Notify, so we make an atomic write the frame = buffer. + // We would not want a timer based event (Cursor, ...) to come in while = we are + // doing this operation. + // + OriginalTPL =3D gBS->RaiseTPL (TPL_NOTIFY); + + switch (BltOperation) { + case EfiBltVideoToBltBuffer: + case EfiBltBufferToVideo: + case EfiBltVideoFill: + case EfiBltVideoToVideo: + Status =3D FrameBufferBlt ( + Private->FrameBufferBltConfigure, + BltBuffer, + BltOperation, + SourceX, + SourceY, + DestinationX, + DestinationY, + Width, + Height, + Delta + ); + break; + + default: + Status =3D EFI_INVALID_PARAMETER; + break; + } + + gBS->RestoreTPL (OriginalTPL); + + return Status; +} + +EFI_STATUS +QemuVideoGraphicsOutputConstructor ( + QEMU_VIDEO_PRIVATE_DATA *Private + ) +{ + EFI_STATUS Status; + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; + + + GraphicsOutput =3D &Private->GraphicsOutput; + GraphicsOutput->QueryMode =3D QemuVideoGraphicsOutputQueryMode; + GraphicsOutput->SetMode =3D QemuVideoGraphicsOutputSetMode; + GraphicsOutput->Blt =3D QemuVideoGraphicsOutputBlt; + + // + // Initialize the private data + // + Status =3D gBS->AllocatePool ( + EfiBootServicesData, + sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE), + (VOID **) &Private->GraphicsOutput.Mode + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D gBS->AllocatePool ( + EfiBootServicesData, + sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), + (VOID **) &Private->GraphicsOutput.Mode->Info + ); + if (EFI_ERROR (Status)) { + goto FreeMode; + } + Private->GraphicsOutput.Mode->MaxMode =3D (UINT32) Private->MaxMode; + Private->GraphicsOutput.Mode->Mode =3D GRAPHICS_OUTPUT_INVALIDE_MODE_= NUMBER; + Private->FrameBufferBltConfigure =3D NULL; + Private->FrameBufferBltConfigureSize =3D 0; + + // + // Initialize the hardware + // + Status =3D GraphicsOutput->SetMode (GraphicsOutput, 0); + if (EFI_ERROR (Status)) { + goto FreeInfo; + } + + DrawLogo ( + Private, + Private->ModeData[Private->GraphicsOutput.Mode->Mode].HorizontalResolu= tion, + Private->ModeData[Private->GraphicsOutput.Mode->Mode].VerticalResoluti= on + ); + + return EFI_SUCCESS; + +FreeInfo: + FreePool (Private->GraphicsOutput.Mode->Info); + +FreeMode: + FreePool (Private->GraphicsOutput.Mode); + Private->GraphicsOutput.Mode =3D NULL; + + return Status; +} + +EFI_STATUS +QemuVideoGraphicsOutputDestructor ( + QEMU_VIDEO_PRIVATE_DATA *Private + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +{ + if (Private->FrameBufferBltConfigure !=3D NULL) { + FreePool (Private->FrameBufferBltConfigure); + } + + if (Private->GraphicsOutput.Mode !=3D NULL) { + if (Private->GraphicsOutput.Mode->Info !=3D NULL) { + gBS->FreePool (Private->GraphicsOutput.Mode->Info); + } + gBS->FreePool (Private->GraphicsOutput.Mode); + } + + return EFI_SUCCESS; +} + + diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/Initialize.c = b/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/Initialize.c new file mode 100644 index 0000000000..c8a76636af --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/Initialize.c @@ -0,0 +1,341 @@ +/** @file + Graphics Output Protocol functions for the QEMU video controller. + + Copyright (c) 2007 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "Simics.h" + + +/// +/// Generic Attribute Controller Register Settings +/// +UINT8 AttributeController[21] =3D { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00 +}; + +/// +/// Generic Graphics Controller Register Settings +/// +UINT8 GraphicsController[9] =3D { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF +}; + +// +// 640 x 480 x 256 color @ 60 Hertz +// +UINT8 Crtc_640_480_256_60[28] =3D { + 0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe1, 0x83, 0xdf, 0x50, 0x00, 0xe7, 0x04, 0xe3, + 0xff, 0x00, 0x00, 0x22 +}; + +UINT8 Crtc_640_480_32bpp_60[28] =3D { + 0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe1, 0x83, 0xdf, 0x40, 0x00, 0xe7, 0x04, 0xe3, + 0xff, 0x00, 0x00, 0x32 +}; + +UINT16 Seq_640_480_256_60[15] =3D { + 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, + 0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e +}; + +UINT16 Seq_640_480_32bpp_60[15] =3D { + 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b, + 0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e +}; + +// +// 800 x 600 x 256 color @ 60 Hertz +// +UINT8 Crtc_800_600_256_60[28] =3D { + 0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x8C, 0x57, 0x64, 0x00, 0x5F, 0x91, 0xE3, + 0xFF, 0x00, 0x00, 0x22 +}; + +UINT8 Crtc_800_600_32bpp_60[28] =3D { + 0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x8C, 0x57, 0x90, 0x00, 0x5F, 0x91, 0xE3, + 0xFF, 0x00, 0x00, 0x32 +}; + +UINT16 Seq_800_600_256_60[15] =3D { + 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, + 0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e +}; + +UINT16 Seq_800_600_32bpp_60[15] =3D { + 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b, + 0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e +}; + +UINT8 Crtc_960_720_32bpp_60[28] =3D { + 0xA3, 0x77, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x88, 0xCF, 0xe0, 0x00, 0x00, 0x64, 0xE3, + 0xFF, 0x4A, 0x00, 0x32 +}; + +UINT16 Seq_960_720_32bpp_60[15] =3D { + 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b, + 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e +}; + +// +// 1024 x 768 x 256 color @ 60 Hertz +// +UINT8 Crtc_1024_768_256_60[28] =3D { + 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3, + 0xFF, 0x4A, 0x00, 0x22 +}; + +UINT16 Seq_1024_768_256_60[15] =3D { + 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, + 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e +}; + +// +// 1024 x 768 x 24-bit color @ 60 Hertz +// +UINT8 Crtc_1024_768_24bpp_60[28] =3D { + 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3, + 0xFF, 0x4A, 0x00, 0x32 +}; + +UINT16 Seq_1024_768_24bpp_60[15] =3D { + 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1507, 0x0008, 0x4a0b, + 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e +}; + +UINT8 Crtc_1024_768_32bpp_60[28] =3D { + 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x88, 0xFF, 0xe0, 0x00, 0x00, 0x64, 0xE3, + 0xFF, 0x4A, 0x00, 0x32 +}; + +UINT16 Seq_1024_768_32bpp_60[15] =3D { + 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b, + 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e +}; + +/// +/// Table of supported video modes +/// +QEMU_VIDEO_CIRRUS_MODES QemuVideoCirrusModes[] =3D { +// { 640, 480, 8, Crtc_640_480_256_60, Seq_640_480_256_60, 0xe3 }, +// { 800, 600, 8, Crtc_800_600_256_60, Seq_800_600_256_60, 0xef }, + { 640, 480, 32, Crtc_640_480_32bpp_60, Seq_640_480_32bpp_60, 0xef }, + { 800, 600, 32, Crtc_800_600_32bpp_60, Seq_800_600_32bpp_60, 0xef }, +// { 1024, 768, 8, Crtc_1024_768_256_60, Seq_1024_768_256_60, 0xef } + { 1024, 768, 24, Crtc_1024_768_24bpp_60, Seq_1024_768_24bpp_60, 0xef } +// { 1024, 768, 32, Crtc_1024_768_32bpp_60, Seq_1024_768_32bpp_60, 0xef } +// { 960, 720, 32, Crtc_960_720_32bpp_60, Seq_1024_768_32bpp_60, 0xef } +}; + +#define QEMU_VIDEO_CIRRUS_MODE_COUNT \ + (ARRAY_SIZE (QemuVideoCirrusModes)) + +/** + Construct the valid video modes for QemuVideo. + +**/ +EFI_STATUS +QemuVideoCirrusModeSetup ( + QEMU_VIDEO_PRIVATE_DATA *Private + ) +{ + UINT32 Index; + QEMU_VIDEO_MODE_DATA *ModeData; + QEMU_VIDEO_CIRRUS_MODES *VideoMode; + + // + // Setup Video Modes + // + Private->ModeData =3D AllocatePool ( + sizeof (Private->ModeData[0]) * QEMU_VIDEO_CIRRUS_= MODE_COUNT + ); + if (Private->ModeData =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + ModeData =3D Private->ModeData; + VideoMode =3D &QemuVideoCirrusModes[0]; + for (Index =3D 0; Index < QEMU_VIDEO_CIRRUS_MODE_COUNT; Index ++) { + ModeData->InternalModeIndex =3D Index; + ModeData->HorizontalResolution =3D VideoMode->Width; + ModeData->VerticalResolution =3D VideoMode->Height; + ModeData->ColorDepth =3D VideoMode->ColorDepth; + DEBUG ((EFI_D_INFO, + "Adding Mode %d as Cirrus Internal Mode %d: %dx%d, %d-bit\n", + (INT32) (ModeData - Private->ModeData), + ModeData->InternalModeIndex, + ModeData->HorizontalResolution, + ModeData->VerticalResolution, + ModeData->ColorDepth + )); + + ModeData ++ ; + VideoMode ++; + } + Private->MaxMode =3D ModeData - Private->ModeData; + + return EFI_SUCCESS; +} + +/// +/// Table of supported video modes +/// +QEMU_VIDEO_BOCHS_MODES QemuVideoBochsModes[] =3D { + { 640, 480, 32 }, + { 800, 480, 32 }, + { 800, 600, 32 }, + { 832, 624, 32 }, + { 960, 640, 32 }, + { 1024, 600, 32 }, + { 1024, 768, 32 }, + { 1152, 864, 32 }, + { 1152, 870, 32 }, + { 1280, 720, 32 }, + { 1280, 760, 32 }, + { 1280, 768, 32 }, + { 1280, 800, 32 }, + { 1280, 960, 32 }, + { 1280, 1024, 32 }, + { 1360, 768, 32 }, + { 1366, 768, 32 }, + { 1400, 1050, 32 }, + { 1440, 900, 32 }, + { 1600, 900, 32 }, + { 1600, 1200, 32 }, + { 1680, 1050, 32 }, + { 1920, 1080, 32 }, + { 1920, 1200, 32 }, + { 1920, 1440, 32 }, + { 2000, 2000, 32 }, + { 2048, 1536, 32 }, + { 2048, 2048, 32 }, + { 2560, 1440, 32 }, + { 2560, 1600, 32 }, + { 2560, 2048, 32 }, + { 2800, 2100, 32 }, + { 3200, 2400, 32 }, + { 3840, 2160, 32 }, + { 4096, 2160, 32 }, + { 7680, 4320, 32 }, + { 8192, 4320, 32 } +}; + +#define QEMU_VIDEO_BOCHS_MODE_COUNT \ + (ARRAY_SIZE (QemuVideoBochsModes)) + +EFI_STATUS +QemuVideoBochsModeSetup ( + QEMU_VIDEO_PRIVATE_DATA *Private, + BOOLEAN IsQxl + ) +{ + UINT32 AvailableFbSize; + UINT32 Index; + QEMU_VIDEO_MODE_DATA *ModeData; + QEMU_VIDEO_BOCHS_MODES *VideoMode; + + // + // Fetch the available framebuffer size. + // + // VBE_DISPI_INDEX_VIDEO_MEMORY_64K is expected to return the size of the + // drawable framebuffer. Up to and including qemu-2.1 however it used to + // return the size of PCI BAR 0 (ie. the full video RAM size). + // + // On stdvga the two concepts coincide with each other; the full memory = size + // is usable for drawing. + // + // On QXL however, only a leading segment, "surface 0", can be used for + // drawing; the rest of the video memory is used for the QXL guest-host + // protocol. VBE_DISPI_INDEX_VIDEO_MEMORY_64K should report the size of + // "surface 0", but since it doesn't (up to and including qemu-2.1), we + // retrieve the size of the drawable portion from a field in the QXL ROM= BAR, + // where it is also available. + // + if (IsQxl) { + UINT32 Signature; + UINT32 DrawStart; + + Signature =3D 0; + DrawStart =3D 0xFFFFFFFF; + AvailableFbSize =3D 0; + if (EFI_ERROR ( + Private->PciIo->Mem.Read (Private->PciIo, EfiPciIoWidthUint32, + PCI_BAR_IDX2, 0, 1, &Signature)) || + Signature !=3D SIGNATURE_32 ('Q', 'X', 'R', 'O') || + EFI_ERROR ( + Private->PciIo->Mem.Read (Private->PciIo, EfiPciIoWidthUint32, + PCI_BAR_IDX2, 36, 1, &DrawStart)) || + DrawStart !=3D 0 || + EFI_ERROR ( + Private->PciIo->Mem.Read (Private->PciIo, EfiPciIoWidthUint32, + PCI_BAR_IDX2, 40, 1, &AvailableFbSize))) { + DEBUG ((EFI_D_ERROR, "%a: can't read size of drawable buffer from QX= L " + "ROM\n", __FUNCTION__)); + return EFI_NOT_FOUND; + } + } else { + AvailableFbSize =3D BochsRead (Private, VBE_DISPI_INDEX_VIDEO_MEMORY_= 64K); + AvailableFbSize *=3D SIZE_64KB; + } + DEBUG ((EFI_D_INFO, "%a: AvailableFbSize=3D0x%x\n", __FUNCTION__, + AvailableFbSize)); + + // + // Setup Video Modes + // + Private->ModeData =3D AllocatePool ( + sizeof (Private->ModeData[0]) * QEMU_VIDEO_BOCHS_M= ODE_COUNT + ); + if (Private->ModeData =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + ModeData =3D Private->ModeData; + VideoMode =3D &QemuVideoBochsModes[0]; + for (Index =3D 0; Index < QEMU_VIDEO_BOCHS_MODE_COUNT; Index ++) { + UINTN RequiredFbSize; + + ASSERT (VideoMode->ColorDepth % 8 =3D=3D 0); + RequiredFbSize =3D (UINTN) VideoMode->Width * VideoMode->Height * + (VideoMode->ColorDepth / 8); + if (RequiredFbSize <=3D AvailableFbSize) { + ModeData->InternalModeIndex =3D Index; + ModeData->HorizontalResolution =3D VideoMode->Width; + ModeData->VerticalResolution =3D VideoMode->Height; + ModeData->ColorDepth =3D VideoMode->ColorDepth; + DEBUG ((EFI_D_INFO, + "Adding Mode %d as Bochs Internal Mode %d: %dx%d, %d-bit\n", + (INT32) (ModeData - Private->ModeData), + ModeData->InternalModeIndex, + ModeData->HorizontalResolution, + ModeData->VerticalResolution, + ModeData->ColorDepth + )); + + ModeData ++ ; + } + VideoMode ++; + } + Private->MaxMode =3D ModeData - Private->ModeData; + + return EFI_SUCCESS; +} + diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/VbeShim.c b/P= latform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/VbeShim.c new file mode 100644 index 0000000000..ba13e3d8e5 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/VbeShim.c @@ -0,0 +1,302 @@ +/** @file + Install a fake VGABIOS service handler (real mode Int10h) for the buggy + Windows 2008 R2 SP1 UEFI guest. + + The handler is never meant to be directly executed by a VCPU; it's there= for + the internal real mode emulator of Windows 2008 R2 SP1. + + The code is based on Ralf Brown's Interrupt List: + + + + Copyright (C) 2014, Red Hat, Inc. + Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include + +#include "Simics.h" +#include "VbeShim.h" + +#pragma pack (1) +typedef struct { + UINT16 Offset; + UINT16 Segment; +} IVT_ENTRY; +#pragma pack () + +// +// This string is displayed by Windows 2008 R2 SP1 in the Screen Resolutio= n, +// Advanced Settings dialog. It should be short. +// +STATIC CONST CHAR8 mProductRevision[] =3D "OVMF Int10h (fake)"; + +/** + Install the VBE Info and VBE Mode Info structures, and the VBE service + handler routine in the C segment. Point the real-mode Int10h interrupt v= ector + to the handler. The only advertised mode is 1024x768x32. + + @param[in] CardName Name of the video card to be exposed in the + Product Name field of the VBE Info structure= . The + parameter must originate from a + QEMU_VIDEO_CARD.Name field. + @param[in] FrameBufferBase Guest-physical base address of the video car= d's + frame buffer. +**/ +VOID +InstallVbeShim ( + IN CONST CHAR16 *CardName, + IN EFI_PHYSICAL_ADDRESS FrameBufferBase + ) +{ + EFI_PHYSICAL_ADDRESS Segment0, SegmentC, SegmentF; + UINTN Segment0Pages; + IVT_ENTRY *Int0x10; + EFI_STATUS Segment0AllocationStatus; + UINT16 HostBridgeDevId; + UINTN SegmentCPages; + VBE_INFO *VbeInfoFull; + VBE_INFO_BASE *VbeInfo; + UINT8 *Ptr; + UINTN Printed; + VBE_MODE_INFO *VbeModeInfo; + + if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & (BIT0|BIT7)) =3D=3D= BIT0) { + DEBUG (( + DEBUG_WARN, + "%a: page 0 protected, not installing VBE shim\n", + __FUNCTION__ + )); + DEBUG (( + DEBUG_WARN, + "%a: page 0 protection prevents Windows 7 from booting anyway\n", + __FUNCTION__ + )); + return; + } + + Segment0 =3D 0x00000; + SegmentC =3D 0xC0000; + SegmentF =3D 0xF0000; + + // + // Attempt to cover the real mode IVT with an allocation. This is a UEFI + // driver, hence the arch protocols have been installed previously. Among + // those, the CPU arch protocol has configured the IDT, so we can overwr= ite + // the IVT used in real mode. + // + // The allocation request may fail, eg. if LegacyBiosDxe has already run. + // + Segment0Pages =3D 1; + Int0x10 =3D (IVT_ENTRY *)(UINTN)Segment0 + 0x10; + Segment0AllocationStatus =3D gBS->AllocatePages ( + AllocateAddress, + EfiBootServicesCode, + Segment0Pages, + &Segment0 + ); + + if (EFI_ERROR (Segment0AllocationStatus)) { + EFI_PHYSICAL_ADDRESS Handler; + + // + // Check if a video BIOS handler has been installed previously -- we + // shouldn't override a real video BIOS with our shim, nor our own shi= m if + // it's already present. + // + Handler =3D (Int0x10->Segment << 4) + Int0x10->Offset; + if (Handler >=3D SegmentC && Handler < SegmentF) { + DEBUG ((EFI_D_INFO, "%a: Video BIOS handler found at %04x:%04x\n", + __FUNCTION__, Int0x10->Segment, Int0x10->Offset)); + return; + } + + // + // Otherwise we'll overwrite the Int10h vector, even though we may not= own + // the page at zero. + // + DEBUG (( + DEBUG_INFO, + "%a: failed to allocate page at zero: %r\n", + __FUNCTION__, + Segment0AllocationStatus + )); + } else { + // + // We managed to allocate the page at zero. SVN r14218 guarantees that= it + // is NUL-filled. + // + ASSERT (Int0x10->Segment =3D=3D 0x0000); + ASSERT (Int0x10->Offset =3D=3D 0x0000); + } + + HostBridgeDevId =3D PcdGet16(PcdSimicsX58HostBridgePciDevId); + switch (HostBridgeDevId) { + case INTEL_ICH10_DEVICE_ID: + break; + default: + DEBUG(( + DEBUG_ERROR, + "%a: unknown host bridge device ID: 0x%04x\n", + __FUNCTION__, + HostBridgeDevId + )); + ASSERT (FALSE); + + if (!EFI_ERROR(Segment0AllocationStatus)) { + gBS->FreePages(Segment0, Segment0Pages); + } + return; + } + // + // low nibble covers 0xC0000 to 0xC3FFF + // high nibble covers 0xC4000 to 0xC7FFF + // bit1 in each nibble is Write Enable + // bit0 in each nibble is Read Enable + // + + // + // We never added memory space during PEI or DXE for the C segment, so we + // don't need to (and can't) allocate from there. Also, guest operating + // systems will see a hole in the UEFI memory map there. + // + SegmentCPages =3D 4; + + ASSERT (sizeof mVbeShim <=3D EFI_PAGES_TO_SIZE (SegmentCPages)); + CopyMem ((VOID *)(UINTN)SegmentC, mVbeShim, sizeof mVbeShim); + + // + // Fill in the VBE INFO structure. + // + VbeInfoFull =3D (VBE_INFO *)(UINTN)SegmentC; + VbeInfo =3D &VbeInfoFull->Base; + Ptr =3D VbeInfoFull->Buffer; + + CopyMem (VbeInfo->Signature, "VESA", 4); + VbeInfo->VesaVersion =3D 0x0300; + + VbeInfo->OemNameAddress =3D (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr; + CopyMem (Ptr, "QEMU", 5); + Ptr +=3D 5; + + VbeInfo->Capabilities =3D BIT0; // DAC can be switched into 8-bit mode + + VbeInfo->ModeListAddress =3D (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr; + *(UINT16*)Ptr =3D 0x00f1; // mode number + Ptr +=3D 2; + *(UINT16*)Ptr =3D 0xFFFF; // mode list terminator + Ptr +=3D 2; + + VbeInfo->VideoMem64K =3D (UINT16)((1024 * 768 * 4 + 65535) / 65536); + VbeInfo->OemSoftwareVersion =3D 0x0000; + + VbeInfo->VendorNameAddress =3D (UINT32)SegmentC << 12 | (UINT16)(UINTN)P= tr; + CopyMem (Ptr, "OVMF", 5); + Ptr +=3D 5; + + VbeInfo->ProductNameAddress =3D (UINT32)SegmentC << 12 | (UINT16)(UINTN)= Ptr; + Printed =3D AsciiSPrint ((CHAR8 *)Ptr, + sizeof VbeInfoFull->Buffer - (Ptr - VbeInfoFull->Buffer), "%= s", + CardName); + Ptr +=3D Printed + 1; + + VbeInfo->ProductRevAddress =3D (UINT32)SegmentC << 12 | (UINT16)(UINTN)P= tr; + CopyMem (Ptr, mProductRevision, sizeof mProductRevision); + Ptr +=3D sizeof mProductRevision; + + ASSERT (sizeof VbeInfoFull->Buffer >=3D Ptr - VbeInfoFull->Buffer); + ZeroMem (Ptr, sizeof VbeInfoFull->Buffer - (Ptr - VbeInfoFull->Buffer)); + + // + // Fil in the VBE MODE INFO structure. + // + VbeModeInfo =3D (VBE_MODE_INFO *)(VbeInfoFull + 1); + + // + // bit0: mode supported by present hardware configuration + // bit1: optional information available (must be =3D1 for VBE v1.2+) + // bit3: set if color, clear if monochrome + // bit4: set if graphics mode, clear if text mode + // bit5: mode is not VGA-compatible + // bit7: linear framebuffer mode supported + // + VbeModeInfo->ModeAttr =3D BIT7 | BIT5 | BIT4 | BIT3 | BIT1 | BIT0; + + // + // bit0: exists + // bit1: bit1: readable + // bit2: writeable + // + VbeModeInfo->WindowAAttr =3D BIT2 | BIT1 | BIT0; + + VbeModeInfo->WindowBAttr =3D 0x00; + VbeModeInfo->WindowGranularityKB =3D 0x0040; + VbeModeInfo->WindowSizeKB =3D 0x0040; + VbeModeInfo->WindowAStartSegment =3D 0xA000; + VbeModeInfo->WindowBStartSegment =3D 0x0000; + VbeModeInfo->WindowPositioningAddress =3D 0x0000; + VbeModeInfo->BytesPerScanLine =3D 1024 * 4; + + VbeModeInfo->Width =3D 1024; + VbeModeInfo->Height =3D 768; + VbeModeInfo->CharCellWidth =3D 8; + VbeModeInfo->CharCellHeight =3D 16; + VbeModeInfo->NumPlanes =3D 1; + VbeModeInfo->BitsPerPixel =3D 32; + VbeModeInfo->NumBanks =3D 1; + VbeModeInfo->MemoryModel =3D 6; // direct color + VbeModeInfo->BankSizeKB =3D 0; + VbeModeInfo->NumImagePagesLessOne =3D 0; + VbeModeInfo->Vbe3 =3D 0x01; + + VbeModeInfo->RedMaskSize =3D 8; + VbeModeInfo->RedMaskPos =3D 16; + VbeModeInfo->GreenMaskSize =3D 8; + VbeModeInfo->GreenMaskPos =3D 8; + VbeModeInfo->BlueMaskSize =3D 8; + VbeModeInfo->BlueMaskPos =3D 0; + VbeModeInfo->ReservedMaskSize =3D 8; + VbeModeInfo->ReservedMaskPos =3D 24; + + // + // bit1: Bytes in reserved field may be used by application + // + VbeModeInfo->DirectColorModeInfo =3D BIT1; + + VbeModeInfo->LfbAddress =3D (UINT32)FrameBufferBase; + VbeModeInfo->OffScreenAddress =3D 0; + VbeModeInfo->OffScreenSizeKB =3D 0; + + VbeModeInfo->BytesPerScanLineLinear =3D 1024 * 4; + VbeModeInfo->NumImagesLessOneBanked =3D 0; + VbeModeInfo->NumImagesLessOneLinear =3D 0; + VbeModeInfo->RedMaskSizeLinear =3D 8; + VbeModeInfo->RedMaskPosLinear =3D 16; + VbeModeInfo->GreenMaskSizeLinear =3D 8; + VbeModeInfo->GreenMaskPosLinear =3D 8; + VbeModeInfo->BlueMaskSizeLinear =3D 8; + VbeModeInfo->BlueMaskPosLinear =3D 0; + VbeModeInfo->ReservedMaskSizeLinear =3D 8; + VbeModeInfo->ReservedMaskPosLinear =3D 24; + VbeModeInfo->MaxPixelClockHz =3D 0; + + ZeroMem (VbeModeInfo->Reserved, sizeof VbeModeInfo->Reserved); + + // + // Clear Write Enable (bit1), keep Read Enable (bit0) set + // + + // + // Second, point the Int10h vector at the shim. + // + Int0x10->Segment =3D (UINT16) ((UINT32)SegmentC >> 4); + Int0x10->Offset =3D (UINT16) ((UINTN) (VbeModeInfo + 1) - SegmentC); + + DEBUG ((EFI_D_INFO, "%a: VBE shim installed\n", __FUNCTION__)); +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf b/= Platform/Intel/SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf new file mode 100644 index 0000000000..b8d326cdb6 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf @@ -0,0 +1,31 @@ +## @file +# Component description file for PlatformAcpiTables module. +# +# ACPI table data and ASL sources required to boot the platform. +# +# Copyright (c) 2008 - 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D PlatformAcpiTables + FILE_GUID =3D 7E374E25-8E01-4FEE-87F2-390C23C606CD + MODULE_TYPE =3D USER_DEFINED + VERSION_STRING =3D 1.0 + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC +# + +[Sources] + Platform.h + Dsdt.asl + +[Packages] + MdePkg/MdePkg.dec + diff --git a/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl b/Platfo= rm/Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl new file mode 100644 index 0000000000..8a6c3792ba --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl @@ -0,0 +1,821 @@ +/** @file + Contains root level name space objects for the platform + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +DefinitionBlock ("Dsdt.aml", "DSDT", 1, "INTEL ", "SIMICS ", 4) { + // + // System Sleep States + // + Name (\_S3, Package () {5, 5, 0, 0}) + Name (\_S4, Package () {6, 6, 0, 0}) + Name (\_S5, Package () {7, 7, 0, 0}) + + Name (GPIC, Zero) + Method (_PIC, 1, NotSerialized) // _PIC: Interrupt Model + { + GPIC =3D Arg0 + } + // + // System Bus + // + Scope (\_SB) { + // + // PCI Root Bridge + // + Device (PCI0) { + Name (_HID, EISAID ("PNP0A03")) + Name (_ADR, 0x00000000) + Name (_BBN, 0x00) + Name (_UID, 0x00) + + + // Current resource settings + Name (_CRS, ResourceTemplate () { + WORDBusNumber ( // Bus number resource (0); the bridge pr= oduces bus numbers for its subsequent buses + ResourceProducer, // bit 0 of general flags is 1 + MinFixed, // Range is fixed + MaxFixed, // Range is fixed + PosDecode, // PosDecode + 0x0000, // Granularity + 0x0000, // Min + 0x00FF, // Max + 0x0000, // Translation + 0x0100 // Range Length =3D Max-Min+1 + ) + + IO (Decode16, 0xCF8, 0xCF8, 0x01, 0x08) //Consumed resource = (0xCF8-0xCFF) + + WORDIO ( // Consumed-and-produced resource (all I/= O below CF8) + ResourceProducer, // bit 0 of general flags is 0 + MinFixed, // Range is fixed + MaxFixed, // Range is fixed + PosDecode, + EntireRange, + 0x0000, // Granularity + 0x0000, // Min + 0x0CF7, // Max + 0x0000, // Translation + 0x0CF8 // Range Length + ) + + WORDIO ( // Consumed-and-produced resource (all I/= O above CFF) + ResourceProducer, // bit 0 of general flags is 0 + MinFixed, // Range is fixed + MaxFixed, // Range is fixed + PosDecode, + EntireRange, + 0x0000, // Granularity + 0x0D00, // Min + 0xFFFF, // Max + 0x0000, // Translation + 0xF300 // Range Length + ) + + DWORDMEMORY ( // Descriptor for legacy VGA video RAM + ResourceProducer, // bit 0 of general flags is 0 + PosDecode, + MinFixed, // Range is fixed + MaxFixed, // Range is Fixed + Cacheable, + ReadWrite, + 0x00000000, // Granularity + 0x000A0000, // Min + 0x000BFFFF, // Max + 0x00000000, // Translation + 0x00020000 // Range Length + ) + + DWORDMEMORY ( // Descriptor for 32-bit MMIO + ResourceProducer, // bit 0 of general flags is 0 + PosDecode, + MinFixed, // Range is fixed + MaxFixed, // Range is Fixed + NonCacheable, + ReadWrite, + 0x00000000, // Granularity + 0xF0000000, // Min + 0xFBFFFFFF, // Max + 0x00000000, // Translation + 0x0C000000, // Range Length + , // ResourceSourceIndex + , // ResourceSource + PW32 // DescriptorName + ) + }) + + // + // PCI Interrupt Routing Table - PIC Mode Only + // + // If you change the IRQ mapping here you also need + // to change the mapping in the south bridge + // (pci-conf.py) and in the BIOS. + // INTA -> 0xa (10) + // INTB -> 0xb (11) + // INTC -> 0xa (10) + // INTD -> 0xb (11) + + Method (_PRT, 0, NotSerialized) { + If (GPIC) { + Return (AR00) // APIC Mode + } + Return (PR00) // PIC Mode + } + + Name (PR00, Package(){ + Package () {0x000FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x000FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x000FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x000FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + // + // Bus 0, Device 1 + // + Package () {0x0001FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0001FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0001FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0001FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0002FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0002FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0002FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0002FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + // + // Bus 0, Device 3 + // + Package () {0x0003FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0003FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0003FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0003FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0004FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0004FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0004FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0004FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0005FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0005FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0005FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0005FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0006FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0006FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0006FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0006FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0007FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0007FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0007FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0007FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0008FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0008FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0008FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0008FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0009FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0009FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0009FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0009FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x000AFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x000AFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x000AFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x000AFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x000BFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x000BFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x000BFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x000BFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x000CFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x000CFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x000CFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x000CFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x000DFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x000DFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x000DFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x000DFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x000EFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x000EFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x000EFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x000EFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x000FFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x000FFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x000FFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x000FFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x00010FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x00010FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x00010FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x00010FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x00011FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x00011FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x00011FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x00011FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x00012FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x00012FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x00012FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x00012FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x00013FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x00013FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x00013FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x00013FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x00014FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x00014FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x00014FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x00014FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x00015FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x00015FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x00015FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x00015FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x00016FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x00016FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x00016FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x00016FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x00017FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x00017FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x00017FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x00017FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x00018FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x00018FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x00018FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x00018FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0001EFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0001EFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0001EFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0001EFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x00019FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x00019FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x00019FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x00019FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0001AFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0001AFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0001AFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0001AFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0001BFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0001BFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0001BFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0001BFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0001CFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0001CFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0001CFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0001CFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0001DFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0001DFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0001DFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0001DFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + + Package () {0x0001FFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00}, + Package () {0x0001FFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00}, + Package () {0x0001FFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00}, + Package () {0x0001FFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00}, + } + ) + + Name(AR00, Package(){ + + Package () {0x000FFFF, 0x00, 0, 16}, + Package () {0x000FFFF, 0x01, 0, 17}, + Package () {0x000FFFF, 0x02, 0, 18}, + Package () {0x000FFFF, 0x03, 0, 19}, + + // + // Bus 0, Device 1 + // + Package () {0x0001FFFF, 0x00, 0, 16}, + Package () {0x0001FFFF, 0x01, 0, 17}, + Package () {0x0001FFFF, 0x02, 0, 18}, + Package () {0x0001FFFF, 0x03, 0, 19}, + + Package () {0x0002FFFF, 0x00, 0, 16}, + Package () {0x0002FFFF, 0x01, 0, 17}, + Package () {0x0002FFFF, 0x02, 0, 18}, + Package () {0x0002FFFF, 0x03, 0, 19}, + // + // Bus 0, Device 3 + // + Package () {0x0003FFFF, 0x00, 0, 16}, + Package () {0x0003FFFF, 0x01, 0, 17}, + Package () {0x0003FFFF, 0x02, 0, 18}, + Package () {0x0003FFFF, 0x03, 0, 19}, + + Package () {0x0004FFFF, 0x00, 0, 16}, + Package () {0x0004FFFF, 0x01, 0, 17}, + Package () {0x0004FFFF, 0x02, 0, 18}, + Package () {0x0004FFFF, 0x03, 0, 19}, + + Package () {0x0005FFFF, 0x00, 0, 16}, + Package () {0x0005FFFF, 0x01, 0, 17}, + Package () {0x0005FFFF, 0x02, 0, 18}, + Package () {0x0005FFFF, 0x03, 0, 19}, + + Package () {0x0006FFFF, 0x00, 0, 16}, + Package () {0x0006FFFF, 0x01, 0, 17}, + Package () {0x0006FFFF, 0x02, 0, 18}, + Package () {0x0006FFFF, 0x03, 0, 19}, + + Package () {0x0007FFFF, 0x00, 0, 16}, + Package () {0x0007FFFF, 0x01, 0, 17}, + Package () {0x0007FFFF, 0x02, 0, 18}, + Package () {0x0007FFFF, 0x03, 0, 19}, + + Package () {0x0008FFFF, 0x00, 0, 16}, + Package () {0x0008FFFF, 0x01, 0, 17}, + Package () {0x0008FFFF, 0x02, 0, 18}, + Package () {0x0008FFFF, 0x03, 0, 19}, + + Package () {0x0009FFFF, 0x00, 0, 16}, + Package () {0x0009FFFF, 0x01, 0, 17}, + Package () {0x0009FFFF, 0x02, 0, 18}, + Package () {0x0009FFFF, 0x03, 0, 19}, + + Package () {0x000AFFFF, 0x00, 0, 16}, + Package () {0x000AFFFF, 0x01, 0, 17}, + Package () {0x000AFFFF, 0x02, 0, 18}, + Package () {0x000AFFFF, 0x03, 0, 19}, + + Package () {0x000BFFFF, 0x00, 0, 16}, + Package () {0x000BFFFF, 0x01, 0, 17}, + Package () {0x000BFFFF, 0x02, 0, 18}, + Package () {0x000BFFFF, 0x03, 0, 19}, + + Package () {0x000CFFFF, 0x00, 0, 16}, + Package () {0x000CFFFF, 0x01, 0, 17}, + Package () {0x000CFFFF, 0x02, 0, 18}, + Package () {0x000CFFFF, 0x03, 0, 19}, + + Package () {0x000DFFFF, 0x00, 0, 16}, + Package () {0x000DFFFF, 0x01, 0, 17}, + Package () {0x000DFFFF, 0x02, 0, 18}, + Package () {0x000DFFFF, 0x03, 0, 19}, + + Package () {0x000EFFFF, 0x00, 0, 16}, + Package () {0x000EFFFF, 0x01, 0, 17}, + Package () {0x000EFFFF, 0x02, 0C, 18}, + Package () {0x000EFFFF, 0x03, 0, 19}, + + Package () {0x000FFFFF, 0x00, 0, 16}, + Package () {0x000FFFFF, 0x01, 0, 17}, + Package () {0x000FFFFF, 0x02, 0, 18}, + Package () {0x000FFFFF, 0x03, 0, 19}, + + Package () {0x00010FFFF, 0x00, 0, 16}, + Package () {0x00010FFFF, 0x01, 0, 17}, + Package () {0x00010FFFF, 0x02, 0, 18}, + Package () {0x00010FFFF, 0x03, 0, 19}, + + Package () {0x00011FFFF, 0x00, 0, 16}, + Package () {0x00011FFFF, 0x01, 0, 17}, + Package () {0x00011FFFF, 0x02, 0, 18}, + Package () {0x00011FFFF, 0x03, 0, 19}, + + Package () {0x00012FFFF, 0x00, 0, 16}, + Package () {0x00012FFFF, 0x01, 0, 17}, + Package () {0x00012FFFF, 0x02, 0, 18}, + Package () {0x00012FFFF, 0x03, 0, 19}, + + Package () {0x00013FFFF, 0x00, 0, 16}, + Package () {0x00013FFFF, 0x01, 0, 17}, + Package () {0x00013FFFF, 0x02, 0, 18}, + Package () {0x00013FFFF, 0x03, 0, 19}, + + Package () {0x00014FFFF, 0x00, 0, 16}, + Package () {0x00014FFFF, 0x01, 0, 17}, + Package () {0x00014FFFF, 0x02, 0, 18}, + Package () {0x00014FFFF, 0x03, 0, 19}, + + Package () {0x00015FFFF, 0x00, 0, 16}, + Package () {0x00015FFFF, 0x01, 0, 17}, + Package () {0x00015FFFF, 0x02, 0, 18}, + Package () {0x00015FFFF, 0x03, 0, 19}, + + Package () {0x00016FFFF, 0x00, 0, 16}, + Package () {0x00016FFFF, 0x01, 0, 17}, + Package () {0x00016FFFF, 0x02, 0, 18}, + Package () {0x00016FFFF, 0x03, 0, 19}, + + Package () {0x00017FFFF, 0x00, 0, 16}, + Package () {0x00017FFFF, 0x01, 0, 17}, + Package () {0x00017FFFF, 0x02, 0, 18}, + Package () {0x00017FFFF, 0x03, 0, 19}, + + Package () {0x00018FFFF, 0x00, 0, 16}, + Package () {0x00018FFFF, 0x01, 0, 17}, + Package () {0x00018FFFF, 0x02, 0, 18}, + Package () {0x00018FFFF, 0x03, 0, 19}, + + Package () {0x0001EFFFF, 0x00, 0, 16}, + Package () {0x0001EFFFF, 0x01, 0, 17}, + Package () {0x0001EFFFF, 0x02, 0, 18}, + Package () {0x0001EFFFF, 0x03, 0, 19}, + + Package () {0x00019FFFF, 0x00, 0, 16}, + Package () {0x00019FFFF, 0x01, 0, 17}, + Package () {0x00019FFFF, 0x02, 0, 18}, + Package () {0x00019FFFF, 0x03, 0, 19}, + + Package () {0x0001AFFFF, 0x00, 0, 16}, + Package () {0x0001AFFFF, 0x01, 0, 17}, + Package () {0x0001AFFFF, 0x02, 0, 18}, + Package () {0x0001AFFFF, 0x03, 0, 19}, + + Package () {0x0001BFFFF, 0x00, 0, 16}, + Package () {0x0001BFFFF, 0x01, 0, 17}, + Package () {0x0001BFFFF, 0x02, 0, 18}, + Package () {0x0001BFFFF, 0x03, 0, 19}, + + Package () {0x0001CFFFF, 0x00, 0, 16}, + Package () {0x0001CFFFF, 0x01, 0, 17}, + Package () {0x0001CFFFF, 0x02, 0, 18}, + Package () {0x0001CFFFF, 0x03, 0, 19}, + + Package () {0x0001DFFFF, 0x00, 0, 16}, + Package () {0x0001DFFFF, 0x01, 0, 17}, + Package () {0x0001DFFFF, 0x02, 0, 18}, + Package () {0x0001DFFFF, 0x03, 0, 19}, + + Package () {0x0001FFFFF, 0x00, 0, 16}, + Package () {0x0001FFFFF, 0x01, 0, 17}, + Package () {0x0001FFFFF, 0x02, 0, 18}, + Package () {0x0001FFFFF, 0x03, 0, 19}, + } + ) + + // + // PCI to ISA Bridge (Bus 0, Device 7, Function 0) + // + Device (LPC) { + Name (_ADR, 0x001F0000) + + // + // PCI Interrupt Routing Configuration Registers + // + OperationRegion (PRR0, PCI_Config, 0x60, 0x0C) + Field (PRR0, ANYACC, NOLOCK, PRESERVE) { + PIRA, 8, + PIRB, 8, + PIRC, 8, + PIRD, 8, + Offset (0x04), + PIRE, 8, + PIRF, 8, + PIRG, 8, + PIRH, 8 + } + + // + // _STA method for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH + // + Method (PSTA, 1, NotSerialized) { + If (And (Arg0, 0x80)) { + Return (0x9) + } Else { + Return (0xB) + } + } + + // + // _DIS method for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH + // + Method (PDIS, 1, NotSerialized) { + Or (Arg0, 0x80, Arg0) + } + + // + // _CRS method for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH + // + Method (PCRS, 1, NotSerialized) { + Name (BUF0, ResourceTemplate () {IRQ (Level, ActiveLow, Shared){= 0}}) + // + // Define references to buffer elements + // + CreateWordField (BUF0, 0x01, IRQW) // IRQ low + // + // Write current settings into IRQ descriptor + // + If (And (Arg0, 0x80)) { + Store (Zero, Local0) + } Else { + Store (One, Local0) + } + // + // Shift 1 by value in register 70 + // + ShiftLeft (Local0, And (Arg0, 0x0F), IRQW) // Save in buffer + Return (BUF0) // Return Buf0 + } + + // + // _PRS resource for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH + // + Name (PPRS, ResourceTemplate () { + IRQ (Level, ActiveLow, Shared) {3, 4, 5, 7, 9, 10, 11, 12, 14, 1= 5} + }) + + // + // _SRS method for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH + // + Method (PSRS, 2, NotSerialized) { + CreateWordField (Arg1, 0x01, IRQW) // IRQ low + FindSetRightBit (IRQW, Local0) // Set IRQ + If (LNotEqual (IRQW, Zero)) { + And (Local0, 0x7F, Local0) + Decrement (Local0) + } Else { + Or (Local0, 0x80, Local0) + } + Store (Local0, Arg0) + } + + // + // PCI IRQ Link A + // + Device (LNKA) { + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 1) + + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRA)) } + Method (_DIS, 0, NotSerialized) { PDIS (PIRA) } + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRA)) } + Method (_PRS, 0, NotSerialized) { Return (PPRS) } + Method (_SRS, 1, NotSerialized) { PSRS (PIRA, Arg0) } + } + + // + // PCI IRQ Link B + // + Device (LNKB) { + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 2) + + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRB)) } + Method (_DIS, 0, NotSerialized) { PDIS (PIRB) } + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRB)) } + Method (_PRS, 0, NotSerialized) { Return (PPRS) } + Method (_SRS, 1, NotSerialized) { PSRS (PIRB, Arg0) } + } + + // + // PCI IRQ Link C + // + Device (LNKC) { + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 3) + + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRC)) } + Method (_DIS, 0, NotSerialized) { PDIS (PIRC) } + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRC)) } + Method (_PRS, 0, NotSerialized) { Return (PPRS) } + Method (_SRS, 1, NotSerialized) { PSRS (PIRC, Arg0) } + } + + // + // PCI IRQ Link D + // + Device (LNKD) { + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 4) + + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRD)) } + Method (_DIS, 0, NotSerialized) { PDIS (PIRD) } + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRD)) } + Method (_PRS, 0, NotSerialized) { Return (PPRS) } + Method (_SRS, 1, NotSerialized) { PSRS (PIRD, Arg0) } + } + + // + // PCI IRQ Link E + // + Device (LNKE) { + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 5) + + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRE)) } + Method (_DIS, 0, NotSerialized) { PDIS (PIRE) } + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRE)) } + Method (_PRS, 0, NotSerialized) { Return (PPRS) } + Method (_SRS, 1, NotSerialized) { PSRS (PIRE, Arg0) } + } + + // + // PCI IRQ Link F + // + Device (LNKF) { + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 6) + + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRF)) } + Method (_DIS, 0, NotSerialized) { PDIS (PIRF) } + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRF)) } + Method (_PRS, 0, NotSerialized) { Return (PPRS) } + Method (_SRS, 1, NotSerialized) { PSRS (PIRF, Arg0) } + } + + // + // PCI IRQ Link G + // + Device (LNKG) { + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 7) + + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRG)) } + Method (_DIS, 0, NotSerialized) { PDIS (PIRG) } + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRG)) } + Method (_PRS, 0, NotSerialized) { Return (PPRS) } + Method (_SRS, 1, NotSerialized) { PSRS (PIRG, Arg0) } + } + + // + // PCI IRQ Link H + // + Device (LNKH) { + Name (_HID, EISAID("PNP0C0F")) + Name (_UID, 8) + + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRH)) } + Method (_DIS, 0, NotSerialized) { PDIS (PIRH) } + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRH)) } + Method (_PRS, 0, NotSerialized) { Return (PPRS) } + Method (_SRS, 1, NotSerialized) { PSRS (PIRH, Arg0) } + } + + // + // Programmable Interrupt Controller (PIC) + // + Device(PIC) { + Name (_HID, EISAID ("PNP0000")) + Name (_CRS, ResourceTemplate () { + IO (Decode16, 0x020, 0x020, 0x00, 0x02) + IO (Decode16, 0x0A0, 0x0A0, 0x00, 0x02) + IO (Decode16, 0x4D0, 0x4D0, 0x00, 0x02) + IRQNoFlags () {2} + }) + } + + // + // ISA DMA + // + Device (DMAC) { + Name (_HID, EISAID ("PNP0200")) + Name (_CRS, ResourceTemplate () { + IO (Decode16, 0x00, 0x00, 0, 0x10) + IO (Decode16, 0x81, 0x81, 0, 0x03) + IO (Decode16, 0x87, 0x87, 0, 0x01) + IO (Decode16, 0x89, 0x89, 0, 0x03) + IO (Decode16, 0x8f, 0x8f, 0, 0x01) + IO (Decode16, 0xc0, 0xc0, 0, 0x20) + DMA (Compatibility, NotBusMaster, Transfer8) {4} + }) + } + + // + // 8254 Timer + // + Device(TMR) { + Name(_HID,EISAID("PNP0100")) + Name(_CRS, ResourceTemplate () { + IO (Decode16, 0x40, 0x40, 0x00, 0x04) + IRQNoFlags () {0} + }) + } + + // + // Real Time Clock + // + Device (RTC) { + Name (_HID, EISAID ("PNP0B00")) + Name (_CRS, ResourceTemplate () { + IO (Decode16, 0x70, 0x70, 0x00, 0x02) + IRQNoFlags () {8} + }) + } + + // + // PCAT Speaker + // + Device(SPKR) { + Name (_HID, EISAID("PNP0800")) + Name (_CRS, ResourceTemplate () { + IO (Decode16, 0x61, 0x61, 0x01, 0x01) + }) + } + + // + // Floating Point Coprocessor + // + Device(FPU) { + Name (_HID, EISAID("PNP0C04")) + Name (_CRS, ResourceTemplate () { + IO (Decode16, 0xF0, 0xF0, 0x00, 0x10) + IRQNoFlags () {13} + }) + } + + // + // Generic motherboard devices and pieces that don't fit anywhere = else + // + Device(XTRA) { + Name (_HID, EISAID ("PNP0C02")) + Name (_UID, 0x01) + Name (_CRS, ResourceTemplate () { + IO (Decode16, 0x010, 0x010, 0x00, 0x10) + IO (Decode16, 0x022, 0x022, 0x00, 0x1E) + IO (Decode16, 0x044, 0x044, 0x00, 0x1C) + IO (Decode16, 0x062, 0x062, 0x00, 0x02) + IO (Decode16, 0x065, 0x065, 0x00, 0x0B) + IO (Decode16, 0x072, 0x072, 0x00, 0x0E) + IO (Decode16, 0x080, 0x080, 0x00, 0x01) + IO (Decode16, 0x084, 0x084, 0x00, 0x03) + IO (Decode16, 0x088, 0x088, 0x00, 0x01) + IO (Decode16, 0x08c, 0x08c, 0x00, 0x03) + IO (Decode16, 0x090, 0x090, 0x00, 0x10) + IO (Decode16, 0x0A2, 0x0A2, 0x00, 0x1E) + IO (Decode16, 0x0E0, 0x0E0, 0x00, 0x10) + IO (Decode16, 0x1E0, 0x1E0, 0x00, 0x10) + IO (Decode16, 0x160, 0x160, 0x00, 0x10) + IO (Decode16, 0x278, 0x278, 0x00, 0x08) + IO (Decode16, 0x370, 0x370, 0x00, 0x02) + IO (Decode16, 0x378, 0x378, 0x00, 0x08) + IO (Decode16, 0x400, 0x400, 0x00, 0x40) // PMBLK1 + IO (Decode16, 0x440, 0x440, 0x00, 0x10) + IO (Decode16, 0x678, 0x678, 0x00, 0x08) + IO (Decode16, 0x778, 0x778, 0x00, 0x08) + Memory32Fixed (ReadOnly, 0xFEC00000, 0x1000) // IO APIC + Memory32Fixed (ReadOnly, 0xFEE00000, 0x100000) // LAPIC + }) + } + + // + // PS/2 Keyboard and PC/AT Enhanced Keyboard 101/102 + // + Device (PS2K) { + Name (_HID, EISAID ("PNP0303")) + Name (_CID, EISAID ("PNP030B")) + Name(_CRS,ResourceTemplate() { + IO (Decode16, 0x60, 0x60, 0x00, 0x01) + IO (Decode16, 0x64, 0x64, 0x00, 0x01) + IRQNoFlags () {1} + }) + } + + // + // PS/2 Mouse and Microsoft Mouse + // + Device (PS2M) { // PS/2 stype mouse port + Name (_HID, EISAID ("PNP0F03")) + Name (_CID, EISAID ("PNP0F13")) + Name (_CRS, ResourceTemplate() { + IRQNoFlags () {12} + }) + } + + // + // UART Serial Port - COM1 + // + Device (UAR1) { + Name (_HID, EISAID ("PNP0501")) + Name (_DDN, "COM1") + Name (_UID, 0x01) + Name(_CRS,ResourceTemplate() { + IO (Decode16, 0x3F8, 0x3F8, 0x00, 0x08) + IRQ (Edge, ActiveHigh, Exclusive, ) {4} + }) + } + + // + // UART Serial Port - COM2 + // + Device (UAR2) { + Name (_HID, EISAID ("PNP0501")) + Name (_DDN, "COM2") + Name (_UID, 0x02) + Name(_CRS,ResourceTemplate() { + IO (Decode16, 0x2F8, 0x2F8, 0x00, 0x08) + IRQ (Edge, ActiveHigh, Exclusive, ) {3} + }) + } + } + } + } +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatformAcpiTa= bles/AcpiPlatform.h b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatf= ormAcpiTables/AcpiPlatform.h new file mode 100644 index 0000000000..e98aac4676 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatformAcpiTables/Ac= piPlatform.h @@ -0,0 +1,45 @@ +/** @file + This is an implementation of the ACPI platform driver. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + 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 + +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatformAcpiTa= bles/AcpiPlatform.inf b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPla= tformAcpiTables/AcpiPlatform.inf new file mode 100644 index 0000000000..7dfd0832a3 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/MinPlatformAcpiTables/Ac= piPlatform.inf @@ -0,0 +1,105 @@ +## @file +# Component information file for AcpiPlatform module +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D AcpiPlatform + FILE_GUID =3D FC90EB7A-3E0A-483C-A26C-484D36593FF4 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D InstallAcpiPlatform + +[Sources.common] + AcpiPlatform.h + AcpiPlatform.c + Fadt/Fadt.c + Facs/Facs.c + Hpet/Hpet.c + Wsmt/Wsmt.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + MinPlatformPkg/MinPlatformPkg.dec + PcAtChipsetPkg/PcAtChipsetPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + BaseLib + DebugLib + IoLib + PcdLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + BaseMemoryLib + HobLib + PciSegmentInfoLib + AslUpdateLib + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision + + gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicEnable + gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicCount + gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicIdBase + gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicAddressBase + gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicInterruptBase + gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuThreadCount + gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuCoreCount + gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuSocketCount + + gMinPlatformPkgTokenSpaceGuid.PcdFadtPreferredPmProfile + gMinPlatformPkgTokenSpaceGuid.PcdFadtIaPcBootArch + gMinPlatformPkgTokenSpaceGuid.PcdFadtFlags + + gPcAtChipsetPkgTokenSpaceGuid.PcdHpetBaseAddress + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress + gMinPlatformPkgTokenSpaceGuid.PcdPciExpressRegionLength + gMinPlatformPkgTokenSpaceGuid.PcdAcpiEnableSwSmi + gMinPlatformPkgTokenSpaceGuid.PcdAcpiDisableSwSmi + gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1AEventBlockAddress + gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1BEventBlockAddress + gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1AControlBlockAddress + gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1BControlBlockAddress + gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm2ControlBlockAddress + gMinPlatformPkgTokenSpaceGuid.PcdAcpiPmTimerBlockAddress + gMinPlatformPkgTokenSpaceGuid.PcdAcpiGpe0BlockAddress + gMinPlatformPkgTokenSpaceGuid.PcdAcpiGpe1BlockAddress + + gMinPlatformPkgTokenSpaceGuid.PcdLocalApicAddress + gMinPlatformPkgTokenSpaceGuid.PcdIoApicAddress + gMinPlatformPkgTokenSpaceGuid.PcdIoApicId + + gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber + gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuSocketCount + + gMinPlatformPkgTokenSpaceGuid.PcdWsmtProtectionFlags + +[Protocols] + gEfiAcpiTableProtocolGuid ## CONSUMES + gEfiMpServiceProtocolGuid ## CONSUMES + gEfiPciIoProtocolGuid ## CONSUMES + +[Guids] + gEfiGlobalVariableGuid ## CONSUMES + gEfiHobListGuid ## CONSUMES + gEfiEndOfDxeEventGroupGuid ## CONSUMES + +[Depex] + gEfiAcpiTableProtocolGuid AND + gEfiMpServiceProtocolGuid AND + gEfiPciRootBridgeIoProtocolGuid AND + gEfiVariableArchProtocolGuid AND + gEfiVariableWriteArchProtocolGuid + + diff --git a/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h b/Plat= form/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h new file mode 100644 index 0000000000..6a4fcb172b --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h @@ -0,0 +1,75 @@ +/** @file + Platform specific defines for constructing ACPI tables + + Copyright (c) 2013 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _ACPI_PLATFORM_H_ +#define _ACPI_PLATFORM_H_ + +#include +#include + +// +// ACPI table information used to initialize tables. +// +#define EFI_ACPI_OEM_ID 'S','I','M','I','C','S' // OEMID 6 byt= es long +#define EFI_ACPI_OEM_TABLE_ID SIGNATURE_64('S','I','M','I','C','S','T'= ,'B') // OEM table id 8 bytes long +#define EFI_ACPI_OEM_REVISION 0x02000820 +#define EFI_ACPI_CREATOR_ID SIGNATURE_32('Q','S','P',' ') +#define EFI_ACPI_CREATOR_REVISION 0x00000097 + +#define INT_MODEL 0x01 +#define SCI_INT_VECTOR 0x0009 +#define SMI_CMD_IO_PORT 0xB2 +#define ACPI_ENABLE 0x0E1 +#define ACPI_DISABLE 0x01E +#define S4BIOS_REQ 0x00 +#define PM1a_EVT_BLK 0x00000400 +#define PM1b_EVT_BLK 0x00000000 +#define PM1a_CNT_BLK 0x00000404 +#define PM1b_CNT_BLK 0x00000000 +#define PM2_CNT_BLK 0x00000450 +#define PM_TMR_BLK 0x00000408 +#define GPE0_BLK 0x00000420 +#define GPE1_BLK 0x00000000 +#define PM1_EVT_LEN 0x04 +#define PM1_CNT_LEN 0x04 +#define PM2_CNT_LEN 0x01 +#define PM_TM_LEN 0x04 +#define GPE0_BLK_LEN 0x10 +#define GPE1_BLK_LEN 0x00 +#define GPE1_BASE 0x00 +#define RESERVED 0x00 +#define P_LVL2_LAT 0x0065 +#define P_LVL3_LAT 0x03E9 +#define FLUSH_SIZE 0x0400 +#define FLUSH_STRIDE 0x0010 +#define DUTY_OFFSET 0x00 +#define DUTY_WIDTH 0x00 +#define DAY_ALRM 0x0D +#define MON_ALRM 0x00 +#define CENTURY 0x00 +#define FLAG (EFI_ACPI_2_0_WBINVD | \ + EFI_ACPI_2_0_PROC_C1 | \ + EFI_ACPI_2_0_SLP_BUTTON | \ + EFI_ACPI_2_0_RTC_S4 | \ + EFI_ACPI_2_0_RESET_REG_SUP) +#define RESET_REG 0xCF9 +#define RESET_VALUE (BIT2 | BIT1) // PIIX3 Reset CPU + System Reset + +// +// Byte-aligned IO port register block initializer for +// EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE +// +#define GAS2_IO(Base, Size) { \ + EFI_ACPI_2_0_SYSTEM_IO, /* AddressSpaceId */ \ + (Size) * 8, /* RegisterBitWidth */ \ + 0, /* RegisterBitOffset */ \ + 0, /* Reserved */ \ + (Base) /* Address */ \ + } + +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/Logo/Logo.bmp b/Platform/Int= el/SimicsOpenBoardPkg/Logo/Logo.bmp new file mode 100644 index 0000000000000000000000000000000000000000..86d7030833a096f545393735d93= 1d9f4f2fbf8c0 GIT binary patch literal 141078 zcmeHwJ9Hz-kzh@gFoN)Qu|weq&F~F*XbyPdaEHTfE*dKcjU5ohf-&!%BU8pXGG)q? zD^tc9GS`(UQ>MIoGG)r#cb?2OW$Gd_vnu0Pg~E?y>sT{Q)F&%4G9u%Xk&#)e|2h0& zn&2`0PLf>1@BjWNN&Xl7`zYzU`~UYcP5w_masS+n@=3Dv#$bm8A8pL~*ZKm9cM6#l(=3D z^C_Iaf!{aDCtrStK`$wx5>BPew+N{ zCqGF({r0EHo1gqN`6>SUDV+cGXUUiF?`J>zS@QFr|2+Bf=3Df6mP@rz$1Z-4R2|AgN^{U!O!U;dK(*MI$2^6j7hn*8;ze@*`Ox4)It zdHsE*z$*n_Dey{xR|>pR;FSWe6nLe;D+OLD@JfMK3cOO_l>)C6c%=3DZLK$`j}9J%#+ z`g{~f-@JKc$n%k3)||b2c=3D-M+LnK+A>$>;;@$vEfKfY?L=3DVAb__wxr}$K&JI&mkaS zw~kS*1G~9@9j0;vimRVfxy_Y(?c(tf7y|!~-77nSYEzvqlcpIQf^ZIl@W;O*3M7fT z!9kZ0_+7Z-@1+@3FK$(@q_Qx*CNCLHfLrh%DN_M$JaLeE@0@S|JKldEOG8tTLJSzc zYJ|Dn!`@e*DIXr+U-e-^H5^DwWD+9bE5=3D`ek8z`XKS_FDqrkua>L0^f)%(?nEBo=3DA z_fYpY?}i^&&`AMu>PnMqa+)M3U!$^re1FlY5cqf;0Cy_D)w70^J`w{D#QyQ|9Rf@{ z8kVb`(W3$AHjlEeUB&Ltb>`mu&NuNEoIQM&cK+Snc~b#~A`kH2n~2dD(13?{J;ulG z|Id&fV>kskN%9G{)3wsUdQ;W(-n%jm@Z%%a^j$>b;a#VyJ9)L?rr`_zY37>O@Q{_-78}U2meqcS?f20ZdoD)$&5I7LUsP#5!2mA zEIv!W^NqXXbtyvT1i?FFELrj6Q@p|h8in*2V;#tu|Ax1|Dk=3D1pD}m+Uwxe4Bj5U1+ zJNVDq?`cmO&E`M9W{0!H{GGAQ{1E-QX`E<5s} zixRkn@-arZCEI?0@4(@!dEW!@f%90CZ#9t*CtDBKkZs|re|+@#d>x=3DTP>&8u37Fif zP;WRXRfWgu@yZqbfd>-qeSjS!=3D`3l7Lc);J!$~z?;OIihj zxJtjk;$;D^S?~^kMG7IeoW6RCcaSk~q(8!hUi69=3D~R-0q&3OmUD4Bta0ky`-E zBMCQ&c4z~>MVXJ@dBmalpL?R*fV4s^ECYzID`MbpMsHs!vn@! z&V+3w2Pj#D`tZXJ_M-sGAqlrXPlBcONaEABVz;s4SiqS=3D@9#jn@OTgGC#?-dgT$2G z--!^SMEK$C2MRMB*}oyW&Rm32W4K0rzt017ZiRi1VxPE@+rB{(^ty{I0;YL1?!h9HEL8Lugef_t; zp{PGRq8g8|BDz@ifQQ!rNT?+7E-FwFyj#SjQa(^$Ab&|ne*?-yfnolYlQqW=3D01AB< z`2nRtKFVKgL(mTh)C&}X`>xkSc+-}ThiiC5@cGo?>P&AiC2xWXLl_@B~y zEP9hpAtG3)%foU#Ho^kTkU&H`)PUUf_74!O_alHGC?AjDQv~}Fsb9)RL?Ea%Qe=3D$y zhXSsny77dg7WC*bJj9k_&vlFfOrd>PIjS`$P>+v5YSQ(Be8ll!kPo0&7$ISGu3jg5 zXsxgbZ_sH7fPv9?AP+Yl!AUOpf$xFw@~#>p8DWL)(2C0&tEB~kMLm!50Ugba{s5Us z{jxvCJA`Zj-WP~}DDcsbfH{urt^(i(j^2?UIN(APg@+RgAQp%c031C0MSbO0qqHgqY^dWo@^!kv6Qptfgi3X1$_k|p?4zHpiv*AdsRkDKJvp4 zCm;S4$mS{S0Q*XVe}%Ys?dtt2B$q2SM)p;OAaaYNG3l=3D>gnf&eMdp2>%o z=3Dg?`O9Y^r5u=3D@fRaNGm>3J*Lli5*cdsZ`zZu8ix(;hvL#HxLPh>lAxe&{qJ{*>j-T zxp#cZ&g$A6%iSkkUSMU%B1_L+W2G?fj#&8u}NoPMCO%bpc0?=3D+K7Y}~e4JT-u0UxXixi*Gh zIGlXAVJO)1f5UnLVAmAXaT^aO;V4#6*vZF3u;&2GBU!=3D<_5-pV%C>9--mZXie*!<6 z><6ePY@xE}kwK;20D^trTk6uDd-;H-I6}j3nY4jg4Jiqz_FYR+BAt^PLs>wQ%xgJd zuaCaq3@Yg#m6nMlC-M;iZzf34d`@{+@&UT97RiyDq}mL)eTmB7g~n9&qa1%k>X+@0 zcN~L|v{hZf8oJ;_91jwI*R>1&c*9b?=3DT1I#{CK$doA3Fa^Iix*K76-7`y2AZhl_)F zV)bLZ7vzHj#VZ61{a}RWn-1Rs@HzmhX9EppRew?VhMH}q}|yOjAp>C;O~NF z#yA9O^5IJP;pZ5tf&&e%Iy_*QiUz=3D&53jF0 zKcc=3DW-=3DnYsIgn-8;)nM=3DtM>BEEq+lx0HzyEMf>5ZgNm>&-%{+g{t9lO2Z{q^IHbM` z*G@jd_yb-H_8bRQuKSk*!hmQg9d48mnp*l-*hR;_(GTAb;}3X^lo~rkeG_=3DgQvmFd zRszWjhAU^!12IrO0P{*dI4txuT(wvTk9HN9wX&Oa@)6pBRUs9z{jO#B2apT|0W}|? zx!x77g?xYoeuJO@k^{u}k%mMkCs-KkcTFw*D-AH4AdLyq#{`yxJq z3oJFpli(sous~4&?4EeHm_DjGuOLB#-H@`94++clDgch~-QR~%4a_ZXoBkCN&DZ3r zLx0rWDes|tkT7hh()H88A0i*fC8w_dRwWCehzAE9u%|Nwq zC-4Jme0K&9zj*_#et6@sD97h`1Bft&$8hRQV5CTJh>=3D)ChU0VV%=3DM_?sZo7pB8il! zkfcqrAh*6}+mGPgx`sl}189H}BH)j}54=3DQ-!r@vIu8DjAsi=3DIoj$OGsp%+4tO2xaH zJa;@A@7_U0@B0`S{^0}GNyq2N545=3Dr5@ zkjrj)I8fd-%17C`VCV#OVn=3DgIzUr~qh_csK4RSY_d;ndlYaC7aVc!^Gdi&u#13!OW z>MQpSV(@jC!L0-jJGHO$Jr0n+c2gVgoL7OqjDO^YKdv80eFcF15dl}I*Pe{sD?k7! z5mH}}AO1Exi?Bk6b&}`ncg|!jAbz&1HcgflqsAMgWu5ZvXkLWgzQ+0_rCbC5_DlMk%bIV!X|kFBR1 zizm7UGkyU6V~nr?kub~3X?K_*a#G{4K2QCisvHlxUbGZqHp3qyX$2@~O)q!gn7Ovs_On_5%t5KYXrA)Kw*tfR=3D0h7;!`leFgjd z4HR)*!k?qKx;|PdpMU`Nmq`9nK4SH*HHaGG<}M)F)eo&fP{!^FfI#fO3U8GJ@RyE} zUJ`v%LnnY2z59z#AVn*ohM`2ZaJpbbx> zG*rE|M7_Kb{9C;3I=3DgES_)5-k0$}byaR^Uc4Q02CNerd@0I7Y~b9FnOBLvs^$Bub$ z75GtN2>0>8QLFd09>41N&W(cPMa8}2T1dwt;EN-y>hPM+OPY`GqI~=3DaiQ=3D5P2+JWE z2sFmp52df1Jr61~%15vt1a~D4;RazD_EY~K`mVuIz_vJ7wtNbx|ELV^1)YHTxPg*j zsy!2&D!@~uh4<7#HX8a`rGMqPR#6e5xEH<--mY6}Hg>%NeE`ho0)ZI2=3DpyjqGw39h zn~hBQ!dK@w>v4lgFvl2l*)@{h-^Kc&-G{LsOg@mB&YlAy@H~1`Wv`9m;EDu^#kN!u zfb_#~5i}0L0Xv*_!b?0J-bKF#@)@v%Zz?`RQio6-_JvRfYVq>Qm5&$L9mc*MFCPxz zS1yiN(y#>V6f)of{DAElzd<7gfqW_;6=3D$IWudgt4>gB_Cni5t((h&&ihvPu@Japq=3D z&mCm1ukbWdpK5hL77pyY(0C$3{(k)XJ($dffm~Qa5%0${udguri&VnWpkW+fU^Ltd zr!GDWmwr~N8V^EoS89we2CYAKr(bpaoSvg~1sDOKrW`-K?*e3}G{0t%czhdxxdkLn z;X?2E*tzb=3DTLVe&?_&Md92>l_^-;+Oyb0$38r3JDi}FE~k-J01A>1G$v~}HRWUwuj zd^mL;>PEofG}s1^I4{6hK6rpw%2Uy6eV>2zwHuBKz$sSeE!q2C$%h}XeqDA>Y)NPz z*bgDZ6iG)QtRKjBD1C(#@x~DCxj!%M2lfen0D8!+$f0n9h)`Ly{jblz^77$5BIt#o zZUpS=3DfNDdy%g;t3nX5-w%2Uxd!9y9la7_@a3NS)OsT*S>AAjW3rn4dy!oEY|>IkRG zuo&KZumc(BD?Z-tJC{q9at1h7Wl3TjjrxM;}CgF>)ict z76H4z?}d)NW!+_^q!MpHoIH_IL2Q6>kf(*DgVtDpOMZL-_5&9^;iw3BN%#?h_>S~r z2MJvo3szZumimR!dJ1|+q5wj0c;&0)!=3DnV_xt`b8uA^XaXfa7>-mz+U?F)qU`1r$* zLq-o0CrAMbUMUbI$$|k9@&p{lqqVhk)-%a3`Hy~Rt6xoj-*darET&u!J5351Izz;k{r^p@OaY+?UUxi1m z`p}O`P&kOO0GHZn3=3DRTjZ^OF)1*@zMH{>i4!e4}M!3x!55npYEV+Cus6Q{32Kq;O> zb@YH<;se;#O}C&BuN*;ks~X>ORXUd7AE!G)-3U0GMpfWOG;Dm1K>SdFLoom&yayO{ zj9n|XWyQK@^G!7$nTke{{y6lNCFFkl*`fr>tq54T5S1LGnXp z)3I>>)M+HAlfq^($ExWSZaWHiQL^UG+r9r<>Xibo6nLe;D+OLD@JfMK3cOO_l>)C6 zc%{HA1zsueN`Y4jyi(wm0t9)G@`ShHvqL2)H`PbdS`Diq{I6oVn4o>>r zxL^EBMm_EHPe-@YWl=3DGrI>|@X8kd*cf*Rb?!Obi$)u4T-+gUcz=3DP!j+3dj7#q>8Hb*hUL?nGZ2%K zZ7=3D6H>z?1&;2aq<{7?m?tE3|~s#xBh^UIZ9K)@`wvuMbtj@B#^sEBl$3JH`eP9l^?w}!e1;d53|}v(s#S--u1$8 zZjBBEw{AYrAxLj!w@2J97FYf4hPG)6s(|%+dH+0aeR?+8 zLRGET#fNG=3Dpd0k(l;RuCi~034n33M)HaNoI{OZ}{cz?M{&)Qk^z^VNH?1_i$>EN~v zh8TQX%xAON{q^vPG2EXC6hb=3DMPBkyC4z>3&#iI7Sb2i;%Ir8Ofa(8n%g7`E9sQVu@ zH-HZ5@NTxs^Ss#9?jRz?-RaXcxqH#9tBNHE#7mBS)^@ap2i@W5>iXv9_I@&*v8kOJ zb259X37@oo)ugNP<@EMq@PUr}8u;NK!FB>L^?81IGnp-6KBVbbUiP0Newv=3D#*85e( zYJPX|Bxr1;+>r}(PR?&&3bctK#qG)Qbyhm453Uuf+11HY^ob+Wx-Iz5>D81@N-O3} zj&4NK;Y`&UZWQ_S#l$$TO#QwaF9m~tVSBI({H5)jxx;~mktz$=3Di_XLhaJHk9y zskD1p*H@3mkUC{Gzlb06eJ*-Df4$kDZXB?>IfjI!L%RdycZ1`5+0Rez78rETXZ8s3 z7!r~WY|jd2jgP_o7R`ToMY6$-JwRMt9hyezi9PPvkd~Xdyz29d3zzr$;u9=3DQ7DGPr z>F_+X0g^QG@2z@@`}zTB+QTr<-DEnSFP6(C#@!*${qp>@ z_u;5FNPxY#gb3nnzVL0BO?~QaEmN|ydsAmE&kx$_-i=3DjDep?qE>71NhL58~?xk4EJ z{_1@20XP6@_w?fWex}ori+nM?y*#UNDIxLN)LDx|PEmC(tq|hs+D=3Df&`e#>@hAg0B zIlVqVdD#P&&fwy9Y7*A#iDGeoHMD1SdRM07GlMUv9_Yv}tQwYArU-TiqkF43*LSPQ zH6H)DU)sSOox_{T3%ZG?hdYMoIcJExLRDl zOpc_zv)j!b$~7mSURtU*y)YSab0AOj#E7sL%aOs>&fwa_MDfDkSlygj{mTISbhm&T zn-le8dy4s`Wk}4hYjK#MQuiiSU!7U(NNY4_^^!hW-B_)8I_j&MI;VG*snnRqJ9BFU zc53y@FvU?-qC3G?)@{zjvlwZ%Qln=3DeZ6cXQOS! zJc3D5{x*gqqVLXDS`}FgDQ--k)aV;Ex6&I;XCw2oZ;wg^(sh@`^gtg5uW3ZP z+h>-BsY6-aFK$(*vW)t2uW!>Ni6y~zau}GMZI`{L8na%E+R^NIrLt?oOlm~y?-Wxx z;4|Ic>FGXg=3Do{Kz>oqy{5Pl;x=3Dd&bVyj7+~3|p-s|0DzCo=3Di z1>73Z{R%cDBRJY)O#03>;eI-AUJ$mrJ>j?**@MO1u0Gb4_N}BXZ)C@EayvSQy7#^Nd8YrtI*10h!^$)05DK!Rh&BW84>}AQ(fe*xzbLAFHpe(Ol@1 zLA{@gLG^(M;ifn*QoqB=3DdiD&fL^}1!QxH_Y9QH+s4fX}OxTz1tL#_>DNH)@b+iWLO zncXSfw-U2lClgg9XxGL4s3tO%^)K#f-Q%a1ka}g6&u-52u-g&4Gq|jsQ^@bQ4e4Gh z8Wnmx&3I^Dq^AmwTtHqo3M>|P=3DW29BD(Rfv){VU;(upUp9pe;+PPTo9Re<$#(SS+s zqE629Ti*SRF~f?>P^*S@_0VI^E9%Cjl* z3eBv+bw@Q?E5BtvkCiAjVI?$deJ4Fv{U+xlkB;HX!8=3D8}HSsWsrsWS`7violJLDb1 z{lRAE(^k3R{TsUtIiESru5?Q|DO)tDukw3}J2oMhT_Wb{$nQ6HtWbOZPFp$vS3Kb^ zKs{T+7i|NaAYR%9#WwKhVn++%wtImYOW>DG2^sQ(yjjU1Y7^^6=3D72=3D>t|kC`KFf?? zDGIpzc5^$}HNlC3cglelkc;gGA$>K!m2#tytvt3S^3s>tz^`F=3DQTGH(wItE@5&CG&XN=3DZKkbIv^z>SJ#;pb9MET3i zP+Qr&`A*8pQ>|yjk=3DF}muQrl*+X9v?U&;BsEr41KSuy3;Q+bk8s;rb8g&NeFabsMCaj!*FHeXG1$fo;;oEi}v+Bm1S^)t2XZvou zqPKVlgG9YjmEF+p69e5_>Af*!WDI|n<|YJgcMk~)V|CX*^6r&P;?-JS(#!^BOX>H0_=3Dm2gNNjLcVE3 z_rD5fh)C>Apn26DvH(gs%93Fw~1Yy7=3Dwj^4R=3D}bEiR1d(isi?^wc8E7G9}x zc5}Kmw4)tu!+3OthW}FbdjC5+6T`<$nL8+0vm%ac`efynH%@M(?Vk(engi!xb zn-HF`t1L*1P_i=3DDEFV#c+}c>m+pFC>f{=3DncAJE30F}YLNAJw7pgDtl-%B;~RA4=3DEL zd()FlkEG_*)lq)r=3D9%=3D4k}0YJjhPiT3Uvru3V|@9I-LrS=3DG2(N}=3D&Igl#uNlE41ZJ1e5 zLmH}&^e*O9nPIJ`MpTVUguLR*7tBm^No^$`5bRJ&jnJSvwH6mGSV*HPy8DTq3t7-H zh>8tN<R?+b!j`) z6s0ZC)1g%A#VrA$I@7XAw$<>03V=3D>2;d8`EM@g3=3DzrIo2vZ=3D?ev4o|Vup;R>_pcCU zaYL*oX+Ama8^$T8?IUIPIn}}A1wlW%5Xk40Te4mmN~bA_sfshwdH_GZMqo^mcBC~0iLGTxcoRPfI4bJ zi#Zt+D)DJhSju1%g_Nq4tQBDvwAfC`THc+Pp+nrL#pH-kM>=3DE)BNaA;HiI5BVazx~ zRMW5{YzXLc2(7PDrPvFCeR|ejVaf3rO?&L9fdya1kf~mQie`GjnAS1Bs>-K>la3zd z!1r~S2c^3pRAy|FP|`5f=3D^fxmZC0!XwjN zs^``Y2~}`~#QS;jQ!G*ZEaVH7bS!pmRQRnVw2f z#WH;Q*7B~Wqz6U(tk2a6V6pH)&N8)^XqY9NnI+3O#o5Y^u${EuHu`3oa#%69p^u7%R$c7B2J?E(^G5=3DISTIZmk11n zBeo{euhu>j*@5>@q&8cxx%`xMxL=3D*F4ajkTNouWz<0@Z!d_ZTR_^>{+voM4Xf6Dmy3a#8W=3DXH(K1d-o&)86K+CM6-BjW2l5J47 zysnA{hdWWh8KOxu8R=3DMB=3D%~r2N!0(UNlQ8{l4!!L$Oy=3D2r0IVWk;Yf7uPTcSGHdcx zrwC~7^K5+szx{8iusa=3DED`U(CSE2H*5V3+pgp|L-I+)f!o95ii-T9@vYQNkwFu^50h1Qx-Qaa8eMl z@+Ehm%$+p(eqPq{D%i}BBBzI{hDzfv9OO#Iy6N~psUkXl54EfH%L}5eq=3D&|)SoCVC z7A;oQAw$GCy`v`c!C>?KLDX~tK*@<;=3Do-iK&_q1>AjCI-sF_wW)1uaQuHwj|1l18? zRciFrj>v4aqM}LBCgY=3DH#MKM2)r2)p&siS2nf$pVniiXv(o7<`zew5sL;tF&Ju0>; zxI~600TJnh<(CmdsmZyzQd5xa7B^XwiMa?t>FfZx{xX}bR(-ggctEQq#z=3D0S z-;iWh>M2hNF$0uJWA;Zk_xE>KL#?O}M1BQE`J}|-O=3DJXH#oT2SxR}HWB*k+!S*@}P z`6xPqQD>RN3K=3Drt9k^%NbY8=3DWN^v#E>9A~0uLM#!9qxu&;!Ib2$o1$dgw+-1oCbkq zD3u9-3dFBQt=3DnX*n1Hw!cUP^&yg7@#r)o+X*ebSkX^qkW3(CO}U81VO%cP>`eH zRZK%sNsdfkNa0zl@mNC>tyPdKD%bF?m2%6o7qW9{9)TfC5};_n;E0c8Dl|19DjGzy z))6N;{kM!UU=3D=3DK3Tlz{PU`6!m8$GmgqIm2zRsI`Ldqs21z{xv4$el;opqN z;Y+9xHAP6SJP=3DtwGR8wkgHrBT{-){#)M~Y8qiNH{2AoDhB8=3Dr(Otd4X{(&EBdw#M7 zQU@v`J#o5Hg$_{>SDuZKNS&15M4aSOOJ+V)a*h!ii=3Dd1%Su-NXa`fRH#dIvhqau9~ z4Rv4+ottZ*-*iiUcZ&warM+JB*quyAAba+z=3D|z@&Ao~EVvkBMuOsYeqB=3DzpFq%j@5 zUi0h)nbw40SePx=3D_*7?dR)I#$l|kntblG6i5}B~g*1V-M3bjKxLUtphB!>MzvH)0iU*`SDhdB+>v~6_9bXWPXup?tOzz;Fg z(UUp9#U%uK)HLrlyFCF zmZEO${U;V+wIk$#N=3DaY7AcFywQ%W_xoZ=3D&E61sxq`G_Ffl}Ycrdi;7BBzA4)K*4$+ zBTU6TsGiKw2PiqUq6GIRI8`ZB%)t^d9x|Vs&81!kQ_#ObiD}?xyrvm^PL&$MZS2Y^{u2x~?q@ zlC^}K@9@)+gD?amqNiITwtI0I3!=3D%Ba_C0p{L>3WIv(`X64HpWbQ>8hp*CszR!C_> zgyej>M8}n3gK+B`bA^#`wmp8^zae8y#7|OdT*%N(4hLy;SBe00cf};{n)+v9cFv|ABf3BA*}Gx@Oy{?}FSe@5tDAaTTG+y~Oh9)5-}SG8~lqljSsV zT_z2SNtIZ4+cW8RBO&EFD`_KL8MdOuOb%8V9Bpyhr<_bZpt12xtlJ~g>oOysY`81) zPS|2l6{Y9y=3D?*PX(_27omd*mPcbV>j4B-PGDeqWfEhZgzKyHUuTL+JH1W zWJXp7)XBsMCuVPa7Fq0C^XV-%^W1^r&9BJJ7djx6)-pOn zGF(F3G8yS3UI6R`ClocyTWm(O?y2Rj7AzJG(Kc)A0dCV}v<}%?Ji~mt9KF#&hIGs$ zdUDE%#6;!V4&o)lnq$Eam8Drn^@jU>Bla#o8ZPm5)aEM(Et@U_lnq!M>X95%(XBz` z06k6~NFgA@NI7a@!*eN(2hj*}428tz3H6ZtZKRX%&pRY)!5DxM0m?%Wy#bDlHqq`Z zRdXCn%N#=3DzzLNZ4=3D{$0y5thc;fMw$&bB{PWkb<{U8Bjo`@sGQii9}*B(}>4G9!kp6 z8A2KPh`m{MH^N1k@Xx{}GL`x;fmAyL#UsaNM&g96YUxV<1z5(vS#uDIHv>_cCk`?a zN!mEkr}z;A5cMwsBFEuJ(v_ADdp`+rA_=3DVJRqNOyEYc=3D97|R{=3DkfT>(nGTI2LWY*%G&PsylVGnk3%RQJNM)ywizcw{7@(l4SED1O9l*2oVz zQfAa>g>OwE>l@YUl?Xve(Z%l1!@(UH48Ld0xQscg-S+@`0EbFi=3DZy36YKmp}P z{m`y~AI&C$Cq0rRx_w)h*xzU2dscO<9ey~q&B4qOV()3^0=3D|^Bn%@c;mYHQF5~a3L zh+b_&+(XV0aTCEDvx29C?8%bU$TnOvZvw2P+J_Cp!K{l)qlt1R1~Ypi>Rvx7Cz5kI z4XzWZ+VNu>`QXA%=3D1*yI(IJ{B7sMka<@Z@kYL95`sT{L9hVV6`wES-8{g{cwx60m4 zKAQL;LR4HnAcR#$F4}yXYP-hDBnwB$xUA6uvurx`@y*?@z!DwEF%J!5tAW^7R9o?* z8uB*qL)mjKA4%G~m@HSz*(F!)+flxzw5%H$BEHXJd?5&ij&V2(kj(%k{pLVT?d@-i z^aHkzb~k%2<}t|Ls*V1xLpkg8dOhh^v~Ns9N#omkFjvlXjqHHPGclhoV@Oy;PC7PV zvH6kM`h_GvCr#sz2LGy5I*2M9gdb8N2#dNI*?mfM#gr!ECO;%S5c#ZFhEfC<^N8-| zitL$sL7OEOlhdsfn#Skt`9TC;W^M5h5yk2l=3DT_HVaR(~3GZHB_nH77NAFrY>YnILXnDZcl-rE z)`TBY!0G&lbk-wjRg}K+yb}3RWa94lZ}X=3D4eU^y117+ECSYAaLVg)F35un@#Eml_U zZ842COPv(Q;AE(Py#tQeDmfob@{gMUGNg`m(c=3D3oFw@~%ME{EARWbyDMHhU<^sX&P z2ee)gylI5g)Sc_6mKwYO*|EsfdaU)RXQu|S`FE3(RHh9efyC#!?ZHg!$-B2f?l(>S zD>>&x^Gl@b8Y6Ei3K>ViGDO7kuXb<47H`&k4TnK6qar+eA(iP)$TKmRVK7@?$i>NY zF|3@Cp!rvFXcvbPGVPaS1j_ux?e|}3-LATVnbo!Bx2vq>RdGTAL0b!S)klr%aA>+O zH}9rj;%LfGl%exDm9cC7ZWERVeAcyyExy}ley*FxS_fqe79}GbE4lB~4rphi5}N-d z+1)aKcTIQJlUV{WA5QMSPV(F3UgO99Fn~!9zJYFNy+|(V8oOhPDc&=3Dq$N|0w*+f0D zaWNrmqE=3DVLe9`PuaQHfsMfS}Dbf^ft?U|T}^w^5oVHp&~LgI7XQbS-7F_>wK5h*9N zJz3--H#5vffIjxA+Km<|DL<)VnHl1_1CH4ZA4ww=3D z8m!x`8Op>)Z%8^y#4slf>kZU`39`IPdI3)xFexb{dyJzb|K^%j0FK%$9Be7R;+9P) zmNmBjmATu?7^{&3J34)?*5i;=3DAUX9zjHMj4aHpj`)_ayz+e9F-X5x z)ZV@&ayUpQALVe6c4oO>GTl%{j>3uBm2G7EGi;Cj?r-#s{bWQ4%BD682WQrNI$PAT zEryv`oV+IAv5}S0>}MI?rJ*gkDF)GVQsw5+T5XH@p5^6g6Q>*a`t(d%J1j$$1PlwM z!w4k`qMx@$Qts?c=3DFio4C8&=3DsXO^h)l@U_1fKU!VSq>@n=3Dn$nTTRI@~S1tllxnybwn=3D-?$}a+2%X{0n!fjK{e$d^v>F?O24`+m?7s>$<*+(MdTtWuB1q z%j4`I)-2~7*Ru##R+(S6#PvwUWdHEQW|f)YU>YET(tIru0)bD4#84oESAQW>AIa88 zYDp0_=3Dc&xnkh3{Le3#L|l7sj4z5(j`*0p+~0!B#56(5D9<`yT6+A`jaP}aPcZbnD$ zj6}Cz7HQTTxZJ8rd~YI=3DA2=3DubDrHxKS5KW2C&{98Hd2y*pCvJuS8)$Y23QfwYD?!) z1_i-uuCSHQ*eAy1{wi|ou&$6FI@2p16yImr^>f|CJ!*lU%2z1J zOt&;2WS&Yd73c017<3`vG>J(136xhYkUl~Yt80sIqpQuJkY{{8-5ktpWz%K)I*d)L z)~ZjVFtsALcBYA02tq04c{J$CpXYl`RTv!QBpaNM&Ie+BSvnL!HAie7f=3DaFVbWUya z1Jcy$ZfcRLf~YIGU*(!UtH&i)#Bj5;EI_@t)5+XLs|(ayh>jskSlz ziu{1@v#^MVNp1PLZebb$3jf$-BmV09(=3D>1?-N1r2K`mAl>!e{&D|%c`rq$%`M#QOW z#CPw9z3Vb%YQcIJ>Q_xk`Gvclu|8d_N4AoK+uL+$A*gqy(yQqFcp~G4dbdsK{?QSk zoX&l!?S<*=3DQXyQ?p0RU&E|?}qPAEi6rWvwxu~ZL>5F^moqvT8!+w-O)H4xmE0X9)(|f*-@D_V!Yo&z8_4^KJ@{cX&UqCOTMHdHL1;}c+JmsivVR^E7W`? zUGuFLIIw8}*_p)0fS^X1rM=3DFhC!Jmh z)oWkZi=3DC;1g0FRq5R~}l8f*wAn=3DU=3D5R1UAO#}^`;WMC=3D%CoXu(A*XX6Y8WY^J+3yn zQ~P=3DqMHKruH5*<>^JzAxC++o`?eD8* z1*p1G-;T1>jY{IBLNpNGFpdA3=3D!ld>Q+ zsP9>?qB~4s9Ohh!BhrWs{RZf>vopGwJ@osY*$uo6DQVTX16AD662@!-5`%|>4Tou6%y?3Y18VKy0qTz^Bo%t%-l+PhDTz#RwB>RI zs<3n=3D2j29qLPf_Rz$BQ)!@tte4iw#D#}%^7j0gu?8(y!Mw_@a+of$!6?rWrS?i)sz z#06Kzg)C60Xy8wJ!qBXV!b)U3WrIg3K)1iNGSmzDogW3t_&&=3Dry6V2TwHts42g?N+ zPNC$}t3ia-J-aO@0HV5qGxk+2mC?Ii(&(+4O{yO{q)K6toF$b2e4MW=3Dc4eX%G`C<=3D zor)i7mvk6kL>h+TC(@e-xGOf|x56)2Xm)dP+J`*}PtGpy=3D5izl1pq&4u66Ds*Pe3S z;9AGps}`yVGTly8&Pufj@>G!9o@65_qtITme9nZE%2bZ^T$i)DKMx068#p*}FK3hc zyZh-}1}X3%90mI>km~>ZV`J%1u#`?TNvu_(C0W>+WU7bJrxMg|*Xfx^B*yk`{vNOl zLGd2xQ8B~8lejh+rW~x%J|eK;-~oJ@C=3DJq0tcM<*Hmw)X3X4wOXuHYeeK!v9x8#Ct zq{NB}DKB1KiE%nhttkt2WKIXb=3DHcMXnl9PEjCH~DXLU4yrR}QEr1C&~iEH_*5+>;K z|E`Jxh#l@rC_Ddlb(9YFzi$%>$Y?+{zok90!lpkFssc#OZMyBtHgjY#sw#jJ{bdFo zEl_dN!p1eg>`QgApm9UFcLtG`k4>#o#-FuEgVqE{0iWQVnY zhqZ6nV;*PkXQ#UcN0;(T2%$Za_a6tMMfBa z4yl1(${xf7Q-)}Dq0%i_{-hqPiP@hD&ekWXG5IRKn6@=3Dc{eqRfAo{2oFEp8=3D;*Bcc zwC3WGs!#9ozM%0FvDzSAo<&=3DJjV zb19cwyLPu4m$!i~%P1`l)#;v^^)But{TyD!{ASqI0RST!DV7N7R`Ny863=3Dk0c4R5o z;vMxEyUTvVbn^=3DZ)4B=3DT8noNrHtlt;v%9k1@akU7cjWWC(ZJw_nVTn;>nibBwVGnp z-%e&0glC<*9;1>1+tUV1c2v|1pt9u>+risd+O+9QYaH3>4=3D=3D9oCbRisv6#>9Z?Dcz zd(v*W>a55cANeQR+_!Wel}pG2{9R)y4Bw@2BSBb!j`ARY9V;=3D?VsGqyp}QPZIah0x zTs>*0H#i**&xXUnNiWlS$`vx#Vu`r4YG&K9bVrR)dC<#nv%$$SyG;wqnM-2w>zanQ z0NAF8`MK_?&5#!GOoht^(w1l1!rAq8tLZkL&6=3DGX6J<-Se_J#JLLAnb8E&y!!P&Bq znZ2+pLpnyX&|2<>qDF3oke~V%7;`Etvq?PBy%Kb>4RTrDD5^(jWoeMR`g_?X*kgXnI`zKa#e?7B| z`UaRiJuL)nkS?c=3D{Lu{)H&meogim9o*5>u=3D;%eJ1);i_{=3D^+OE8ybj@_2dC|g~qgY z18UkAJ1Mxn$+D~QEuFHuRWL{{P=3DhfB3-M%fMWM&ycDpfyJw2M!k7O7WIMglkbKS6f zM31~1YD}%cB~VMGQ>J?EeygcfHE#kvhj~0YUD0u5dYZCg4J}F16Dz_F0b>zMYJ#!X zGc!no^YyKpkYw_EfWBXu%rq_e4TRT@ClumkF)8!ygNUmb=3DZGmi~miY%XAtbzu zKOzJt8g}4IH9PGQX}e{{&{!@95Q-`5xsa8hL&|c0rHu{K`Rrn5-Y`+FHO2C}HlLuX z6%4sOD>^@9f<#qa-H8?Z!A2B|7NewJFMYy!F$Go?@ct8zk`<8=3D5dGr<8-Sxq)LTK#L4uIZZq>lg%{nf?T|oNp0tSeJ4` z6GW1vSHmmj#@i05)$Cg2>Bkz<{^iuz+|#|c>mWZu-}cPfFTbd>kZDX?q;^#z;}w7ib?AERxy@Sgs;1y zv#nH+Dm%Ab4Bwt&HJ`$q!R6&>ba{1iKbhAz1YT%kL+eo8=3DYChMvhdi4HZ13pyBlo7 z<>mG5{d7?)-B7-mO6jn^2F_z0TcB>t6Uj+}?5ts$IkYHWt@6CafXAk99jVx&A4Yo@dOBVOic0l-A&-wCLU^8y)srA9K30dQbh0~$Ape`cW@@)2`jxK8^ zY#wPvHCrMci{)~$AyCH{a^@pm`xaM5P`XfQ1}C@m3OFL$e3r9?FF*>WhR1#kQn!PdHjbvEG>Eg6 za&cUBIx7Ui7Nd5UG?cPdOsvfXtY_O>k;TDR=3Dr**Z#iOn{fh_3HFQG@7fUP~|*Nyv3 zm|*nHpr(PbN=3DFJskC)cgr_hNExkM6-4H zw}kS%zn%W5Rj*p!4(paHTDzry@i+9>Q%hCDS=3D}GSc;YCTUw9_A)o?VQt$~Fv7s~NVkjQH)^(R(>jA>P{d(sr`!9R@k< zG|f7lEUQ~N!3)38t2A?MXp!p&{<7(vEo#tub5 zsDrsyku<3hdq4)d(UoIn#47o1p#OJ@1^^`QebEeFW)1^3_TR?9hGkK^yG-J4aSy$f36$ ziygp_`taxKx_0sD{*8U{5Ympd4AOZ#Ir#$j;oD(5*REpVNDGJX@F=3D|ih%jC*hrNyz z0)F%5Vs>{kIv);TC;D!gA8rEs zFmI-P*!ySRoKvH-d5_iBY&apruQ@I9)nYN5&8E}I-AJw(Iu>R}hnse~C&P;?48zyC zRGuEIYmw=3DEOw`hW@gdS0zQAo_~gLE_;)GsrQ=3Dv8MQtbp{kQO(8T zw%v{h$LNLdxv`oYjEW2KcBm@UX8;)s$VIWZc@g8R>}=3D8y#HkSG zn`a-2TE~aeYv)H6>f@2eN3E`gba1;_YduA9tq#F`?ziK|>REi;`gV0Lrj237_3GI* zYd!LfPr5CFLoYC=3DBhC7a1CmyoV>c4!nI2}NO6A%o`Q6#ejAmz@{`pPKUP^~p8uUyI zX;fH{=3D>C#3k~7#|`{H`C5GxMaeAMxosJ*$`^sFXoRV?l<26bydHp6|Y62Oy_!TIP4 zwqJ2O(J!Xg#`iLw3Y!DelNp=3D!uI6`Far>eJRB~hxu)$Kd-# +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + DEC_SPECIFICATION =3D 0x00010005 + PACKAGE_NAME =3D SimicsOpenBoardPkg + PACKAGE_GUID =3D E6A03E0D-5944-4dc6-9292-090D609EDD3A + PACKAGE_VERSION =3D 0.1 + +[Includes] + Include + +[Guids] + gBoardModuleTokenSpaceGuid =3D {0xeed35f57, 0x4ff2, 0x4244, {0xb8, 0x3a= , 0xea, 0x71, 0x5f, 0xd3, 0x59, 0xa5}} + gSimicsBoardConfigGuid =3D {0xeed35f57, 0x4ff2, 0x4244, {0xb8, 0x3a, 0x= ea, 0x71, 0x5f, 0xd3, 0x59, 0xa5}} + +[PcdsFixedAtBuild] + gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvBase|0x0|UINT32|0 + gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvSize|0x0|UINT32|1 + gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvBase|0x0|UINT32|0x15 + gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvSize|0x0|UINT32|0x16 + + #TODO: Remove these two when we integrate new PlatformPei + gBoardModuleTokenSpaceGuid.PcdSimicsMemFvBase|0x00800000|UINT32|2 + gBoardModuleTokenSpaceGuid.PcdSimicsMemFvSize|0x00500000|UINT32|3 + + gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase|0x0|UINT3= 2|0x8 + gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize|0x0|UINT3= 2|0x9 + gBoardModuleTokenSpaceGuid.PcdSimicsFirmwareFdSize|0x0|UINT32|0xa + gBoardModuleTokenSpaceGuid.PcdSimicsFirmwareBlockSize|0|UINT32|0xb + gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase|0x0|UINT3= 2|0xc + gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageFtwSpareBase|0x0|UINT3= 2|0xd + gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase|0x0|UIN= T32|0xe + gBoardModuleTokenSpaceGuid.PcdSimicsFdBaseAddress|0x0|UINT32|0xf + gBoardModuleTokenSpaceGuid.PcdSimicsSecPageTablesBase|0x0|UINT32|0x11 + gBoardModuleTokenSpaceGuid.PcdSimicsSecPageTablesSize|0x0|UINT32|0x12 + gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamBase|0x0|UINT32|0x13 + gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamSize|0x0|UINT32|0x14 + gBoardModuleTokenSpaceGuid.PcdSimicsLockBoxStorageBase|0x0|UINT32|0x18 + gBoardModuleTokenSpaceGuid.PcdSimicsLockBoxStorageSize|0x0|UINT32|0x19 + gBoardModuleTokenSpaceGuid.PcdGuidedExtractHandlerTableSize|0x0|UINT32|0= x1a + gBoardModuleTokenSpaceGuid.PcdSimicsDecompressionScratchEnd|0x0|UINT32|0= x1f + +[PcdsDynamic, PcdsDynamicEx] + + # TODO: investigate whether next two Pcds are needed + gBoardModuleTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|0x28 + gBoardModuleTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10 + gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId|0|UINT16|0x1b + + ## The IO port aperture shared by all PCI root bridges. + # + gBoardModuleTokenSpaceGuid.PcdPciIoBase|0x0|UINT64|0x22 + gBoardModuleTokenSpaceGuid.PcdPciIoSize|0x0|UINT64|0x23 + + ## The 32-bit MMIO aperture shared by all PCI root bridges. + # + gBoardModuleTokenSpaceGuid.PcdPciMmio32Base|0x0|UINT64|0x24 + gBoardModuleTokenSpaceGuid.PcdPciMmio32Size|0x0|UINT64|0x25 + + ## The 64-bit MMIO aperture shared by all PCI root bridges. + # + gBoardModuleTokenSpaceGuid.PcdPciMmio64Base|0x0|UINT64|0x26 + gBoardModuleTokenSpaceGuid.PcdPciMmio64Size|0x0|UINT64|0x27 + +[PcdsFixedAtBuild, PcdsDynamic, PcdsDynamicEx, PcdsPatchableInModule] + ## Pcd8259LegacyModeMask defines the default mask value for platform. Th= is value is determined

+ # 1) If platform only support pure UEFI, value should be set to 0xFFFF = or 0xFFFE; + # Because only clock interrupt is allowed in legacy mode in pure UEF= I platform.
+ # 2) If platform install CSM and use thunk module:
+ # a) If thunk call provided by CSM binary requires some legacy inter= rupt support, the corresponding bit + # should be opened as 0.
+ # For example, if keyboard interfaces provided CSM binary use leg= acy keyboard interrupt in 8259 bit 1, then + # the value should be set to 0xFFFC.
+ # b) If all thunk call provied by CSM binary do not require legacy i= nterrupt support, value should be set + # to 0xFFFF or 0xFFFE.
+ # + # The default value of legacy mode mask could be changed by EFI_LEGACY_= 8259_PROTOCOL->SetMask(). But it is rarely + # need change it except some special cases such as when initializing th= e CSM binary, it should be set to 0xFFFF to + # mask all legacy interrupt. Please restore the original legacy mask va= lue if changing is made for these special case.
+ # @Prompt 8259 Legacy Mode mask. + gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeMask|0xFFFF|UINT16|0x0000= 0001 + + ## Pcd8259LegacyModeEdgeLevel defines the default edge level for legacy = mode's interrrupt controller. + # For the corresponding bits, 0 =3D Edge triggered and 1 =3D Level trig= gered. + # @Prompt 8259 Legacy Mode edge level. + gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel|0x0000|UINT16|0= x00000002 + + ## Indicates if we need enable IsaAcpiCom1 device.

+ # TRUE - Enables IsaAcpiCom1 device.
+ # FALSE - Doesn't enable IsaAcpiCom1 device.
+ # @Prompt Enable IsaAcpiCom1 device. + gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiCom1Enable|TRUE|BOOLEAN|0x000000= 03 + + ## Indicates if we need enable IsaAcpiCom2 device.

+ # TRUE - Enables IsaAcpiCom2 device.
+ # FALSE - Doesn't enable IsaAcpiCom2 device.
+ # @Prompt Enable IsaAcpiCom12 device. + gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiCom2Enable|TRUE|BOOLEAN|0x000000= 04 + + ## Indicates if we need enable IsaAcpiPs2Keyboard device.

+ # TRUE - Enables IsaAcpiPs2Keyboard device.
+ # FALSE - Doesn't enable IsaAcpiPs2Keyboard device.
+ # @Prompt Enable IsaAcpiPs2Keyboard device. + gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiPs2KeyboardEnable|TRUE|BOOLEAN|0= x00000005 + + ## Indicates if we need enable IsaAcpiPs2Mouse device.

+ # TRUE - Enables IsaAcpiPs2Mouse device.
+ # FALSE - Doesn't enable IsaAcpiPs2Mouse device.
+ # @Prompt Enable IsaAcpiPs2Mouse device. + gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiPs2MouseEnable|TRUE|BOOLEAN|0x00= 000006 + + ## Indicates if we need enable IsaAcpiFloppyA device.

+ # TRUE - Enables IsaAcpiFloppyA device.
+ # FALSE - Doesn't enable IsaAcpiFloppyA device.
+ # @Prompt Enable IsaAcpiFloppyA device. + gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiFloppyAEnable|TRUE|BOOLEAN|0x000= 00007 + + ## Indicates if we need enable IsaAcpiFloppyB device.

+ # TRUE - Enables IsaAcpiFloppyB device.
+ # FALSE - Doesn't enable IsaAcpiFloppyB device.
+ # @Prompt Enable IsaAcpiFloppyB device. + gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiFloppyBEnable|TRUE|BOOLEAN|0x000= 00008 + +[PcdsFixedAtBuild, PcdsPatchableInModule] + ## FFS filename to find the shell application. + # @Prompt FFS Name of Shell Application + gBoardModuleTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E, = 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 }|VOID*|0x= 40000004 + + ## ISA Bus features to support DMA, SlaveDMA and ISA Memory.

+ # BIT0 indicates if DMA is supported
+ # BIT1 indicates if only slave DMA is supported
+ # BIT2 indicates if ISA memory is supported
+ # Other BITs are reseved and must be zero. + # If more than one features are supported, the different BIT will be en= abled at the same time. + # @Prompt ISA Bus Features + # @Expression 0x80000002 | (gBoardModuleTokenSpaceGuid.PcdIsaBusSupporte= dFeatures & 0xF8) =3D=3D 0 + gBoardModuleTokenSpaceGuid.PcdIsaBusSupportedFeatures|0x05|UINT8|0x00010= 040 + + gBoardModuleTokenSpaceGuid.PcdLogoFile |{ 0x99, 0x8b, 0xB2, 0x7B, 0xBB, = 0x61, 0xD5, 0x11, 0x9A, 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }|VOID*|0x= 00010037 + +[Protocols] + ## + ## IntelFrameworkModulePkg + ## + gEfiOemBadgingProtocolGuid =3D { 0x170E13C0, 0xBF1= B, 0x4218, { 0x87, 0x1D, 0x2A, 0xBD, 0xC6, 0xF8, 0x87, 0xBC }} diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/Simics.h b/Pl= atform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/Simics.h new file mode 100644 index 0000000000..f6ef44a14f --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/Simics.h @@ -0,0 +1,507 @@ +/** @file + QEMU Video Controller Driver + + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// QEMU Video Controller Driver +// + +#ifndef _QEMU_H_ +#define _QEMU_H_ + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +// +// QEMU Video PCI Configuration Header values +// +#define CIRRUS_LOGIC_VENDOR_ID 0x1013 +#define CIRRUS_LOGIC_5430_DEVICE_ID 0x00a8 +#define CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID 0x00a0 +#define CIRRUS_LOGIC_5446_DEVICE_ID 0x00b8 + +// +// QEMU Vide Graphical Mode Data +// +typedef struct { + UINT32 InternalModeIndex; // points into card-specific mode table + UINT32 HorizontalResolution; + UINT32 VerticalResolution; + UINT32 ColorDepth; +} QEMU_VIDEO_MODE_DATA; + +#define PIXEL_RED_SHIFT 0 +#define PIXEL_GREEN_SHIFT 3 +#define PIXEL_BLUE_SHIFT 6 + +#define PIXEL_RED_MASK (BIT7 | BIT6 | BIT5) +#define PIXEL_GREEN_MASK (BIT4 | BIT3 | BIT2) +#define PIXEL_BLUE_MASK (BIT1 | BIT0) + +#define PIXEL_TO_COLOR_BYTE(pixel, mask, shift) ((UINT8) ((pixel & mask) <= < shift)) +#define PIXEL_TO_RED_BYTE(pixel) PIXEL_TO_COLOR_BYTE(pixel, PIXEL_RED_MASK= , PIXEL_RED_SHIFT) +#define PIXEL_TO_GREEN_BYTE(pixel) PIXEL_TO_COLOR_BYTE(pixel, PIXEL_GREEN_= MASK, PIXEL_GREEN_SHIFT) +#define PIXEL_TO_BLUE_BYTE(pixel) PIXEL_TO_COLOR_BYTE(pixel, PIXEL_BLUE_MA= SK, PIXEL_BLUE_SHIFT) + +#define RGB_BYTES_TO_PIXEL(Red, Green, Blue) \ + (UINT8) ( (((Red) >> PIXEL_RED_SHIFT) & PIXEL_RED_MASK) | \ + (((Green) >> PIXEL_GREEN_SHIFT) & PIXEL_GREEN_MASK) | \ + (((Blue) >> PIXEL_BLUE_SHIFT) & PIXEL_BLUE_MASK) ) + +#define PIXEL24_RED_MASK 0x00ff0000 +#define PIXEL24_GREEN_MASK 0x0000ff00 +#define PIXEL24_BLUE_MASK 0x000000ff + +#define GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER 0xffff + +// +// QEMU Video Private Data Structure +// +#define QEMU_VIDEO_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('Q', 'V', 'I', 'D= ') + +typedef enum { + QEMU_VIDEO_CIRRUS_5430 =3D 1, + QEMU_VIDEO_CIRRUS_5446, + QEMU_VIDEO_BOCHS, + QEMU_VIDEO_BOCHS_MMIO, +} QEMU_VIDEO_VARIANT; + +typedef struct { + UINT8 SubClass; + UINT16 VendorId; + UINT16 DeviceId; + QEMU_VIDEO_VARIANT Variant; + CHAR16 *Name; +} QEMU_VIDEO_CARD; + +typedef struct { + UINT64 Signature; + EFI_HANDLE Handle; + EFI_PCI_IO_PROTOCOL *PciIo; + UINT64 OriginalPciAttributes; + EFI_GRAPHICS_OUTPUT_PROTOCOL GraphicsOutput; + EFI_DEVICE_PATH_PROTOCOL *GopDevicePath; + + // + // The next two fields match the client-visible + // EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.MaxMode field. + // + UINTN MaxMode; + QEMU_VIDEO_MODE_DATA *ModeData; + + QEMU_VIDEO_VARIANT Variant; + FRAME_BUFFER_CONFIGURE *FrameBufferBltConfigure; + UINTN FrameBufferBltConfigureSize; +} QEMU_VIDEO_PRIVATE_DATA; + +/// +/// Card-specific Video Mode structures +/// +typedef struct { + UINT32 Width; + UINT32 Height; + UINT32 ColorDepth; + UINT8 *CrtcSettings; + UINT16 *SeqSettings; + UINT8 MiscSetting; +} QEMU_VIDEO_CIRRUS_MODES; + +typedef struct { + UINT32 Width; + UINT32 Height; + UINT32 ColorDepth; +} QEMU_VIDEO_BOCHS_MODES; + +#define QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS(a) \ + CR(a, QEMU_VIDEO_PRIVATE_DATA, GraphicsOutput, QEMU_VIDEO_PRIVATE_DATA_S= IGNATURE) + + +// +// Global Variables +// +extern UINT8 AttributeController[]; +extern UINT8 GraphicsController[]; +extern UINT8 Crtc_640_480_256_60[]; +extern UINT16 Seq_640_480_256_60[]; +extern UINT8 Crtc_800_600_256_60[]; +extern UINT16 Seq_800_600_256_60[]; +extern UINT8 Crtc_1024_768_256_60[]; +extern UINT16 Seq_1024_768_256_60[]; +extern QEMU_VIDEO_CIRRUS_MODES QemuVideoCirrusModes[]; +extern QEMU_VIDEO_BOCHS_MODES QemuVideoBochsModes[]; +extern EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding; +extern EFI_COMPONENT_NAME_PROTOCOL gQemuVideoComponentName; +extern EFI_COMPONENT_NAME2_PROTOCOL gQemuVideoComponentName2; +extern EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL gQemuVideoDriverSupporte= dEfiVersion; + +// +// Io Registers defined by VGA +// +#define CRTC_ADDRESS_REGISTER 0x3d4 +#define CRTC_DATA_REGISTER 0x3d5 +#define SEQ_ADDRESS_REGISTER 0x3c4 +#define SEQ_DATA_REGISTER 0x3c5 +#define GRAPH_ADDRESS_REGISTER 0x3ce +#define GRAPH_DATA_REGISTER 0x3cf +#define ATT_ADDRESS_REGISTER 0x3c0 +#define MISC_OUTPUT_REGISTER 0x3c2 +#define INPUT_STATUS_1_REGISTER 0x3da +#define DAC_PIXEL_MASK_REGISTER 0x3c6 +#define PALETTE_INDEX_REGISTER 0x3c8 +#define PALETTE_DATA_REGISTER 0x3c9 + +#define VBE_DISPI_IOPORT_INDEX 0x01CE +#define VBE_DISPI_IOPORT_DATA 0x01D0 + +#define VBE_DISPI_INDEX_ID 0x0 +#define VBE_DISPI_INDEX_XRES 0x1 +#define VBE_DISPI_INDEX_YRES 0x2 +#define VBE_DISPI_INDEX_BPP 0x3 +#define VBE_DISPI_INDEX_ENABLE 0x4 +#define VBE_DISPI_INDEX_BANK 0x5 +#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6 +#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7 +#define VBE_DISPI_INDEX_X_OFFSET 0x8 +#define VBE_DISPI_INDEX_Y_OFFSET 0x9 +#define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa + +#define VBE_DISPI_ID0 0xB0C0 +#define VBE_DISPI_ID1 0xB0C1 +#define VBE_DISPI_ID2 0xB0C2 +#define VBE_DISPI_ID3 0xB0C3 +#define VBE_DISPI_ID4 0xB0C4 +#define VBE_DISPI_ID5 0xB0C5 + +#define VBE_DISPI_DISABLED 0x00 +#define VBE_DISPI_ENABLED 0x01 +#define VBE_DISPI_GETCAPS 0x02 +#define VBE_DISPI_8BIT_DAC 0x20 +#define VBE_DISPI_LFB_ENABLED 0x40 +#define VBE_DISPI_NOCLEARMEM 0x80 + +// +// Graphics Output Hardware abstraction internal worker functions +// +EFI_STATUS +QemuVideoGraphicsOutputConstructor ( + QEMU_VIDEO_PRIVATE_DATA *Private + ); + +EFI_STATUS +QemuVideoGraphicsOutputDestructor ( + QEMU_VIDEO_PRIVATE_DATA *Private + ); + + +// +// EFI_DRIVER_BINDING_PROTOCOL Protocol Interface +// +/** + TODO: Add function description + + @param This TODO: add argument description + @param Controller TODO: add argument description + @param RemainingDevicePath TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +EFIAPI +QemuVideoControllerDriverSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + +/** + TODO: Add function description + + @param This TODO: add argument description + @param Controller TODO: add argument description + @param RemainingDevicePath TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +EFIAPI +QemuVideoControllerDriverStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + +/** + TODO: Add function description + + @param This TODO: add argument description + @param Controller TODO: add argument description + @param NumberOfChildren TODO: add argument description + @param ChildHandleBuffer TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +EFIAPI +QemuVideoControllerDriverStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ); + +// +// EFI Component Name Functions +// +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form o= f a + Unicode string. If the driver specified by This has a user readable name= in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver speci= fied + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTO= COL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the calle= r is + requesting, and it must match one of the + languages specified in SupportedLanguages.= The + number of languages supported by a driver = is up + to the driver writer. Language is specified + in RFC 4646 or ISO 639-2 language code for= mat. + + @param DriverName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specifie= d by + This and the language specified by Languag= e was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not supp= ort + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +QemuVideoComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + + +/** + Retrieves a Unicode string that is the user readable name of the control= ler + that is being managed by a driver. + + This function retrieves the user readable name of the controller specifi= ed by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specif= ied by + Language, then a pointer to the controller name is returned in Controlle= rName, + and EFI_SUCCESS is returned. If the driver specified by This is not cur= rently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does = not + support the language specified by Language, then EFI_UNSUPPORTED is retu= rned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTO= COL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param ControllerHandle[in] The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to = be + returned. + + @param ChildHandle[in] The handle of the child controller to retr= ieve + the name of. This is an optional paramete= r that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus d= rivers + that wish to retrieve the name of the bus + controller. It will not be NULL for a bus + driver that wishes to retrieve the name of= a + child controller. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the calle= r is + requesting, and it must match one of the + languages specified in SupportedLanguages.= The + number of languages supported by a driver = is up + to the driver writer. Language is specifie= d in + RFC 4646 or ISO 639-2 language code format. + + @param ControllerName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + controller specified by ControllerHandle a= nd + ChildHandle in the language specified by + Language from the point of view of the dri= ver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable n= ame in + the language specified by Language for the + driver specified by This was returned in + DriverName. + + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a va= lid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not curren= tly + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not supp= ort + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +QemuVideoComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle O= PTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + + +// +// Local Function Prototypes +// +VOID +InitializeCirrusGraphicsMode ( + QEMU_VIDEO_PRIVATE_DATA *Private, + QEMU_VIDEO_CIRRUS_MODES *ModeData + ); + +VOID +InitializeBochsGraphicsMode ( + QEMU_VIDEO_PRIVATE_DATA *Private, + QEMU_VIDEO_BOCHS_MODES *ModeData + ); + +VOID +SetPaletteColor ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINTN Index, + UINT8 Red, + UINT8 Green, + UINT8 Blue + ); + +VOID +SetDefaultPalette ( + QEMU_VIDEO_PRIVATE_DATA *Private + ); + +VOID +DrawLogo ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINTN ScreenWidth, + UINTN ScreenHeight + ); + +VOID +outb ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINTN Address, + UINT8 Data + ); + +VOID +outw ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINTN Address, + UINT16 Data + ); + +UINT8 +inb ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINTN Address + ); + +UINT16 +inw ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINTN Address + ); + +VOID +BochsWrite ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINT16 Reg, + UINT16 Data + ); + +UINT16 +BochsRead ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINT16 Reg + ); + +VOID +VgaOutb ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINTN Reg, + UINT8 Data + ); + +EFI_STATUS +QemuVideoCirrusModeSetup ( + QEMU_VIDEO_PRIVATE_DATA *Private + ); + +EFI_STATUS +QemuVideoBochsModeSetup ( + QEMU_VIDEO_PRIVATE_DATA *Private, + BOOLEAN IsQxl + ); + +VOID +InstallVbeShim ( + IN CONST CHAR16 *CardName, + IN EFI_PHYSICAL_ADDRESS FrameBufferBase + ); +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/SimicsVideoDx= e.inf b/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/SimicsVideoDxe.inf new file mode 100644 index 0000000000..002cb56826 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/SimicsVideoDxe.inf @@ -0,0 +1,74 @@ +## @file +# This driver is a sample implementation of the Graphics Output Protocol = for +# the QEMU (Cirrus Logic 5446) video controller. +# +# Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D QemuVideoDxe + FILE_GUID =3D e3752948-b9a1-4770-90c4-df41c38986be + MODULE_TYPE =3D UEFI_DRIVER + VERSION_STRING =3D 1.0 + + ENTRY_POINT =3D InitializeQemuVideo + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC +# +# DRIVER_BINDING =3D gQemuVideoDriverBinding +# COMPONENT_NAME =3D gQemuVideoComponentName +# + +[Sources.common] + ComponentName.c + Driver.c + DriverSupportedEfiVersion.c + Gop.c + Initialize.c + Simics.h + +[Sources.Ia32, Sources.X64] + VbeShim.c + VbeShim.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + OptionRomPkg/OptionRomPkg.dec + OvmfPkg/OvmfPkg.dec + SimicsOpenBoardPkg/OpenBoardPkg.dec + SimicsIch10Pkg/Ich10Pkg.dec + +[LibraryClasses] + BaseMemoryLib + FrameBufferBltLib + DebugLib + DevicePathLib + MemoryAllocationLib + PcdLib + PciLib + PrintLib + TimerLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiLib + S3BootScriptLib + +[Protocols] + gEfiDriverSupportedEfiVersionProtocolGuid # PROTOCOL ALWAYS_PRODUCED + gEfiGraphicsOutputProtocolGuid # PROTOCOL BY_START + gEfiDevicePathProtocolGuid # PROTOCOL BY_START + gEfiPciIoProtocolGuid # PROTOCOL TO_START + gEfiDxeSmmReadyToLockProtocolGuid + +[Pcd] + gOptionRomPkgTokenSpaceGuid.PcdDriverSupportedEfiVersion + gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId + gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/VbeShim.asm b= /Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/VbeShim.asm new file mode 100644 index 0000000000..a82077e2d9 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/VbeShim.asm @@ -0,0 +1,279 @@ +; @file +; A minimal Int10h stub that allows the Windows 2008 R2 SP1 UEFI guest's b= uggy, +; default VGA driver to switch to 1024x768x32, on the stdvga and QXL video +; cards of QEMU. +; +; Copyright (C) 2014, Red Hat, Inc. +; Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
+; +; SPDX-License-Identifier: BSD-2-Clause-Patent +; + +; enable this macro for debug messages +;%define DEBUG + +%macro DebugLog 1 +%ifdef DEBUG + push si + mov si, %1 + call PrintStringSi + pop si +%endif +%endmacro + + +BITS 16 +ORG 0 + +VbeInfo: +TIMES 256 nop + +VbeModeInfo: +TIMES 256 nop + + +Handler: + cmp ax, 0x4f00 + je GetInfo + cmp ax, 0x4f01 + je GetModeInfo + cmp ax, 0x4f02 + je SetMode + cmp ax, 0x4f03 + je GetMode + cmp ax, 0x4f10 + je GetPmCapabilities + cmp ax, 0x4f15 + je ReadEdid + cmp ah, 0x00 + je SetModeLegacy + DebugLog StrUnkownFunction +Hang: + jmp Hang + + +GetInfo: + push es + push di + push ds + push si + push cx + + DebugLog StrEnterGetInfo + + ; target (es:di) set on input + push cs + pop ds + mov si, VbeInfo + ; source (ds:si) set now + + mov cx, 256 + cld + rep movsb + + pop cx + pop si + pop ds + pop di + pop es + jmp Success + + +GetModeInfo: + push es + push di + push ds + push si + push cx + + DebugLog StrEnterGetModeInfo + + and cx, ~0x4000 ; clear potentially set LFB bit in mode number + cmp cx, 0x00f1 + je KnownMode1 + DebugLog StrUnkownMode + jmp Hang +KnownMode1: + ; target (es:di) set on input + push cs + pop ds + mov si, VbeModeInfo + ; source (ds:si) set now + + mov cx, 256 + cld + rep movsb + + pop cx + pop si + pop ds + pop di + pop es + jmp Success + + +%define ATT_ADDRESS_REGISTER 0x03c0 +%define VBE_DISPI_IOPORT_INDEX 0x01ce +%define VBE_DISPI_IOPORT_DATA 0x01d0 + +%define VBE_DISPI_INDEX_XRES 0x1 +%define VBE_DISPI_INDEX_YRES 0x2 +%define VBE_DISPI_INDEX_BPP 0x3 +%define VBE_DISPI_INDEX_ENABLE 0x4 +%define VBE_DISPI_INDEX_BANK 0x5 +%define VBE_DISPI_INDEX_VIRT_WIDTH 0x6 +%define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7 +%define VBE_DISPI_INDEX_X_OFFSET 0x8 +%define VBE_DISPI_INDEX_Y_OFFSET 0x9 + +%define VBE_DISPI_ENABLED 0x01 +%define VBE_DISPI_LFB_ENABLED 0x40 + +%macro BochsWrite 2 + push dx + push ax + + mov dx, VBE_DISPI_IOPORT_INDEX + mov ax, %1 + out dx, ax + + mov dx, VBE_DISPI_IOPORT_DATA + mov ax, %2 + out dx, ax + + pop ax + pop dx +%endmacro + +SetMode: + push dx + push ax + + DebugLog StrEnterSetMode + + cmp bx, 0x40f1 + je KnownMode2 + DebugLog StrUnkownMode + jmp Hang +KnownMode2: + + ; unblank + mov dx, ATT_ADDRESS_REGISTER + mov al, 0x20 + out dx, al + + BochsWrite VBE_DISPI_INDEX_ENABLE, 0 + BochsWrite VBE_DISPI_INDEX_BANK, 0 + BochsWrite VBE_DISPI_INDEX_X_OFFSET, 0 + BochsWrite VBE_DISPI_INDEX_Y_OFFSET, 0 + BochsWrite VBE_DISPI_INDEX_BPP, 32 + BochsWrite VBE_DISPI_INDEX_XRES, 1024 + BochsWrite VBE_DISPI_INDEX_VIRT_WIDTH, 1024 + BochsWrite VBE_DISPI_INDEX_YRES, 768 + BochsWrite VBE_DISPI_INDEX_VIRT_HEIGHT, 768 + BochsWrite VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENA= BLED + + pop ax + pop dx + jmp Success + + +GetMode: + DebugLog StrEnterGetMode + mov bx, 0x40f1 + jmp Success + + +GetPmCapabilities: + DebugLog StrGetPmCapabilities + jmp Unsupported + + +ReadEdid: + DebugLog StrReadEdid + jmp Unsupported + + +SetModeLegacy: + DebugLog StrEnterSetModeLegacy + + cmp al, 0x03 + je KnownMode3 + cmp al, 0x12 + je KnownMode4 + DebugLog StrUnkownMode + jmp Hang +KnownMode3: + mov al, 0x30 + jmp SetModeLegacyDone +KnownMode4: + mov al, 0x20 +SetModeLegacyDone: + DebugLog StrExitSuccess + iret + + +Success: + DebugLog StrExitSuccess + mov ax, 0x004f + iret + + +Unsupported: + DebugLog StrExitUnsupported + mov ax, 0x014f + iret + + +%ifdef DEBUG +PrintStringSi: + pusha + push ds ; save original + push cs + pop ds + mov dx, 0x0402 +PrintStringSiLoop: + lodsb + cmp al, 0 + je PrintStringSiDone + out dx, al + jmp PrintStringSiLoop +PrintStringSiDone: + pop ds ; restore original + popa + ret + + +StrExitSuccess: + db 'Exit', 0x0a, 0 + +StrExitUnsupported: + db 'Unsupported', 0x0a, 0 + +StrUnkownFunction: + db 'Unknown Function', 0x0a, 0 + +StrEnterGetInfo: + db 'GetInfo', 0x0a, 0 + +StrEnterGetModeInfo: + db 'GetModeInfo', 0x0a, 0 + +StrEnterGetMode: + db 'GetMode', 0x0a, 0 + +StrEnterSetMode: + db 'SetMode', 0x0a, 0 + +StrEnterSetModeLegacy: + db 'SetModeLegacy', 0x0a, 0 + +StrUnkownMode: + db 'Unkown Mode', 0x0a, 0 + +StrGetPmCapabilities: + db 'GetPmCapabilities', 0x0a, 0 + +StrReadEdid: + db 'ReadEdid', 0x0a, 0 +%endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/VbeShim.h b/P= latform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/VbeShim.h new file mode 100644 index 0000000000..cc9b6e14cd --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/VbeShim.h @@ -0,0 +1,701 @@ +// +// THIS FILE WAS GENERATED BY "VbeShim.sh". DO NOT EDIT. +// +#ifndef _VBE_SHIM_H_ +#define _VBE_SHIM_H_ +STATIC CONST UINT8 mVbeShim[] =3D { + /* 00000000 nop */ 0x90, + /* 00000001 nop */ 0x90, + /* 00000002 nop */ 0x90, + /* 00000003 nop */ 0x90, + /* 00000004 nop */ 0x90, + /* 00000005 nop */ 0x90, + /* 00000006 nop */ 0x90, + /* 00000007 nop */ 0x90, + /* 00000008 nop */ 0x90, + /* 00000009 nop */ 0x90, + /* 0000000A nop */ 0x90, + /* 0000000B nop */ 0x90, + /* 0000000C nop */ 0x90, + /* 0000000D nop */ 0x90, + /* 0000000E nop */ 0x90, + /* 0000000F nop */ 0x90, + /* 00000010 nop */ 0x90, + /* 00000011 nop */ 0x90, + /* 00000012 nop */ 0x90, + /* 00000013 nop */ 0x90, + /* 00000014 nop */ 0x90, + /* 00000015 nop */ 0x90, + /* 00000016 nop */ 0x90, + /* 00000017 nop */ 0x90, + /* 00000018 nop */ 0x90, + /* 00000019 nop */ 0x90, + /* 0000001A nop */ 0x90, + /* 0000001B nop */ 0x90, + /* 0000001C nop */ 0x90, + /* 0000001D nop */ 0x90, + /* 0000001E nop */ 0x90, + /* 0000001F nop */ 0x90, + /* 00000020 nop */ 0x90, + /* 00000021 nop */ 0x90, + /* 00000022 nop */ 0x90, + /* 00000023 nop */ 0x90, + /* 00000024 nop */ 0x90, + /* 00000025 nop */ 0x90, + /* 00000026 nop */ 0x90, + /* 00000027 nop */ 0x90, + /* 00000028 nop */ 0x90, + /* 00000029 nop */ 0x90, + /* 0000002A nop */ 0x90, + /* 0000002B nop */ 0x90, + /* 0000002C nop */ 0x90, + /* 0000002D nop */ 0x90, + /* 0000002E nop */ 0x90, + /* 0000002F nop */ 0x90, + /* 00000030 nop */ 0x90, + /* 00000031 nop */ 0x90, + /* 00000032 nop */ 0x90, + /* 00000033 nop */ 0x90, + /* 00000034 nop */ 0x90, + /* 00000035 nop */ 0x90, + /* 00000036 nop */ 0x90, + /* 00000037 nop */ 0x90, + /* 00000038 nop */ 0x90, + /* 00000039 nop */ 0x90, + /* 0000003A nop */ 0x90, + /* 0000003B nop */ 0x90, + /* 0000003C nop */ 0x90, + /* 0000003D nop */ 0x90, + /* 0000003E nop */ 0x90, + /* 0000003F nop */ 0x90, + /* 00000040 nop */ 0x90, + /* 00000041 nop */ 0x90, + /* 00000042 nop */ 0x90, + /* 00000043 nop */ 0x90, + /* 00000044 nop */ 0x90, + /* 00000045 nop */ 0x90, + /* 00000046 nop */ 0x90, + /* 00000047 nop */ 0x90, + /* 00000048 nop */ 0x90, + /* 00000049 nop */ 0x90, + /* 0000004A nop */ 0x90, + /* 0000004B nop */ 0x90, + /* 0000004C nop */ 0x90, + /* 0000004D nop */ 0x90, + /* 0000004E nop */ 0x90, + /* 0000004F nop */ 0x90, + /* 00000050 nop */ 0x90, + /* 00000051 nop */ 0x90, + /* 00000052 nop */ 0x90, + /* 00000053 nop */ 0x90, + /* 00000054 nop */ 0x90, + /* 00000055 nop */ 0x90, + /* 00000056 nop */ 0x90, + /* 00000057 nop */ 0x90, + /* 00000058 nop */ 0x90, + /* 00000059 nop */ 0x90, + /* 0000005A nop */ 0x90, + /* 0000005B nop */ 0x90, + /* 0000005C nop */ 0x90, + /* 0000005D nop */ 0x90, + /* 0000005E nop */ 0x90, + /* 0000005F nop */ 0x90, + /* 00000060 nop */ 0x90, + /* 00000061 nop */ 0x90, + /* 00000062 nop */ 0x90, + /* 00000063 nop */ 0x90, + /* 00000064 nop */ 0x90, + /* 00000065 nop */ 0x90, + /* 00000066 nop */ 0x90, + /* 00000067 nop */ 0x90, + /* 00000068 nop */ 0x90, + /* 00000069 nop */ 0x90, + /* 0000006A nop */ 0x90, + /* 0000006B nop */ 0x90, + /* 0000006C nop */ 0x90, + /* 0000006D nop */ 0x90, + /* 0000006E nop */ 0x90, + /* 0000006F nop */ 0x90, + /* 00000070 nop */ 0x90, + /* 00000071 nop */ 0x90, + /* 00000072 nop */ 0x90, + /* 00000073 nop */ 0x90, + /* 00000074 nop */ 0x90, + /* 00000075 nop */ 0x90, + /* 00000076 nop */ 0x90, + /* 00000077 nop */ 0x90, + /* 00000078 nop */ 0x90, + /* 00000079 nop */ 0x90, + /* 0000007A nop */ 0x90, + /* 0000007B nop */ 0x90, + /* 0000007C nop */ 0x90, + /* 0000007D nop */ 0x90, + /* 0000007E nop */ 0x90, + /* 0000007F nop */ 0x90, + /* 00000080 nop */ 0x90, + /* 00000081 nop */ 0x90, + /* 00000082 nop */ 0x90, + /* 00000083 nop */ 0x90, + /* 00000084 nop */ 0x90, + /* 00000085 nop */ 0x90, + /* 00000086 nop */ 0x90, + /* 00000087 nop */ 0x90, + /* 00000088 nop */ 0x90, + /* 00000089 nop */ 0x90, + /* 0000008A nop */ 0x90, + /* 0000008B nop */ 0x90, + /* 0000008C nop */ 0x90, + /* 0000008D nop */ 0x90, + /* 0000008E nop */ 0x90, + /* 0000008F nop */ 0x90, + /* 00000090 nop */ 0x90, + /* 00000091 nop */ 0x90, + /* 00000092 nop */ 0x90, + /* 00000093 nop */ 0x90, + /* 00000094 nop */ 0x90, + /* 00000095 nop */ 0x90, + /* 00000096 nop */ 0x90, + /* 00000097 nop */ 0x90, + /* 00000098 nop */ 0x90, + /* 00000099 nop */ 0x90, + /* 0000009A nop */ 0x90, + /* 0000009B nop */ 0x90, + /* 0000009C nop */ 0x90, + /* 0000009D nop */ 0x90, + /* 0000009E nop */ 0x90, + /* 0000009F nop */ 0x90, + /* 000000A0 nop */ 0x90, + /* 000000A1 nop */ 0x90, + /* 000000A2 nop */ 0x90, + /* 000000A3 nop */ 0x90, + /* 000000A4 nop */ 0x90, + /* 000000A5 nop */ 0x90, + /* 000000A6 nop */ 0x90, + /* 000000A7 nop */ 0x90, + /* 000000A8 nop */ 0x90, + /* 000000A9 nop */ 0x90, + /* 000000AA nop */ 0x90, + /* 000000AB nop */ 0x90, + /* 000000AC nop */ 0x90, + /* 000000AD nop */ 0x90, + /* 000000AE nop */ 0x90, + /* 000000AF nop */ 0x90, + /* 000000B0 nop */ 0x90, + /* 000000B1 nop */ 0x90, + /* 000000B2 nop */ 0x90, + /* 000000B3 nop */ 0x90, + /* 000000B4 nop */ 0x90, + /* 000000B5 nop */ 0x90, + /* 000000B6 nop */ 0x90, + /* 000000B7 nop */ 0x90, + /* 000000B8 nop */ 0x90, + /* 000000B9 nop */ 0x90, + /* 000000BA nop */ 0x90, + /* 000000BB nop */ 0x90, + /* 000000BC nop */ 0x90, + /* 000000BD nop */ 0x90, + /* 000000BE nop */ 0x90, + /* 000000BF nop */ 0x90, + /* 000000C0 nop */ 0x90, + /* 000000C1 nop */ 0x90, + /* 000000C2 nop */ 0x90, + /* 000000C3 nop */ 0x90, + /* 000000C4 nop */ 0x90, + /* 000000C5 nop */ 0x90, + /* 000000C6 nop */ 0x90, + /* 000000C7 nop */ 0x90, + /* 000000C8 nop */ 0x90, + /* 000000C9 nop */ 0x90, + /* 000000CA nop */ 0x90, + /* 000000CB nop */ 0x90, + /* 000000CC nop */ 0x90, + /* 000000CD nop */ 0x90, + /* 000000CE nop */ 0x90, + /* 000000CF nop */ 0x90, + /* 000000D0 nop */ 0x90, + /* 000000D1 nop */ 0x90, + /* 000000D2 nop */ 0x90, + /* 000000D3 nop */ 0x90, + /* 000000D4 nop */ 0x90, + /* 000000D5 nop */ 0x90, + /* 000000D6 nop */ 0x90, + /* 000000D7 nop */ 0x90, + /* 000000D8 nop */ 0x90, + /* 000000D9 nop */ 0x90, + /* 000000DA nop */ 0x90, + /* 000000DB nop */ 0x90, + /* 000000DC nop */ 0x90, + /* 000000DD nop */ 0x90, + /* 000000DE nop */ 0x90, + /* 000000DF nop */ 0x90, + /* 000000E0 nop */ 0x90, + /* 000000E1 nop */ 0x90, + /* 000000E2 nop */ 0x90, + /* 000000E3 nop */ 0x90, + /* 000000E4 nop */ 0x90, + /* 000000E5 nop */ 0x90, + /* 000000E6 nop */ 0x90, + /* 000000E7 nop */ 0x90, + /* 000000E8 nop */ 0x90, + /* 000000E9 nop */ 0x90, + /* 000000EA nop */ 0x90, + /* 000000EB nop */ 0x90, + /* 000000EC nop */ 0x90, + /* 000000ED nop */ 0x90, + /* 000000EE nop */ 0x90, + /* 000000EF nop */ 0x90, + /* 000000F0 nop */ 0x90, + /* 000000F1 nop */ 0x90, + /* 000000F2 nop */ 0x90, + /* 000000F3 nop */ 0x90, + /* 000000F4 nop */ 0x90, + /* 000000F5 nop */ 0x90, + /* 000000F6 nop */ 0x90, + /* 000000F7 nop */ 0x90, + /* 000000F8 nop */ 0x90, + /* 000000F9 nop */ 0x90, + /* 000000FA nop */ 0x90, + /* 000000FB nop */ 0x90, + /* 000000FC nop */ 0x90, + /* 000000FD nop */ 0x90, + /* 000000FE nop */ 0x90, + /* 000000FF nop */ 0x90, + /* 00000100 nop */ 0x90, + /* 00000101 nop */ 0x90, + /* 00000102 nop */ 0x90, + /* 00000103 nop */ 0x90, + /* 00000104 nop */ 0x90, + /* 00000105 nop */ 0x90, + /* 00000106 nop */ 0x90, + /* 00000107 nop */ 0x90, + /* 00000108 nop */ 0x90, + /* 00000109 nop */ 0x90, + /* 0000010A nop */ 0x90, + /* 0000010B nop */ 0x90, + /* 0000010C nop */ 0x90, + /* 0000010D nop */ 0x90, + /* 0000010E nop */ 0x90, + /* 0000010F nop */ 0x90, + /* 00000110 nop */ 0x90, + /* 00000111 nop */ 0x90, + /* 00000112 nop */ 0x90, + /* 00000113 nop */ 0x90, + /* 00000114 nop */ 0x90, + /* 00000115 nop */ 0x90, + /* 00000116 nop */ 0x90, + /* 00000117 nop */ 0x90, + /* 00000118 nop */ 0x90, + /* 00000119 nop */ 0x90, + /* 0000011A nop */ 0x90, + /* 0000011B nop */ 0x90, + /* 0000011C nop */ 0x90, + /* 0000011D nop */ 0x90, + /* 0000011E nop */ 0x90, + /* 0000011F nop */ 0x90, + /* 00000120 nop */ 0x90, + /* 00000121 nop */ 0x90, + /* 00000122 nop */ 0x90, + /* 00000123 nop */ 0x90, + /* 00000124 nop */ 0x90, + /* 00000125 nop */ 0x90, + /* 00000126 nop */ 0x90, + /* 00000127 nop */ 0x90, + /* 00000128 nop */ 0x90, + /* 00000129 nop */ 0x90, + /* 0000012A nop */ 0x90, + /* 0000012B nop */ 0x90, + /* 0000012C nop */ 0x90, + /* 0000012D nop */ 0x90, + /* 0000012E nop */ 0x90, + /* 0000012F nop */ 0x90, + /* 00000130 nop */ 0x90, + /* 00000131 nop */ 0x90, + /* 00000132 nop */ 0x90, + /* 00000133 nop */ 0x90, + /* 00000134 nop */ 0x90, + /* 00000135 nop */ 0x90, + /* 00000136 nop */ 0x90, + /* 00000137 nop */ 0x90, + /* 00000138 nop */ 0x90, + /* 00000139 nop */ 0x90, + /* 0000013A nop */ 0x90, + /* 0000013B nop */ 0x90, + /* 0000013C nop */ 0x90, + /* 0000013D nop */ 0x90, + /* 0000013E nop */ 0x90, + /* 0000013F nop */ 0x90, + /* 00000140 nop */ 0x90, + /* 00000141 nop */ 0x90, + /* 00000142 nop */ 0x90, + /* 00000143 nop */ 0x90, + /* 00000144 nop */ 0x90, + /* 00000145 nop */ 0x90, + /* 00000146 nop */ 0x90, + /* 00000147 nop */ 0x90, + /* 00000148 nop */ 0x90, + /* 00000149 nop */ 0x90, + /* 0000014A nop */ 0x90, + /* 0000014B nop */ 0x90, + /* 0000014C nop */ 0x90, + /* 0000014D nop */ 0x90, + /* 0000014E nop */ 0x90, + /* 0000014F nop */ 0x90, + /* 00000150 nop */ 0x90, + /* 00000151 nop */ 0x90, + /* 00000152 nop */ 0x90, + /* 00000153 nop */ 0x90, + /* 00000154 nop */ 0x90, + /* 00000155 nop */ 0x90, + /* 00000156 nop */ 0x90, + /* 00000157 nop */ 0x90, + /* 00000158 nop */ 0x90, + /* 00000159 nop */ 0x90, + /* 0000015A nop */ 0x90, + /* 0000015B nop */ 0x90, + /* 0000015C nop */ 0x90, + /* 0000015D nop */ 0x90, + /* 0000015E nop */ 0x90, + /* 0000015F nop */ 0x90, + /* 00000160 nop */ 0x90, + /* 00000161 nop */ 0x90, + /* 00000162 nop */ 0x90, + /* 00000163 nop */ 0x90, + /* 00000164 nop */ 0x90, + /* 00000165 nop */ 0x90, + /* 00000166 nop */ 0x90, + /* 00000167 nop */ 0x90, + /* 00000168 nop */ 0x90, + /* 00000169 nop */ 0x90, + /* 0000016A nop */ 0x90, + /* 0000016B nop */ 0x90, + /* 0000016C nop */ 0x90, + /* 0000016D nop */ 0x90, + /* 0000016E nop */ 0x90, + /* 0000016F nop */ 0x90, + /* 00000170 nop */ 0x90, + /* 00000171 nop */ 0x90, + /* 00000172 nop */ 0x90, + /* 00000173 nop */ 0x90, + /* 00000174 nop */ 0x90, + /* 00000175 nop */ 0x90, + /* 00000176 nop */ 0x90, + /* 00000177 nop */ 0x90, + /* 00000178 nop */ 0x90, + /* 00000179 nop */ 0x90, + /* 0000017A nop */ 0x90, + /* 0000017B nop */ 0x90, + /* 0000017C nop */ 0x90, + /* 0000017D nop */ 0x90, + /* 0000017E nop */ 0x90, + /* 0000017F nop */ 0x90, + /* 00000180 nop */ 0x90, + /* 00000181 nop */ 0x90, + /* 00000182 nop */ 0x90, + /* 00000183 nop */ 0x90, + /* 00000184 nop */ 0x90, + /* 00000185 nop */ 0x90, + /* 00000186 nop */ 0x90, + /* 00000187 nop */ 0x90, + /* 00000188 nop */ 0x90, + /* 00000189 nop */ 0x90, + /* 0000018A nop */ 0x90, + /* 0000018B nop */ 0x90, + /* 0000018C nop */ 0x90, + /* 0000018D nop */ 0x90, + /* 0000018E nop */ 0x90, + /* 0000018F nop */ 0x90, + /* 00000190 nop */ 0x90, + /* 00000191 nop */ 0x90, + /* 00000192 nop */ 0x90, + /* 00000193 nop */ 0x90, + /* 00000194 nop */ 0x90, + /* 00000195 nop */ 0x90, + /* 00000196 nop */ 0x90, + /* 00000197 nop */ 0x90, + /* 00000198 nop */ 0x90, + /* 00000199 nop */ 0x90, + /* 0000019A nop */ 0x90, + /* 0000019B nop */ 0x90, + /* 0000019C nop */ 0x90, + /* 0000019D nop */ 0x90, + /* 0000019E nop */ 0x90, + /* 0000019F nop */ 0x90, + /* 000001A0 nop */ 0x90, + /* 000001A1 nop */ 0x90, + /* 000001A2 nop */ 0x90, + /* 000001A3 nop */ 0x90, + /* 000001A4 nop */ 0x90, + /* 000001A5 nop */ 0x90, + /* 000001A6 nop */ 0x90, + /* 000001A7 nop */ 0x90, + /* 000001A8 nop */ 0x90, + /* 000001A9 nop */ 0x90, + /* 000001AA nop */ 0x90, + /* 000001AB nop */ 0x90, + /* 000001AC nop */ 0x90, + /* 000001AD nop */ 0x90, + /* 000001AE nop */ 0x90, + /* 000001AF nop */ 0x90, + /* 000001B0 nop */ 0x90, + /* 000001B1 nop */ 0x90, + /* 000001B2 nop */ 0x90, + /* 000001B3 nop */ 0x90, + /* 000001B4 nop */ 0x90, + /* 000001B5 nop */ 0x90, + /* 000001B6 nop */ 0x90, + /* 000001B7 nop */ 0x90, + /* 000001B8 nop */ 0x90, + /* 000001B9 nop */ 0x90, + /* 000001BA nop */ 0x90, + /* 000001BB nop */ 0x90, + /* 000001BC nop */ 0x90, + /* 000001BD nop */ 0x90, + /* 000001BE nop */ 0x90, + /* 000001BF nop */ 0x90, + /* 000001C0 nop */ 0x90, + /* 000001C1 nop */ 0x90, + /* 000001C2 nop */ 0x90, + /* 000001C3 nop */ 0x90, + /* 000001C4 nop */ 0x90, + /* 000001C5 nop */ 0x90, + /* 000001C6 nop */ 0x90, + /* 000001C7 nop */ 0x90, + /* 000001C8 nop */ 0x90, + /* 000001C9 nop */ 0x90, + /* 000001CA nop */ 0x90, + /* 000001CB nop */ 0x90, + /* 000001CC nop */ 0x90, + /* 000001CD nop */ 0x90, + /* 000001CE nop */ 0x90, + /* 000001CF nop */ 0x90, + /* 000001D0 nop */ 0x90, + /* 000001D1 nop */ 0x90, + /* 000001D2 nop */ 0x90, + /* 000001D3 nop */ 0x90, + /* 000001D4 nop */ 0x90, + /* 000001D5 nop */ 0x90, + /* 000001D6 nop */ 0x90, + /* 000001D7 nop */ 0x90, + /* 000001D8 nop */ 0x90, + /* 000001D9 nop */ 0x90, + /* 000001DA nop */ 0x90, + /* 000001DB nop */ 0x90, + /* 000001DC nop */ 0x90, + /* 000001DD nop */ 0x90, + /* 000001DE nop */ 0x90, + /* 000001DF nop */ 0x90, + /* 000001E0 nop */ 0x90, + /* 000001E1 nop */ 0x90, + /* 000001E2 nop */ 0x90, + /* 000001E3 nop */ 0x90, + /* 000001E4 nop */ 0x90, + /* 000001E5 nop */ 0x90, + /* 000001E6 nop */ 0x90, + /* 000001E7 nop */ 0x90, + /* 000001E8 nop */ 0x90, + /* 000001E9 nop */ 0x90, + /* 000001EA nop */ 0x90, + /* 000001EB nop */ 0x90, + /* 000001EC nop */ 0x90, + /* 000001ED nop */ 0x90, + /* 000001EE nop */ 0x90, + /* 000001EF nop */ 0x90, + /* 000001F0 nop */ 0x90, + /* 000001F1 nop */ 0x90, + /* 000001F2 nop */ 0x90, + /* 000001F3 nop */ 0x90, + /* 000001F4 nop */ 0x90, + /* 000001F5 nop */ 0x90, + /* 000001F6 nop */ 0x90, + /* 000001F7 nop */ 0x90, + /* 000001F8 nop */ 0x90, + /* 000001F9 nop */ 0x90, + /* 000001FA nop */ 0x90, + /* 000001FB nop */ 0x90, + /* 000001FC nop */ 0x90, + /* 000001FD nop */ 0x90, + /* 000001FE nop */ 0x90, + /* 000001FF nop */ 0x90, + /* 00000200 cmp ax,0x4f00 */ 0x3D, 0x00, 0x4F, + /* 00000203 jz 0x22d */ 0x74, 0x28, + /* 00000205 cmp ax,0x4f01 */ 0x3D, 0x01, 0x4F, + /* 00000208 jz 0x245 */ 0x74, 0x3B, + /* 0000020A cmp ax,0x4f02 */ 0x3D, 0x02, 0x4F, + /* 0000020D jz 0x269 */ 0x74, 0x5A, + /* 0000020F cmp ax,0x4f03 */ 0x3D, 0x03, 0x4F, + /* 00000212 jz word 0x331 */ 0x0F, 0x84, 0x1B, 0x01, + /* 00000216 cmp ax,0x4f10 */ 0x3D, 0x10, 0x4F, + /* 00000219 jz word 0x336 */ 0x0F, 0x84, 0x19, 0x01, + /* 0000021D cmp ax,0x4f15 */ 0x3D, 0x15, 0x4F, + /* 00000220 jz word 0x338 */ 0x0F, 0x84, 0x14, 0x01, + /* 00000224 cmp ah,0x0 */ 0x80, 0xFC, 0x00, + /* 00000227 jz word 0x33a */ 0x0F, 0x84, 0x0F, 0x01, + /* 0000022B jmp short 0x22b */ 0xEB, 0xFE, + /* 0000022D push es */ 0x06, + /* 0000022E push di */ 0x57, + /* 0000022F push ds */ 0x1E, + /* 00000230 push si */ 0x56, + /* 00000231 push cx */ 0x51, + /* 00000232 push cs */ 0x0E, + /* 00000233 pop ds */ 0x1F, + /* 00000234 mov si,0x0 */ 0xBE, 0x00, 0x00, + /* 00000237 mov cx,0x100 */ 0xB9, 0x00, 0x01, + /* 0000023A cld */ 0xFC, + /* 0000023B rep movsb */ 0xF3, 0xA4, + /* 0000023D pop cx */ 0x59, + /* 0000023E pop si */ 0x5E, + /* 0000023F pop ds */ 0x1F, + /* 00000240 pop di */ 0x5F, + /* 00000241 pop es */ 0x07, + /* 00000242 jmp word 0x34c */ 0xE9, 0x07, 0x01, + /* 00000245 push es */ 0x06, + /* 00000246 push di */ 0x57, + /* 00000247 push ds */ 0x1E, + /* 00000248 push si */ 0x56, + /* 00000249 push cx */ 0x51, + /* 0000024A and cx,0xbfff */ 0x81, 0xE1, 0xFF, 0xBF, + /* 0000024E cmp cx,0xf1 */ 0x81, 0xF9, 0xF1, 0x00, + /* 00000252 jz 0x256 */ 0x74, 0x02, + /* 00000254 jmp short 0x22b */ 0xEB, 0xD5, + /* 00000256 push cs */ 0x0E, + /* 00000257 pop ds */ 0x1F, + /* 00000258 mov si,0x100 */ 0xBE, 0x00, 0x01, + /* 0000025B mov cx,0x100 */ 0xB9, 0x00, 0x01, + /* 0000025E cld */ 0xFC, + /* 0000025F rep movsb */ 0xF3, 0xA4, + /* 00000261 pop cx */ 0x59, + /* 00000262 pop si */ 0x5E, + /* 00000263 pop ds */ 0x1F, + /* 00000264 pop di */ 0x5F, + /* 00000265 pop es */ 0x07, + /* 00000266 jmp word 0x34c */ 0xE9, 0xE3, 0x00, + /* 00000269 push dx */ 0x52, + /* 0000026A push ax */ 0x50, + /* 0000026B cmp bx,0x40f1 */ 0x81, 0xFB, 0xF1, 0x40, + /* 0000026F jz 0x273 */ 0x74, 0x02, + /* 00000271 jmp short 0x22b */ 0xEB, 0xB8, + /* 00000273 mov dx,0x3c0 */ 0xBA, 0xC0, 0x03, + /* 00000276 mov al,0x20 */ 0xB0, 0x20, + /* 00000278 out dx,al */ 0xEE, + /* 00000279 push dx */ 0x52, + /* 0000027A push ax */ 0x50, + /* 0000027B mov dx,0x1ce */ 0xBA, 0xCE, 0x01, + /* 0000027E mov ax,0x4 */ 0xB8, 0x04, 0x00, + /* 00000281 out dx,ax */ 0xEF, + /* 00000282 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, + /* 00000285 mov ax,0x0 */ 0xB8, 0x00, 0x00, + /* 00000288 out dx,ax */ 0xEF, + /* 00000289 pop ax */ 0x58, + /* 0000028A pop dx */ 0x5A, + /* 0000028B push dx */ 0x52, + /* 0000028C push ax */ 0x50, + /* 0000028D mov dx,0x1ce */ 0xBA, 0xCE, 0x01, + /* 00000290 mov ax,0x5 */ 0xB8, 0x05, 0x00, + /* 00000293 out dx,ax */ 0xEF, + /* 00000294 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, + /* 00000297 mov ax,0x0 */ 0xB8, 0x00, 0x00, + /* 0000029A out dx,ax */ 0xEF, + /* 0000029B pop ax */ 0x58, + /* 0000029C pop dx */ 0x5A, + /* 0000029D push dx */ 0x52, + /* 0000029E push ax */ 0x50, + /* 0000029F mov dx,0x1ce */ 0xBA, 0xCE, 0x01, + /* 000002A2 mov ax,0x8 */ 0xB8, 0x08, 0x00, + /* 000002A5 out dx,ax */ 0xEF, + /* 000002A6 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, + /* 000002A9 mov ax,0x0 */ 0xB8, 0x00, 0x00, + /* 000002AC out dx,ax */ 0xEF, + /* 000002AD pop ax */ 0x58, + /* 000002AE pop dx */ 0x5A, + /* 000002AF push dx */ 0x52, + /* 000002B0 push ax */ 0x50, + /* 000002B1 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, + /* 000002B4 mov ax,0x9 */ 0xB8, 0x09, 0x00, + /* 000002B7 out dx,ax */ 0xEF, + /* 000002B8 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, + /* 000002BB mov ax,0x0 */ 0xB8, 0x00, 0x00, + /* 000002BE out dx,ax */ 0xEF, + /* 000002BF pop ax */ 0x58, + /* 000002C0 pop dx */ 0x5A, + /* 000002C1 push dx */ 0x52, + /* 000002C2 push ax */ 0x50, + /* 000002C3 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, + /* 000002C6 mov ax,0x3 */ 0xB8, 0x03, 0x00, + /* 000002C9 out dx,ax */ 0xEF, + /* 000002CA mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, + /* 000002CD mov ax,0x20 */ 0xB8, 0x20, 0x00, + /* 000002D0 out dx,ax */ 0xEF, + /* 000002D1 pop ax */ 0x58, + /* 000002D2 pop dx */ 0x5A, + /* 000002D3 push dx */ 0x52, + /* 000002D4 push ax */ 0x50, + /* 000002D5 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, + /* 000002D8 mov ax,0x1 */ 0xB8, 0x01, 0x00, + /* 000002DB out dx,ax */ 0xEF, + /* 000002DC mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, + /* 000002DF mov ax,0x400 */ 0xB8, 0x00, 0x04, + /* 000002E2 out dx,ax */ 0xEF, + /* 000002E3 pop ax */ 0x58, + /* 000002E4 pop dx */ 0x5A, + /* 000002E5 push dx */ 0x52, + /* 000002E6 push ax */ 0x50, + /* 000002E7 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, + /* 000002EA mov ax,0x6 */ 0xB8, 0x06, 0x00, + /* 000002ED out dx,ax */ 0xEF, + /* 000002EE mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, + /* 000002F1 mov ax,0x400 */ 0xB8, 0x00, 0x04, + /* 000002F4 out dx,ax */ 0xEF, + /* 000002F5 pop ax */ 0x58, + /* 000002F6 pop dx */ 0x5A, + /* 000002F7 push dx */ 0x52, + /* 000002F8 push ax */ 0x50, + /* 000002F9 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, + /* 000002FC mov ax,0x2 */ 0xB8, 0x02, 0x00, + /* 000002FF out dx,ax */ 0xEF, + /* 00000300 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, + /* 00000303 mov ax,0x300 */ 0xB8, 0x00, 0x03, + /* 00000306 out dx,ax */ 0xEF, + /* 00000307 pop ax */ 0x58, + /* 00000308 pop dx */ 0x5A, + /* 00000309 push dx */ 0x52, + /* 0000030A push ax */ 0x50, + /* 0000030B mov dx,0x1ce */ 0xBA, 0xCE, 0x01, + /* 0000030E mov ax,0x7 */ 0xB8, 0x07, 0x00, + /* 00000311 out dx,ax */ 0xEF, + /* 00000312 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, + /* 00000315 mov ax,0x300 */ 0xB8, 0x00, 0x03, + /* 00000318 out dx,ax */ 0xEF, + /* 00000319 pop ax */ 0x58, + /* 0000031A pop dx */ 0x5A, + /* 0000031B push dx */ 0x52, + /* 0000031C push ax */ 0x50, + /* 0000031D mov dx,0x1ce */ 0xBA, 0xCE, 0x01, + /* 00000320 mov ax,0x4 */ 0xB8, 0x04, 0x00, + /* 00000323 out dx,ax */ 0xEF, + /* 00000324 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, + /* 00000327 mov ax,0x41 */ 0xB8, 0x41, 0x00, + /* 0000032A out dx,ax */ 0xEF, + /* 0000032B pop ax */ 0x58, + /* 0000032C pop dx */ 0x5A, + /* 0000032D pop ax */ 0x58, + /* 0000032E pop dx */ 0x5A, + /* 0000032F jmp short 0x34c */ 0xEB, 0x1B, + /* 00000331 mov bx,0x40f1 */ 0xBB, 0xF1, 0x40, + /* 00000334 jmp short 0x34c */ 0xEB, 0x16, + /* 00000336 jmp short 0x350 */ 0xEB, 0x18, + /* 00000338 jmp short 0x350 */ 0xEB, 0x16, + /* 0000033A cmp al,0x3 */ 0x3C, 0x03, + /* 0000033C jz 0x345 */ 0x74, 0x07, + /* 0000033E cmp al,0x12 */ 0x3C, 0x12, + /* 00000340 jz 0x349 */ 0x74, 0x07, + /* 00000342 jmp word 0x22b */ 0xE9, 0xE6, 0xFE, + /* 00000345 mov al,0x30 */ 0xB0, 0x30, + /* 00000347 jmp short 0x34b */ 0xEB, 0x02, + /* 00000349 mov al,0x20 */ 0xB0, 0x20, + /* 0000034B iretw */ 0xCF, + /* 0000034C mov ax,0x4f */ 0xB8, 0x4F, 0x00, + /* 0000034F iretw */ 0xCF, + /* 00000350 mov ax,0x14f */ 0xB8, 0x4F, 0x01, + /* 00000353 iretw */ 0xCF, +}; +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/VbeShim.sh b/= Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/VbeShim.sh new file mode 100644 index 0000000000..7669f8a219 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsVideoDxe/VbeShim.sh @@ -0,0 +1,79 @@ +#!/bin/sh +### +# @file +# Shell script to assemble and dump the fake Int10h handler from NASM sour= ce to +# a C array. +# +# Copyright (C) 2014, Red Hat, Inc. +# Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +### + +set -e -u + +STEM=3D$(dirname -- "$0")/$(basename -- "$0" .sh) + +# +# Install exit handler -- remove temporary files. +# +exit_handler() +{ + rm -f -- "$STEM".bin "$STEM".disasm "$STEM".offsets "$STEM".insns \ + "$STEM".bytes +} +trap exit_handler EXIT + +# +# Assemble the source file. +# +nasm -o "$STEM".bin -- "$STEM".asm + +# +# Disassemble it, in order to get a binary dump associated with the source. +# (ndisasm doesn't recognize the "--" end-of-options delimiter.) +# +ndisasm "$STEM".bin >"$STEM".disasm + +# +# Create three files, each with one column of the disassembly. +# +# The first column contains the offsets, and it starts the comment. +# +cut -c 1-8 -- "$STEM".disasm \ +| sed -e 's,^, /* ,' >"$STEM".offsets + +# +# The second column contains the assembly-language instructions, and it cl= oses +# the comment. We first pad it to 30 characters. +# +cut -c 29- -- "$STEM".disasm \ +| sed -e 's,$, ,' \ + -e 's,^\(.\{30\}\).*$,\1 */,' >"$STEM".insns + +# +# The third column contains the bytes corresponding to the instruction, +# represented as C integer constants. First strip trailing whitespace from= the +# middle column of the input disassembly, then process pairs of nibbles. +# +cut -c 11-28 -- "$STEM".disasm \ +| sed -e 's, \+$,,' -e 's/\(..\)/ 0x\1,/g' >"$STEM".bytes + +# +# Write the output file, recombining the columns. The output should have C= RLF +# line endings. +# +{ + printf '//\n' + printf '// THIS FILE WAS GENERATED BY "%s". DO NOT EDIT.\n' \ + "$(basename -- "$0")" + printf '//\n' + printf '#ifndef _VBE_SHIM_H_\n' + printf '#define _VBE_SHIM_H_\n' + printf 'STATIC CONST UINT8 mVbeShim[] =3D {\n' + paste -d ' ' -- "$STEM".offsets "$STEM".insns "$STEM".bytes + printf '};\n' + printf '#endif\n' +} \ +| unix2dos >"$STEM".h --=20 2.16.2.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 (#46949): https://edk2.groups.io/g/devel/message/46949 Mute This Topic: https://groups.io/mt/33159244/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Fri Apr 26 02:55:24 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+46948+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+46948+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1567719525; cv=none; d=zoho.com; s=zohoarc; b=Cjz3/iiCjyoHhprLrvSTeuV5PK5atYPuDv1OUUI7wtOW27/5/igGb/mFDtNUWLeZF2S4h9M0ETJZ1PrWkGqRbvsgbLl0MxNox2AlSxLwZLMBaqA0wGceKiA2DCUU4sq37cK+R4ibeW13oO+xxWKzeGU1M/AD6IhT9eniWgo/+E0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1567719525; h=Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To:ARC-Authentication-Results; bh=X+YWu6NOdpf/zRPSd2GqlLZDZ+91W2OyOeDzVOWqdYI=; b=D09elWy3NrNdWx6f/iMFB0krVEcbxMXvmKaS+wli07/5e7ziPduvO3YdU41p1MNd9b7NeTsvYqWTMYGVLX4DEhiIok9/MEo4GfOwm7PgI4ZKsJl9IVQR4n7h3Q7tpOsQkhf+1ck90mRUbk4CyES2DfIAVilp7mLcKDkbyoiaino= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+46948+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1567719525243953.886420941007; Thu, 5 Sep 2019 14:38:45 -0700 (PDT) Return-Path: X-Received: from mga02.intel.com (mga02.intel.com []) by groups.io with SMTP; Thu, 05 Sep 2019 14:38:44 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Sep 2019 14:38:43 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,471,1559545200"; d="scan'208";a="267151629" X-Received: from ydwei-desk.amr.corp.intel.com ([10.24.15.168]) by orsmga001.jf.intel.com with ESMTP; 05 Sep 2019 14:38:42 -0700 From: "David Wei" To: devel@edk2.groups.io Cc: Hao Wu , Liming Gao , Ankit Sinha , Agyeman Prince , Kubacki Michael A , Nate DeSimone , Michael D Kinney Subject: [edk2-devel] [edk2-platforms PATCH v5 6/7] SimicsOpenBoardPkg/BoardX58Ich10: Add board modules for QSP Build tip Date: Thu, 5 Sep 2019 14:38:39 -0700 Message-Id: <832e6f6765d7e580d32e9b8ba0244da5af055a4c.1567718650.git.david.y.wei@intel.com> In-Reply-To: References: In-Reply-To: References: Precedence: Bulk List-Unsubscribe: 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,david.y.wei@intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1567719524; bh=8gtVgGjdzvB3JEFwmFBjcb1aHdGKFxDfNbFx4cjgGcI=; h=Cc:Date:From:Reply-To:Subject:To; b=ell6r3k0qiOeilOHt+NtZMusPWToAgVgJwSXilXARRkXPDLdInZZx6ICS/tLI48k6pJ zotYQMimO8NNlcioS6xuyoC3RriDIxkWu1m6qPguCam5Mtkgrv4Ry+UszkqYC/A+yzA3T aXajq18VEk6rpiLOBXxv/9nI/3nfXzpAO68= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add BoardX58ICH10 modules for QSP(Quick Start Platform) Build tip Cc: Hao Wu Cc: Liming Gao Cc: Ankit Sinha Cc: Agyeman Prince Cc: Kubacki Michael A Cc: Nate DeSimone Cc: Michael D Kinney Signed-off-by: David Wei --- .../Library/BoardInitLib/PeiBoardInitPostMemLib.c | 44 +++ .../Library/BoardInitLib/PeiBoardInitPreMemLib.c | 110 ++++++++ .../Library/BoardInitLib/PeiX58Ich10Detect.c | 26 ++ .../BoardInitLib/PeiX58Ich10InitPostMemLib.c | 34 +++ .../BoardInitLib/PeiX58Ich10InitPreMemLib.c | 111 ++++++++ .../BoardX58Ich10/DecomprScratchEnd.fdf.inc | 67 +++++ .../BoardInitLib/PeiBoardInitPostMemLib.inf | 36 +++ .../Library/BoardInitLib/PeiBoardInitPreMemLib.inf | 39 +++ .../Library/BoardInitLib/PeiX58Ich10InitLib.h | 16 ++ .../BoardX58Ich10/OpenBoardPkg.dsc | 233 ++++++++++++++++ .../BoardX58Ich10/OpenBoardPkg.fdf | 304 +++++++++++++++++= ++++ .../BoardX58Ich10/OpenBoardPkg.fdf.inc | 54 ++++ .../BoardX58Ich10/OpenBoardPkgBuildOption.dsc | 78 ++++++ .../BoardX58Ich10/OpenBoardPkgConfig.dsc | 56 ++++ .../BoardX58Ich10/OpenBoardPkgPcd.dsc | 281 +++++++++++++++++= ++ .../BoardX58Ich10/VarStore.fdf.inc | 53 ++++ .../BoardX58Ich10/build_config.cfg | 31 +++ 17 files changed, 1573 insertions(+) create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library= /BoardInitLib/PeiBoardInitPostMemLib.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library= /BoardInitLib/PeiBoardInitPreMemLib.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library= /BoardInitLib/PeiX58Ich10Detect.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library= /BoardInitLib/PeiX58Ich10InitPostMemLib.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library= /BoardInitLib/PeiX58Ich10InitPreMemLib.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Decompr= ScratchEnd.fdf.inc create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library= /BoardInitLib/PeiBoardInitPostMemLib.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library= /BoardInitLib/PeiBoardInitPreMemLib.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library= /BoardInitLib/PeiX58Ich10InitLib.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoa= rdPkg.dsc create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoa= rdPkg.fdf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoa= rdPkg.fdf.inc create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoa= rdPkgBuildOption.dsc create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoa= rdPkgConfig.dsc create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoa= rdPkgPcd.dsc create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/VarStor= e.fdf.inc create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/build_c= onfig.cfg diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardI= nitLib/PeiBoardInitPostMemLib.c b/Platform/Intel/SimicsOpenBoardPkg/BoardX5= 8Ich10/Library/BoardInitLib/PeiBoardInitPostMemLib.c new file mode 100644 index 0000000000..5ece8c6e34 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/= PeiBoardInitPostMemLib.c @@ -0,0 +1,44 @@ +/** @file + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include + +EFI_STATUS +EFIAPI +X58Ich10BoardInitBeforeSiliconInit ( + VOID + ); + +EFI_STATUS +EFIAPI +X58Ich10BoardInitAfterSiliconInit ( + VOID + ); + +EFI_STATUS +EFIAPI +BoardInitBeforeSiliconInit ( + VOID + ) +{ + X58Ich10BoardInitBeforeSiliconInit (); + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +BoardInitAfterSiliconInit ( + VOID + ) +{ + X58Ich10BoardInitAfterSiliconInit (); + return EFI_SUCCESS; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardI= nitLib/PeiBoardInitPreMemLib.c b/Platform/Intel/SimicsOpenBoardPkg/BoardX58= Ich10/Library/BoardInitLib/PeiBoardInitPreMemLib.c new file mode 100644 index 0000000000..d16e649d34 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/= PeiBoardInitPreMemLib.c @@ -0,0 +1,110 @@ +/** @file + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include + +EFI_STATUS +EFIAPI +X58Ich10BoardDetect( + VOID + ); + +EFI_BOOT_MODE +EFIAPI +X58Ich10BoardBootModeDetect ( + VOID + ); + +EFI_STATUS +EFIAPI +X58Ich10BoardDebugInit ( + VOID + ); + +EFI_STATUS +EFIAPI +X58Ich10BoardInitBeforeMemoryInit ( + VOID + ); + +EFI_STATUS +EFIAPI +X58Ich10BoardInitAfterMemoryInit ( + VOID + ); + +EFI_STATUS +EFIAPI +BoardDetect ( + VOID + ) +{ + X58Ich10BoardDetect (); + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +BoardDebugInit ( + VOID + ) +{ + X58Ich10BoardDebugInit (); + return EFI_SUCCESS; +} + +EFI_BOOT_MODE +EFIAPI +BoardBootModeDetect ( + VOID + ) +{ + return X58Ich10BoardBootModeDetect (); +} + +EFI_STATUS +EFIAPI +BoardInitBeforeMemoryInit ( + VOID + ) +{ + X58Ich10BoardInitBeforeMemoryInit (); + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +BoardInitAfterMemoryInit ( + VOID + ) +{ + X58Ich10BoardInitAfterMemoryInit (); + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +BoardInitBeforeTempRamExit ( + VOID + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +BoardInitAfterTempRamExit ( + VOID + ) +{ + return EFI_SUCCESS; +} + diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardI= nitLib/PeiX58Ich10Detect.c b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich1= 0/Library/BoardInitLib/PeiX58Ich10Detect.c new file mode 100644 index 0000000000..03488ef1f4 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/= PeiX58Ich10Detect.c @@ -0,0 +1,26 @@ +/** @file + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +EFI_STATUS +EFIAPI +X58Ich10BoardDetect ( + VOID + ) +{ + DEBUG ((EFI_D_INFO, "X58Ich10BoardDetect\n")); + return EFI_SUCCESS; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardI= nitLib/PeiX58Ich10InitPostMemLib.c b/Platform/Intel/SimicsOpenBoardPkg/Boar= dX58Ich10/Library/BoardInitLib/PeiX58Ich10InitPostMemLib.c new file mode 100644 index 0000000000..bd6924e269 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/= PeiX58Ich10InitPostMemLib.c @@ -0,0 +1,34 @@ +/** @file + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include + +#include "PeiX58Ich10InitLib.h" +EFI_STATUS +EFIAPI +X58Ich10BoardInitBeforeSiliconInit ( + VOID + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +X58Ich10BoardInitAfterSiliconInit ( + VOID + ) +{ + + DEBUG((EFI_D_ERROR, "X58Ich10BoardInitAfterSiliconInit\n")); + return EFI_SUCCESS; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardI= nitLib/PeiX58Ich10InitPreMemLib.c b/Platform/Intel/SimicsOpenBoardPkg/Board= X58Ich10/Library/BoardInitLib/PeiX58Ich10InitPreMemLib.c new file mode 100644 index 0000000000..c3a31ed426 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/= PeiX58Ich10InitPreMemLib.c @@ -0,0 +1,111 @@ +/** @file + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "PeiX58Ich10InitLib.h" +#include +/** + Reads 8-bits of CMOS data. + + Reads the 8-bits of CMOS data at the location specified by Index. + The 8-bit read value is returned. + + @param Index The CMOS location to read. + + @return The value read. + +**/ +UINT8 +EFIAPI +CmosRead8( + IN UINTN Index + ) +{ + IoWrite8 (0x70, (UINT8)Index); + return IoRead8(0x71); +} + + +/** + Writes 8-bits of CMOS data. + + Writes 8-bits of CMOS data to the location specified by Index + with the value specified by Value and returns Value. + + @param Index The CMOS location to write. + @param Value The value to write to CMOS. + + @return The value written to CMOS. + +**/ +UINT8 +EFIAPI +CmosWrite8( + IN UINTN Index, + IN UINT8 Value + ) +{ + IoWrite8 (0x70, (UINT8)Index); + IoWrite8 (0x71, Value); + return Value; +} + + +EFI_STATUS +EFIAPI +X58Ich10BoardInitBeforeMemoryInit ( + VOID + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +X58Ich10BoardInitAfterMemoryInit ( + VOID + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +X58Ich10BoardDebugInit ( + VOID + ) +{ + return EFI_SUCCESS; +} + +EFI_BOOT_MODE +EFIAPI +X58Ich10BoardBootModeDetect ( + VOID + ) +{ + EFI_BOOT_MODE BootMode =3D BOOT_WITH_FULL_CONFIGURATION; + + DEBUG((EFI_D_INFO, "modeValue =3D %x\n", IoBitFieldRead16(ICH10_PMBASE_I= O + 4, 10, 12))); + if (IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12) =3D=3D 0x5) { + BootMode =3D BOOT_ON_S3_RESUME; + } + + return BootMode; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/DecomprScratch= End.fdf.inc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/DecomprScratc= hEnd.fdf.inc new file mode 100644 index 0000000000..ae9a625da9 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/DecomprScratchEnd.fdf= .inc @@ -0,0 +1,67 @@ +## @file +# This FDF include file computes the end of the scratch buffer used in +# DecompressMemFvs() [SimicsX58Pkg/Sec/SecMain.c]. It is based on the dec= ompressed +# (ie. original) size of the LZMA-compressed section of the one FFS file = in +# the FVMAIN_COMPACT firmware volume. +# +# Copyright (C) 2015, Red Hat, Inc. +# Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +# The GUID EE4E5898-3914-4259-9D6E-DC7BD79403CF means "LzmaCustomDecompres= s". +# The decompressed output will have the following structure (see the file +# "9E21FD93-9C72-4c15-8C4B-E77F1DB2D792SEC1.guided.dummy" in the +# Build/SimicsX58*/*/FV/Ffs/9E21FD93-9C72-4c15-8C4B-E77F1DB2D792/ director= y): +# +# Size Contents +# ------------------- ---------------------------------------------------= ----- +# 4 EFI_COMMON_SECTION_HEADER, stating size 124 (0x7C) = and +# type 0x19 (EFI_SECTION_RAW). The purpose of this se= ction +# is to pad the start of PEIFV to 128 bytes. +# 120 Zero bytes (padding). +# +# 4 EFI_COMMON_SECTION_HEADER, stating size +# (PcdSimicsPeiMemFvSize + 4), and type 0x17 +# (EFI_SECTION_FIRMWARE_VOLUME_IMAGE). +# PcdSimicsPeiMemFvSize PEIFV. Note that the above sizes pad the offset o= f this +# object to 128 bytes. See also the "guided.dummy.txt" +# file in the same directory. +# +# 4 EFI_COMMON_SECTION_HEADER, stating size 12 (0xC) and +# type 0x19 (EFI_SECTION_RAW). The purpose of this se= ction +# is to pad the start of DXEFV to 16 bytes. +# 8 Zero bytes (padding). +# +# 4 EFI_COMMON_SECTION_HEADER, stating size +# (PcdSimicsDxeMemFvSize + 4), and type 0x17 +# (EFI_SECTION_FIRMWARE_VOLUME_IMAGE). +# PcdSimicsDxeMemFvSize DXEFV. Note that the above sizes pad the offset o= f this +# object to 16 bytes. See also the "guided.dummy.txt"= file +# in the same directory. +# +# The total size after decompression is (128 + PcdSimicsPeiMemFvSize + 16 + +# PcdSimicsDxeMemFvSize). + +DEFINE OUTPUT_SIZE =3D (128 + gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFv= Size + 16 + gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvSize) + +# LzmaCustomDecompressLib uses a constant scratch buffer size of 64KB; see +# SCRATCH_BUFFER_REQUEST_SIZE in +# "MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaDecompress.c". + +DEFINE DECOMP_SCRATCH_SIZE =3D 0x00010000 + +# Note: when we use PcdSimicsDxeMemFvBase in this context, BaseTools have = not yet +# offset it with MEMFD's base address. For that reason we have to do it ma= nually. +# +# The calculation below mirrors DecompressMemFvs() [SimicsX58Pkg/Sec/SecMa= in.c]. + +DEFINE OUTPUT_BASE =3D ($(MEMFD_BASE_ADDRESS) + gBoardMo= duleTokenSpaceGuid.PcdSimicsDxeMemFvBase + 0x00100000) +DEFINE DECOMP_SCRATCH_BASE_UNALIGNED =3D ($(OUTPUT_BASE) + $(OUTPUT_SIZE)) +DEFINE DECOMP_SCRATCH_BASE_ALIGNMENT =3D 0x000FFFFF +DEFINE DECOMP_SCRATCH_BASE_MASK =3D 0xFFF00000 +DEFINE DECOMP_SCRATCH_BASE =3D (($(DECOMP_SCRATCH_BASE_UNALIGNED= ) + $(DECOMP_SCRATCH_BASE_ALIGNMENT)) & $(DECOMP_SCRATCH_BASE_MASK)) + +SET gBoardModuleTokenSpaceGuid.PcdSimicsDecompressionScratchEnd =3D $(DECO= MP_SCRATCH_BASE) + $(DECOMP_SCRATCH_SIZE) diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardI= nitLib/PeiBoardInitPostMemLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Board= X58Ich10/Library/BoardInitLib/PeiBoardInitPostMemLib.inf new file mode 100644 index 0000000000..a035eb0e50 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/= PeiBoardInitPostMemLib.inf @@ -0,0 +1,36 @@ +## @file +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D PeiBoardPostMemInitLib + FILE_GUID =3D 30F407D6-6B92-412A-B2DA-8E73E2B386E6 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D BoardInitLib + +[LibraryClasses] + BaseLib + DebugLib + BaseMemoryLib + MemoryAllocationLib + PcdLib + +[Packages] + MinPlatformPkg/MinPlatformPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[Sources] + PeiX58Ich10InitPostMemLib.c + PeiBoardInitPostMemLib.c + +[FixedPcd] + +[Pcd] + diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardI= nitLib/PeiBoardInitPreMemLib.inf b/Platform/Intel/SimicsOpenBoardPkg/BoardX= 58Ich10/Library/BoardInitLib/PeiBoardInitPreMemLib.inf new file mode 100644 index 0000000000..08a6eb159a --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/= PeiBoardInitPreMemLib.inf @@ -0,0 +1,39 @@ +## @file +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D PeiBoardInitPreMemLib + FILE_GUID =3D 73AA24AE-FB20-43F9-A3BA-448953A03A78 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D BoardInitLib + +[LibraryClasses] + BaseLib + DebugLib + BaseMemoryLib + MemoryAllocationLib + PcdLib + +[Packages] + MinPlatformPkg/MinPlatformPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SimicsOpenBoardPkg/OpenBoardPkg.dec + SimicsIch10Pkg/Ich10Pkg.dec + +[Sources] + PeiX58Ich10Detect.c + PeiX58Ich10InitPreMemLib.c + PeiBoardInitPreMemLib.c + +[Pcd] + +[FixedPcd] + diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardI= nitLib/PeiX58Ich10InitLib.h b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich= 10/Library/BoardInitLib/PeiX58Ich10InitLib.h new file mode 100644 index 0000000000..93544a838b --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/= PeiX58Ich10InitLib.h @@ -0,0 +1,16 @@ +/** @file + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _PEI_X58Ich10_BOARD_INIT_LIB_H_ +#define _PEI_X58Ich10_BOARD_INIT_LIB_H_ + +#include +#include +#include +#include +#include + +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.d= sc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.dsc new file mode 100644 index 0000000000..59e13154a7 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.dsc @@ -0,0 +1,233 @@ +## @file +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +##########################################################################= ###### +# +# Defines Section - statements that will be processed to create a Makefile. +# +##########################################################################= ###### +[Defines] + DEFINE PLATFORM_PACKAGE =3D MinPlatformPkg + DEFINE BOARD_NAME =3D BoardX58Ich10 + DEFINE BOARD_PKG =3D SimicsOpenBoardPkg + DEFINE SKT_PKG =3D SimicsX58SktPkg + DEFINE PCH_PKG =3D SimicsIch10Pkg + DEFINE DXE_ARCH =3D X64 + DEFINE PEI_ARCH =3D IA32 + + PLATFORM_NAME =3D SimicsX58 + PLATFORM_GUID =3D EE8EBB5A-CC95-412f-9987-2AF70F88B69A + PLATFORM_VERSION =3D 0.1 + DSC_SPECIFICATION =3D 0x00010005 + OUTPUT_DIRECTORY =3D Build/SimicsX58Ia32X64 + SUPPORTED_ARCHITECTURES =3D IA32|X64 + BUILD_TARGETS =3D DEBUG|RELEASE|NOOPT + SKUID_IDENTIFIER =3D DEFAULT + FLASH_DEFINITION =3D $(BOARD_PKG)/$(BOARD_NAME)/OpenBoardP= kg.fdf + + DEFINE SMM_REQUIRE =3D TRUE + + # + #PLATFORMX64_ENABLE is set to TRUE when PEI is IA32 and DXE is X64 platf= orm + # + DEFINE PLATFORMX64_ENABLE =3D TRUE + DEFINE NETWORK_TLS_ENABLE =3D FALSE + DEFINE NETWORK_ISCSI_ENABLE =3D FALSE + DEFINE NETWORK_ALLOW_HTTP_CONNECTIONS =3D TRUE + !include NetworkPkg/NetworkDefines.dsc.inc +##########################################################################= ###### +# +# SKU Identification section - list of all SKU IDs supported by this Platf= orm. +# +##########################################################################= ###### +[SkuIds] + 0|DEFAULT + +##########################################################################= ###### +# +# Library Class section - list of all Library Classes needed by this Platf= orm. +# +##########################################################################= ###### + +[PcdsFeatureFlag] + # + # Platform On/Off features are defined here + # + !include $(BOARD_PKG)/$(BOARD_NAME)/OpenBoardPkgConfig.dsc + !include MinPlatformPkg/Include/Dsc/CoreCommonLib.dsc + !include $(PCH_PKG)/IchCommonLib.dsc + +[LibraryClasses] + ReportFvLib|$(BOARD_PKG)/Library/PeiReportFvLib/PeiReportFvLib.inf + BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf + SerialPortLib|PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf + NvVarsFileLib|$(BOARD_PKG)/Library/NvVarsFileLib/NvVarsFileLib.inf + SerializeVariablesLib|$(BOARD_PKG)/Library/SerializeVariablesLib/Seriali= zeVariablesLib.inf + DxeLoadLinuxLib|$(BOARD_PKG)/Library/LoadLinuxLib/DxeLoadLinuxLib.inf + CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/C= puExceptionHandlerLibNull.inf + + TestPointCheckLib|MinPlatformPkg/Test/Library/TestPointCheckLibNull/Test= PointCheckLibNull.inf + BoardInitLib|MinPlatformPkg/PlatformInit/Library/BoardInitLibNull/BoardI= nitLibNull.inf + SiliconPolicyInitLib|$(BOARD_PKG)/Policy/Library/SiliconPolicyInitLib/Si= liconPolicyInitLib.inf + SiliconPolicyUpdateLib|$(BOARD_PKG)/Policy/Library/SiliconPolicyUpdateLi= b/SiliconPolicyUpdateLib.inf + PciSegmentInfoLib|MinPlatformPkg/Pci/Library/PciSegmentInfoLibSimple/Pci= SegmentInfoLibSimple.inf + + !include MinPlatformPkg/Include/Dsc/CorePeiLib.dsc + + S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScrip= tLib.inf + AslUpdateLib|MinPlatformPkg/Acpi/Library/DxeAslUpdateLib/DxeAslUpdateLib= .inf + LogoLib|$(BOARD_PKG)/Library/DxeLogoLib/DxeLogoLib.inf +[LibraryClasses.common.SEC] + ExtractGuidedSectionLib|MdePkg/Library/BaseExtractGuidedSectionLib/BaseE= xtractGuidedSectionLib.inf + +[LibraryClasses.common.PEI_CORE] + +[LibraryClasses.common.PEIM] + PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiRe= sourcePublicationLib.inf + MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf + +[LibraryClasses.IA32] +!if $(TARGET) =3D=3D DEBUG + TestPointCheckLib|MinPlatformPkg/Test/Library/TestPointCheckLib/PeiTestP= ointCheckLib.inf +!endif + TestPointLib|MinPlatformPkg/Test/Library/TestPointLib/PeiTestPointLib.inf + + !include MinPlatformPkg/Include/Dsc/CoreDxeLib.dsc + +[LibraryClasses.common.DXE_DRIVER] + PlatformBootManagerLib|$(BOARD_PKG)/Library/PlatformBootManagerLib/Platf= ormBootManagerLib.inf + +[LibraryClasses.common.DXE_SMM_DRIVER] + SpiFlashCommonLib|$(PCH_PKG)/Library/SmmSpiFlashCommonLib/SmmSpiFlashCom= monLib.inf + + !include $(BOARD_PKG)/$(BOARD_NAME)/OpenBoardPkgPcd.dsc + +[Components.IA32] + $(BOARD_PKG)/SecCore/SecMain.inf { + + NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompre= ssLib.inf + } + !include $(SKT_PKG)/SktPkgPei.dsc + !include MinPlatformPkg/Include/Dsc/CorePeiInclude.dsc + + $(BOARD_PKG)/SimicsPei/SimicsPei.inf { + + PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf + } +# S3 SMM driver +# UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf + UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf { + + LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf + } + +!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly =3D=3D FALSE + $(SKT_PKG)/Smm/Access/SmmAccessPei.inf { + + PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf + } +!endif + $(PLATFORM_PACKAGE)/PlatformInit/ReportFv/ReportFvPei.inf + + MinPlatformPkg/PlatformInit/PlatformInitPei/PlatformInitPreMem.inf { + + BoardInitLib|$(BOARD_PKG)/$(BOARD_NAME)/Library/BoardInitLib/PeiBoar= dInitPreMemLib.inf + } + MinPlatformPkg/PlatformInit/PlatformInitPei/PlatformInitPostMem.inf { + + BoardInitLib|$(BOARD_PKG)/$(BOARD_NAME)/Library/BoardInitLib/PeiBoar= dInitPostMemLib.inf + } + MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPreMem.inf + MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPostMem.inf + +[Components.X64] + !include MinPlatformPkg/Include/Dsc/CoreDxeInclude.dsc + !include AdvancedFeaturePkg/Include/Dsc/CoreAdvancedDxeInclude.dsc + + MdeModulePkg/Universal/EbcDxe/EbcDxe.inf + + MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf + # + # ISA Support + # + $(BOARD_PKG)/LegacySioDxe/LegacySioDxe.inf + MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf + + $(BOARD_PKG)/SmbiosPlatformDxe/SmbiosPlatformDxe.inf + $(BOARD_PKG)/AcpiTables/AcpiTables.inf + # + # Video support + # + $(BOARD_PKG)/SimicsVideoDxe/SimicsVideoDxe.inf + + MinPlatformPkg/PlatformInit/PlatformInitDxe/PlatformInitDxe.inf + MinPlatformPkg/PlatformInit/PlatformInitSmm/PlatformInitSmm.inf + $(BOARD_PKG)/SimicsDxe/SimicsDxe.inf + MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf + MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.= inf + + SimicsIch10BinPkg/UndiBinary/UndiDxe.inf + + # + # Shell + # + ShellPkg/Application/Shell/Shell.inf { + + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE + + NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2Comma= ndsLib.inf + NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1Comma= ndsLib.inf + NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3Comma= ndsLib.inf + NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1Com= mandsLib.inf + NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1C= ommandsLib.inf + NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1Comma= ndsLib.inf + NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1C= ommandsLib.inf + NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2C= ommandsLib.inf + ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommand= Lib.inf + HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandlePars= ingLib.inf + BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfg= CommandLib.inf + ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib= .inf + ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf + } + +!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly =3D=3D FALSE + $(SKT_PKG)/Smm/Access/SmmAccess2Dxe.inf + $(PCH_PKG)/SmmControl/RuntimeDxe/SmmControl2Dxe.inf + UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf + $(PCH_PKG)/Spi/Smm/PchSpiSmm.inf + MinPlatformPkg/Flash/SpiFvbService/SpiFvbServiceSmm.inf + UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf + MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf { + + LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf + } +!endif + MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf + MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf + MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf { + + PciHostBridgeLib|$(BOARD_PKG)/Library/PciHostBridgeLib/PciHostBridge= Lib.inf + } + MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf + + UefiCpuPkg/CpuDxe/CpuDxe.inf + MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf + MdeModulePkg/Universal/PrintDxe/PrintDxe.inf + MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf + MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf + # + # ACPI Support + # + MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf + $(BOARD_PKG)/AcpiTables/MinPlatformAcpiTables/AcpiPlatform.inf + +!if gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosEnable =3D=3D TRUE + AdvancedFeaturePkg/Smbios/SmbiosBasicDxe/SmbiosBasicDxe.inf +!endif + + !include $(BOARD_PKG)/$(BOARD_NAME)/OpenBoardPkgBuildOption.dsc diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.f= df b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.fdf new file mode 100644 index 0000000000..6c1579bef7 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.fdf @@ -0,0 +1,304 @@ +## @file +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] +!include OpenBoardPkg.fdf.inc + +# +# Build the variable store and the firmware code as one unified flash devi= ce +# image. +# +[FD.SIMICSX58IA32X64] +BaseAddress =3D $(FW_BASE_ADDRESS) +Size =3D $(FW_SIZE) +ErasePolarity =3D 1 +BlockSize =3D $(BLOCK_SIZE) +NumBlocks =3D $(FW_BLOCKS) + +!include VarStore.fdf.inc + +$(VARS_SIZE)|0x00002000 +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|gEfiMdeModu= lePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize +#NV_FTW_WORKING +DATA =3D { + # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature =3D gEdkiiWorkingBl= ockSignatureGuid =3D + # { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0= x1b, 0x95 }} + 0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49, + 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95, + # Crc:UINT32 #WorkingBlockValid:1, WorkingBlockInvalid:1, Res= erved + 0xE2, 0x33, 0xF2, 0x03, 0xFE, 0xFF, 0xFF, 0xFF, + # WriteQueueSize: UINT64 + 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +} + +0x00040000|0x00040000 +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfiMdeModule= PkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize +#NV_FTW_SPARE + +0x00080000|0x0016C000 +FV =3D FVMAIN_COMPACT + +$(SECFV_OFFSET)|$(SECFV_SIZE) +FV =3D FvTempMemorySilicon + +# +# Build the variable store and the firmware code as separate flash device +# images. +# +[FD.SIMICS_VARS] +BaseAddress =3D $(FW_BASE_ADDRESS) +Size =3D 0x80000 +ErasePolarity =3D 1 +BlockSize =3D $(BLOCK_SIZE) +NumBlocks =3D 0x80 + +!include VarStore.fdf.inc + +[FD.SIMICS_CODE] +BaseAddress =3D $(CODE_BASE_ADDRESS) +Size =3D $(CODE_SIZE) +ErasePolarity =3D 1 +BlockSize =3D $(BLOCK_SIZE) +NumBlocks =3D $(CODE_BLOCKS) + +0x00000000|0x0016C000 +FV =3D FVMAIN_COMPACT + +0x0016C000|$(SECFV_SIZE) +FV =3D FvTempMemorySilicon + +[FD.MEMFD] +BaseAddress =3D $(MEMFD_BASE_ADDRESS) +Size =3D 0xB00000 +ErasePolarity =3D 1 +BlockSize =3D 0x10000 +NumBlocks =3D 0xB0 + +0x000000|0x006000 +gBoardModuleTokenSpaceGuid.PcdSimicsSecPageTablesBase|gBoardModuleTokenSpa= ceGuid.PcdSimicsSecPageTablesSize + +0x006000|0x001000 +gBoardModuleTokenSpaceGuid.PcdSimicsLockBoxStorageBase|gBoardModuleTokenSp= aceGuid.PcdSimicsLockBoxStorageSize + +0x007000|0x001000 +gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gBoardModuleT= okenSpaceGuid.PcdGuidedExtractHandlerTableSize + +0x010000|0x008000 +gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamBase|gBoardModuleTokenSpa= ceGuid.PcdSimicsSecPeiTempRamSize + +0x020000|0x0E0000 +gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvBase|gBoardModuleTokenSpaceGui= d.PcdSimicsPeiMemFvSize +FV =3D FvPreMemory + +0x100000|0xA00000 +gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvBase|gBoardModuleTokenSpaceGui= d.PcdSimicsDxeMemFvSize +FV =3D DXEFV + +##########################################################################= ###### + +[FV.FvTempMemorySilicon] +FvAlignment =3D 16 +FvForceRebase =3D TRUE +ERASE_POLARITY =3D 1 +MEMORY_MAPPED =3D TRUE +STICKY_WRITE =3D TRUE +LOCK_CAP =3D TRUE +LOCK_STATUS =3D TRUE +WRITE_DISABLED_CAP =3D TRUE +WRITE_ENABLED_CAP =3D TRUE +WRITE_STATUS =3D TRUE +WRITE_LOCK_CAP =3D TRUE +WRITE_LOCK_STATUS =3D TRUE +READ_DISABLED_CAP =3D TRUE +READ_ENABLED_CAP =3D TRUE +READ_STATUS =3D TRUE +READ_LOCK_CAP =3D TRUE +READ_LOCK_STATUS =3D TRUE +FvNameGuid =3D 229EEDCE-8E76-4809-B233-EC36BFBF6989 + +INF RuleOverride=3DRESET_SECMAIN USE =3D IA32 $(BOARD_PKG)/SecCore/SecMai= n.inf +!include $(SKT_PKG)/SktSecInclude.fdf + +[FV.FvPreMemory] +FvAlignment =3D 16 +FvForceRebase =3D TRUE +ERASE_POLARITY =3D 1 +MEMORY_MAPPED =3D TRUE +STICKY_WRITE =3D TRUE +LOCK_CAP =3D TRUE +LOCK_STATUS =3D TRUE +WRITE_DISABLED_CAP =3D TRUE +WRITE_ENABLED_CAP =3D TRUE +WRITE_STATUS =3D TRUE +WRITE_LOCK_CAP =3D TRUE +WRITE_LOCK_STATUS =3D TRUE +READ_DISABLED_CAP =3D TRUE +READ_ENABLED_CAP =3D TRUE +READ_STATUS =3D TRUE +READ_LOCK_CAP =3D TRUE +READ_LOCK_STATUS =3D TRUE +FvNameGuid =3D 6522280D-28F9-4131-ADC4-F40EBFA45864 + +## +# PEI Apriori file example, more PEIM module added later. +## +INF MdeModulePkg/Core/Pei/PeiMain.inf +!include $(SKT_PKG)/SktPreMemoryInclude.fdf +!include $(PCH_PKG)/IchPreMemoryInclude.fdf +!include MinPlatformPkg/Include/Fdf/CorePreMemoryInclude.fdf +INF MinPlatformPkg/PlatformInit/ReportFv/ReportFvPei.inf +INF MinPlatformPkg/PlatformInit/PlatformInitPei/PlatformInitPreMem.inf +INF MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPreMem.i= nf +!include MinPlatformPkg/Include/Fdf/CoreSecurityPreMemoryInclude.fdf +!include AdvancedFeaturePkg/Include/Fdf/CoreAdvancedPreMemoryInclude.fdf +INF $(BOARD_PKG)/SimicsPei/SimicsPei.inf +!include $(SKT_PKG)/SktPostMemoryInclude.fdf +!include $(PCH_PKG)/IchPostMemoryInclude.fdf +!include MinPlatformPkg/Include/Fdf/CorePostMemoryInclude.fdf +INF MinPlatformPkg/PlatformInit/PlatformInitPei/PlatformInitPostMem.inf +INF MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPostMem.= inf +!include MinPlatformPkg/Include/Fdf/CoreSecurityPostMemoryInclude.fdf +!include AdvancedFeaturePkg/Include/Fdf/CoreAdvancedPostMemoryInclude.fdf + +INF UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf +INF $(SKT_PKG)/Smm/Access/SmmAccessPei.inf +# S3 SMM PEI driver +#INF UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf + +[FV.DXEFV] +FvNameGuid =3D EACAB9EA-C3C6-4438-8FD7-2270826DC0BB +BlockSize =3D 0x10000 +FvAlignment =3D 16 +ERASE_POLARITY =3D 1 +MEMORY_MAPPED =3D TRUE +STICKY_WRITE =3D TRUE +LOCK_CAP =3D TRUE +LOCK_STATUS =3D TRUE +WRITE_DISABLED_CAP =3D TRUE +WRITE_ENABLED_CAP =3D TRUE +WRITE_STATUS =3D TRUE +WRITE_LOCK_CAP =3D TRUE +WRITE_LOCK_STATUS =3D TRUE +READ_DISABLED_CAP =3D TRUE +READ_ENABLED_CAP =3D TRUE +READ_STATUS =3D TRUE +READ_LOCK_CAP =3D TRUE +READ_LOCK_STATUS =3D TRUE + +!include MinPlatformPkg/Include/Fdf/CoreUefiBootInclude.fdf +!include $(SKT_PKG)/SktUefiBootInclude.fdf +!include $(PCH_PKG)/IchUefiBootInclude.fdf + +INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf +INF MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf +INF UefiCpuPkg/CpuDxe/CpuDxe.inf + +!include MinPlatformPkg/Include/Fdf/CoreOsBootInclude.fdf +INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf +INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorD= xe.inf +INF UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf +INF MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf +INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf +INF MdeModulePkg/Universal/PrintDxe/PrintDxe.inf +INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf +INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf + +INF MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf +INF MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf +INF MinPlatformPkg/Flash/SpiFvbService/SpiFvbServiceSmm.inf +INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf + +INF $(BOARD_PKG)/LegacySioDxe/LegacySioDxe.inf +INF MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf + +INF $(BOARD_PKG)/SmbiosPlatformDxe/SmbiosPlatformDxe.inf + +INF MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf +INF $(BOARD_PKG)/AcpiTables/MinPlatformAcpiTables/AcpiPlatform.inf +INF RuleOverride=3DACPITABLE $(BOARD_PKG)/AcpiTables/AcpiTables.inf + +INF $(BOARD_PKG)/SimicsVideoDxe/SimicsVideoDxe.inf +INF MinPlatformPkg/PlatformInit/PlatformInitDxe/PlatformInitDxe.inf +INF MinPlatformPkg/PlatformInit/PlatformInitSmm/PlatformInitSmm.inf +INF $(BOARD_PKG)/SimicsDxe/SimicsDxe.inf + +FILE FREEFORM =3D 7BB28B99-61BB-11D5-9A5D-0090273FC14D { + SECTION RAW =3D $(BOARD_PKG)/Logo/Logo.bmp +} + +INF ShellPkg/Application/Shell/Shell.inf + +# +# Network modules +# +INF SimicsIch10BinPkg/UndiBinary/UndiDxe.inf + +!include AdvancedFeaturePkg/Include/Fdf/CoreAdvancedLateInclude.fdf + +!if gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosEnable =3D=3D TRUE + INF AdvancedFeaturePkg/Smbios/SmbiosBasicDxe/SmbiosBasicDxe.inf +!endif + +!include MinPlatformPkg/Include/Fdf/CoreSecurityLateInclude.fdf + +[FV.FVMAIN_COMPACT] +FvNameGuid =3D 6189987A-DDA6-4060-B313-49168DA9BD46 +FvAlignment =3D 16 +ERASE_POLARITY =3D 1 +MEMORY_MAPPED =3D TRUE +STICKY_WRITE =3D TRUE +LOCK_CAP =3D TRUE +LOCK_STATUS =3D TRUE +WRITE_DISABLED_CAP =3D TRUE +WRITE_ENABLED_CAP =3D TRUE +WRITE_STATUS =3D TRUE +WRITE_LOCK_CAP =3D TRUE +WRITE_LOCK_STATUS =3D TRUE +READ_DISABLED_CAP =3D TRUE +READ_ENABLED_CAP =3D TRUE +READ_STATUS =3D TRUE +READ_LOCK_CAP =3D TRUE +READ_LOCK_STATUS =3D TRUE + +FILE FV_IMAGE =3D 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 { + SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = =3D TRUE { + # + # These firmware volumes will have files placed in them uncompressed, + # and then both firmware volumes will be compressed in a single + # compression operation in order to achieve better overall compression. + # + SECTION FV_IMAGE =3D FvPreMemory + SECTION FV_IMAGE =3D DXEFV + } +} + +!include DecomprScratchEnd.fdf.inc + + +##########################################################################= ###### +# +# Rules are use with the [FV] section's module INF type to define +# how an FFS file is created for a given INF file. The following Rule are = the default +# rules for the different module type. User can add the customized rules t= o define the +# content of the FFS file. +# +##########################################################################= ###### + +!include MinPlatformPkg/Include/Fdf/RuleInclude.fdf + +[Rule.Common.SEC.RESET_VECTOR] + FILE RAW =3D $(NAMED_GUID) { + RAW RAW |.raw + } + +[Rule.Common.SEC.RESET_SECMAIN] + FILE SEC =3D $(NAMED_GUID) RELOCS_STRIPPED { + UI STRING=3D"$(MODULE_NAME)" Optional + VERSION STRING=3D"$(INF_VERSION)" Optional BUILD_NUM=3D$(BUILD_NUMBER) + PE32 PE32 Align =3D 16 $(INF_OUTPUT)/$(MODULE_NAME).efi + } diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.f= df.inc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.fdf.i= nc new file mode 100644 index 0000000000..044129c941 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.fdf.inc @@ -0,0 +1,54 @@ +## @file +# FDF include file that defines the main macros and sets the dependent PC= Ds. +# +# Copyright (C) 2014, Red Hat, Inc. +# Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +# +# Default flash size is 2MB. +# +# Defining FD_SIZE_2MB on the build command line can override this. +# + +DEFINE BLOCK_SIZE =3D 0x1000 +DEFINE VARS_SIZE =3D 0x3e000 +DEFINE VARS_BLOCKS =3D 0x3e + +DEFINE FW_BASE_ADDRESS =3D 0xFFE00000 +DEFINE FW_SIZE =3D 0x00200000 +DEFINE FW_BLOCKS =3D 0x200 +DEFINE CODE_BASE_ADDRESS =3D 0xFFE80000 +DEFINE CODE_SIZE =3D 0x00180000 +DEFINE CODE_BLOCKS =3D 0x180 +DEFINE FVMAIN_SIZE =3D 0x0016C000 +DEFINE SECFV_OFFSET =3D 0x001EC000 +DEFINE SECFV_SIZE =3D 0x14000 + + +SET gBoardModuleTokenSpaceGuid.PcdSimicsFdBaseAddress =3D $(FW_BASE_AD= DRESS) +SET gBoardModuleTokenSpaceGuid.PcdSimicsFirmwareFdSize =3D $(FW_SIZE) +SET gBoardModuleTokenSpaceGuid.PcdSimicsFirmwareBlockSize =3D $(BLOCK_SIZE) + +SET gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase =3D $(F= W_BASE_ADDRESS) +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize =3D 0xE000 + +SET gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase =3D gBo= ardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase + gEfiMdeModule= PkgTokenSpaceGuid.PcdFlashNvStorageVariableSize +SET gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize =3D $(B= LOCK_SIZE) + +SET gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase =3D g= BoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase + gBoardModul= eTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize =3D $(B= LOCK_SIZE) + +SET gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageFtwSpareBase =3D gBo= ardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase + gEfiMdeModu= lePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize =3D 0x100= 00 + +SET gEfiPchTokenSpaceGuid.PcdFlashAreaBaseAddress =3D 0xFFE00000 +SET gEfiPchTokenSpaceGuid.PcdFlashAreaSize =3D 0x00200000 + +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress =3D gEfiPchToken= SpaceGuid.PcdFlashAreaBaseAddress +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize =3D gEfiPchTokenSpaceGu= id.PcdFlashAreaSize + +DEFINE MEMFD_BASE_ADDRESS =3D 0x800000 diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgBu= ildOption.dsc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPk= gBuildOption.dsc new file mode 100644 index 0000000000..25998b83e7 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgBuildOpti= on.dsc @@ -0,0 +1,78 @@ +## @file +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[BuildOptions.Common.EDKII] +# Append build options for EDK and EDKII drivers (=3D is Append, =3D=3D is= Replace) + + DEFINE EDKII_DSC_FEATURE_BUILD_OPTIONS =3D + +!if $(TARGET) =3D=3D "DEBUG" + DEFINE DEBUG_BUILD_FLAG =3D -D SERIAL_DBG_MSG=3D1 +!else + DEFINE DEBUG_BUILD_FLAG =3D -D MDEPKG_NDEBUG -D SILENT_MODE +!endif + + DEFINE EDKII_DSC_FEATURE_BUILD_OPTIONS =3D $(EDKII_DSC_FEATURE_BUILD= _OPTIONS) $(DEBUG_BUILD_FLAG) +# +# PC_BUILD_END +# + + + DEFINE EDKII_DSC_FEATURE_BUILD_OPTIONS =3D $(EDKII_DSC_FEATURE_BUILD= _OPTIONS) + + + *_*_IA32_CC_FLAGS =3D $(EDKII_DSC_FEATURE_BUILD_OPTIONS) + *_*_IA32_VFRPP_FLAGS =3D $(EDKII_DSC_FEATURE_BUILD_OPTIONS) + *_*_IA32_APP_FLAGS =3D $(EDKII_DSC_FEATURE_BUILD_OPTIONS) + *_*_IA32_PP_FLAGS =3D $(EDKII_DSC_FEATURE_BUILD_OPTIONS) + *_*_IA32_ASLPP_FLAGS =3D $(EDKII_DSC_FEATURE_BUILD_OPTIONS) + *_*_IA32_ASLCC_FLAGS =3D $(EDKII_DSC_FEATURE_BUILD_OPTIONS) + + *_*_X64_CC_FLAGS =3D $(EDKII_DSC_FEATURE_BUILD_OPTIONS) + *_*_X64_VFRPP_FLAGS =3D $(EDKII_DSC_FEATURE_BUILD_OPTIONS) + *_*_X64_APP_FLAGS =3D $(EDKII_DSC_FEATURE_BUILD_OPTIONS) + *_*_X64_PP_FLAGS =3D $(EDKII_DSC_FEATURE_BUILD_OPTIONS) + *_*_X64_ASLPP_FLAGS =3D $(EDKII_DSC_FEATURE_BUILD_OPTIONS) + *_*_X64_ASLCC_FLAGS =3D $(EDKII_DSC_FEATURE_BUILD_OPTIONS) + + + +# +# Enable source level debugging for RELEASE build +# +!if $(TARGET) =3D=3D "RELEASE" + DEFINE EDKII_RELEASE_SRCDBG_ASM_BUILD_OPTIONS =3D /Zi + DEFINE EDKII_RELEASE_SRCDBG_CC_BUILD_OPTIONS =3D /Zi /Gm + DEFINE EDKII_RELEASE_SRCDBG_DLINK_BUILD_OPTIONS =3D /DEBUG + + MSFT:*_*_*_ASM_FLAGS =3D $(EDKII_RELEASE_SRCDBG_ASM_BUILD_OPTIONS) + MSFT:*_*_*_CC_FLAGS =3D $(EDKII_RELEASE_SRCDBG_CC_BUILD_OPTIONS) + MSFT:*_*_*_DLINK_FLAGS =3D $(EDKII_RELEASE_SRCDBG_DLINK_BUILD_OPTIONS) +!endif + + +# +# Override the existing iasl path in tools_def.template +# +# MSFT:*_*_*_ASL_PATH =3D=3D c:/Iasl/iasl.exe + +# +# Override the VFR compile flags to speed the build time +# + +*_*_*_VFR_FLAGS =3D=3D -n + +# Force PE/COFF sections to be aligned at 4KB boundaries to support page l= evel protection +#[BuildOptions.common.EDKII.DXE_SMM_DRIVER, BuildOptions.common.EDKII.SMM_= CORE] +# MSFT:*_*_*_DLINK_FLAGS =3D /ALIGN:4096 +# GCC:*_*_*_DLINK_FLAGS =3D -z common-page-size=3D0x1000 + +# Force PE/COFF sections to be aligned at 4KB boundaries to support Memory= Attribute table +#[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER] +# MSFT:*_*_*_DLINK_FLAGS =3D /ALIGN:4096 +# GCC:*_*_*_DLINK_FLAGS =3D -z common-page-size=3D0x1000 diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgCo= nfig.dsc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgConf= ig.dsc new file mode 100644 index 0000000000..75de60e5bc --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgConfig.dsc @@ -0,0 +1,56 @@ +## @file +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +# +# TRUE is ENABLE. FALSE is DISABLE. +# + +[PcdsFixedAtBuild] + gMinPlatformPkgTokenSpaceGuid.PcdBootStage|4 + +[PcdsFeatureFlag] + gMinPlatformPkgTokenSpaceGuid.PcdStopAfterDebugInit|FALSE + gMinPlatformPkgTokenSpaceGuid.PcdStopAfterMemInit|FALSE + gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly|FALSE + gMinPlatformPkgTokenSpaceGuid.PcdUefiSecureBootEnable|FALSE + gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable|FALSE + +!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >=3D 1 + gMinPlatformPkgTokenSpaceGuid.PcdStopAfterDebugInit|TRUE +!endif + +!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >=3D 2 + gMinPlatformPkgTokenSpaceGuid.PcdStopAfterDebugInit|FALSE + gMinPlatformPkgTokenSpaceGuid.PcdStopAfterMemInit|TRUE +!endif + +!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >=3D 3 + gMinPlatformPkgTokenSpaceGuid.PcdStopAfterMemInit|FALSE + gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly|TRUE +!endif + +!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >=3D 4 + gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly|FALSE +!endif + +!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >=3D 5 + gMinPlatformPkgTokenSpaceGuid.PcdUefiSecureBootEnable|TRUE + gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable|TRUE +!endif + + !if $(TARGET) =3D=3D DEBUG + gMinPlatformPkgTokenSpaceGuid.PcdSmiHandlerProfileEnable|TRUE + !else + gMinPlatformPkgTokenSpaceGuid.PcdSmiHandlerProfileEnable|FALSE + !endif + + gMinPlatformPkgTokenSpaceGuid.PcdPerformanceEnable|FALSE + + gAdvancedFeaturePkgTokenSpaceGuid.PcdNetworkEnable|TRUE + gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosEnable|TRUE + diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgPc= d.dsc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgPcd.dsc new file mode 100644 index 0000000000..3bf10ee524 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgPcd.dsc @@ -0,0 +1,281 @@ +## @file +# +# Copyright (c) 2019 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +##########################################################################= ###### +# +# Pcd Section - list of all EDK II PCD Entries defined by this Platform +# +##########################################################################= ###### +[PcdsFeatureFlag.common] +!if $(TARGET) =3D=3D RELEASE + gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE +!else + gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|TRUE +!endif + # Server doesn't support capsle update on Reset. + gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|FALSE + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmEnableBspElection|FALSE + gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugSupport|FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport|FALSE + + +#S3 add + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|TRUE +#S3 add + + ## This PCD specified whether ACPI SDT protocol is installed. + gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE + +[PcdsFeatureFlag.X64] + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard|FALSE + +[PcdsFeatureFlag] + gEfiMdeModulePkgTokenSpaceGuid.PcdBrowerGrayOutReadOnlyMenu|TRUE + +[PcdsDynamicExDefault] + +[PcdsFixedAtBuild.common] + gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|TRUE +!if $(TARGET) =3D=3D "RELEASE" + gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x03 +!else + gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07 +!endif + gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07 + gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize|0x0 +#S3 modified + gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnS3Boot|TRUE +#S3 modified + + gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize|0x0 + gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0x0 + gEfiMdePkgTokenSpaceGuid.PcdFSBClock|133333333 + gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeiStackSize|0x100000 + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxSizeNonPopulateCapsule|0x1700000 + + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|10000 + gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|512 + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize|0x4000 + + ## Specifies delay value in microseconds after sending out an INIT IPI. + # @Prompt Configure delay value after send an INIT IPI + gUefiCpuPkgTokenSpaceGuid.PcdCpuInitIpiDelayInMicroSeconds|10 + + ## Specifies max supported number of Logical Processors. + # @Prompt Configure max supported number of Logical Processorss + gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|512 + gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize|0x1000 +!if gMinPlatformPkgTokenSpaceGuid.PcdPerformanceEnable =3D=3D TRUE + gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0x1 +!endif + + ## Defines the ACPI register set base address. + # The invalid 0xFFFF is as its default value. It must be configured to = the real value. + # @Prompt ACPI Timer IO Port Address + gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddress | 0x0400 + + ## Defines the PCI Bus Number of the PCI device that contains the BAR an= d Enable for ACPI hardware registers. + # @Prompt ACPI Hardware PCI Bus Number + gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBusNumber | 0x00 + + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision|0x00000002 + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId|0x4C544E49 + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision|0x20091013 + + ## Defines the PCI Device Number of the PCI device that contains the BAR= and Enable for ACPI hardware registers. + # The invalid 0xFF is as its default value. It must be configured to th= e real value. + # @Prompt ACPI Hardware PCI Device Number + gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciDeviceNumber | 0x1F + + ## Defines the PCI Function Number of the PCI device that contains the B= AR and Enable for ACPI hardware registers. + # The invalid 0xFF is as its default value. It must be configured to th= e real value. + # @Prompt ACPI Hardware PCI Function Number + gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciFunctionNumber | 0x00 + + ## Defines the PCI Register Offset of the PCI device that contains the E= nable for ACPI hardware registers. + # The invalid 0xFFFF is as its default value. It must be configured to = the real value. + # @Prompt ACPI Hardware PCI Register Offset + gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciEnableRegisterOffset |0x0044 + + ## Defines the bit mask that must be set to enable the APIC hardware reg= ister BAR. + # @Prompt ACPI Hardware PCI Bar Enable BitMask + gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoBarEnableMask | 0x80 + + ## Defines the PCI Register Offset of the PCI device that contains the B= AR for ACPI hardware registers. + # The invalid 0xFFFF is as its default value. It must be configured to = the real value. + # @Prompt ACPI Hardware PCI Bar Register Offset + gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBarRegisterOffset |0x0040 + + ## Defines the offset to the 32-bit Timer Value register that resides wi= thin the ACPI BAR. + # @Prompt Offset to 32-bit Timer register in ACPI BAR + gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiPm1TmrOffset |0x0008 + + ## Defines the bit mask to retrieve ACPI IO Port Base Address + # @Prompt ACPI IO Port Base Address Mask + gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddressMask |0xFFFC + + gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FAL= SE + + gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuThreadCount|4 + gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuCoreCount|128 + gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuSocketCount|4 + gMinPlatformPkgTokenSpaceGuid.PcdLocalApicAddress|0xFEE00000 + gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicAddressBase|0xFEC01000 + gMinPlatformPkgTokenSpaceGuid.PcdFadtPreferredPmProfile|0x0 + gMinPlatformPkgTokenSpaceGuid.PcdFadtIaPcBootArch|0x0003 + gMinPlatformPkgTokenSpaceGuid.PcdFadtFlags|0x000004A5 + gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1AEventBlockAddress|0x400 + gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1BEventBlockAddress|0 + gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1AControlBlockAddress|0x404 + gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1BControlBlockAddress|0 + gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm2ControlBlockAddress|0x450 + gMinPlatformPkgTokenSpaceGuid.PcdAcpiPmTimerBlockAddress|0x408 + gMinPlatformPkgTokenSpaceGuid.PcdAcpiGpe0BlockAddress|0x420 + gMinPlatformPkgTokenSpaceGuid.PcdAcpiGpe1BlockAddress|0 + +[PcdsFixedAtBuild.X64] + gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeMask|0x0eB8 + gPcAtChipsetPkgTokenSpaceGuid.PcdMinimalValidYear|2015 + gPcAtChipsetPkgTokenSpaceGuid.PcdMaximalValidYear|2099 + # Change PcdBootManagerMenuFile to UiApp +## + + gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c= , 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0= x31 } + + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable |TRUE + + [PcdsPatchableInModule.common] + +!if gMinPlatformPkgTokenSpaceGuid.PcdSmiHandlerProfileEnable =3D=3D TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdSmiHandlerProfilePropertyMask|0x1 +!endif + + gPcAtChipsetPkgTokenSpaceGuid.PcdHpetBaseAddress|0xFED00000 + + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|1024 + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600 + + gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable|TRUE + + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvMicrocodeBase|0x0 + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvMicrocodeSize|0x0 + +[PcdsDynamicExDefault.common.DEFAULT] + gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|30000 + gUefiCpuPkgTokenSpaceGuid.PcdCpuS3DataAddress|0 + +[PcdsDynamicExHii.common.DEFAULT] + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVar= iableGuid|0x0|50 # Variable: L"Timeout" + gEfiMdePkgTokenSpaceGuid.PcdHardwareErrorRecordLevel|L"HwErrRecSupport"|= gEfiGlobalVariableGuid|0x0|1 # Variable: L"HwErrRecSupport" + + +[PcdsDynamicExDefault] + + gEfiMdeModulePkgTokenSpaceGuid.PcdMrIovSupport|FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSystemPageSize|0x1F + + gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L""|VOID*|36 + + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId|{0x49, 0x4E, 0x54, 0x= 45, 0x4C, 0x20} + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId|0x20465730303632= 53 + +[PcdsDynamicExDefault.X64] + + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200 + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits|8 + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|1 + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|1 + gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|0 + + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|31 + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|100 + + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|800 + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|600 + + gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugDataAddress|0 + +[PcdsFeatureFlag] + gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportUefiDecompress|FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE + #gOptionRomPkgTokenSpaceGuid.PcdSupportGop|TRUE + #gOptionRomPkgTokenSpaceGuid.PcdSupportUga|FALSE + +!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly =3D=3D FALSE + gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire|TRUE +!endif + +[PcdsFixedAtBuild] + gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1 + gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x10 + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x400 + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x8000 + gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xc000 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0xc000 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0x2000 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize|0x10000 + + gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0 + + # DEBUG_INIT 0x00000001 // Initialization + # DEBUG_WARN 0x00000002 // Warnings + # DEBUG_LOAD 0x00000004 // Load events + # DEBUG_FS 0x00000008 // EFI File system + # DEBUG_POOL 0x00000010 // Alloc & Free (pool) + # DEBUG_PAGE 0x00000020 // Alloc & Free (page) + # DEBUG_INFO 0x00000040 // Informational debug messages + # DEBUG_DISPATCH 0x00000080 // PEI/DXE/SMM Dispatchers + # DEBUG_VARIABLE 0x00000100 // Variable + # DEBUG_BM 0x00000400 // Boot Manager + # DEBUG_BLKIO 0x00001000 // BlkIo Driver + # DEBUG_NET 0x00004000 // SNP Driver + # DEBUG_UNDI 0x00010000 // UNDI Driver + # DEBUG_LOADFILE 0x00020000 // LoadFile + # DEBUG_EVENT 0x00080000 // Event messages + # DEBUG_GCD 0x00100000 // Global Coherency Database changes + # DEBUG_CACHE 0x00200000 // Memory range cachability changes + # DEBUG_VERBOSE 0x00400000 // Detailed debug messages that may + # // significantly impact boot performance + # DEBUG_ERROR 0x80000000 // Error + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F + + # + # PCI feature overrides. + # + gEfiMdeModulePkgTokenSpaceGuid.PcdAriSupport|FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|FALSE + +##########################################################################= ###### +# +# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Pla= tform +# +##########################################################################= ###### + +[PcdsDynamicDefault] + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0 + + gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId|0 + gBoardModuleTokenSpaceGuid.PcdPciIoBase|0x0 + gBoardModuleTokenSpaceGuid.PcdPciIoSize|0x0 + gBoardModuleTokenSpaceGuid.PcdPciMmio32Base|0x0 + gBoardModuleTokenSpaceGuid.PcdPciMmio32Size|0x0 + gBoardModuleTokenSpaceGuid.PcdPciMmio64Base|0x0 + gBoardModuleTokenSpaceGuid.PcdPciMmio64Size|0x800000000 + + gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType0StringBiosVersion|"Ver.1= .0.0" + gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType1StringProductName|"QSP U= EFI BIOS" + gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType2StringProductName|"QSP U= EFI BIOS" + gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType0StringBiosReleaseDate|"2= 019-08-09" + + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable|FALSE diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/VarStore.fdf.i= nc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/VarStore.fdf.inc new file mode 100644 index 0000000000..ea5b86228f --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/VarStore.fdf.inc @@ -0,0 +1,53 @@ +## @file +# FDF include file with Layout Regions that define an empty variable stor= e. +# +# Copyright (C) 2014, Red Hat, Inc. +# Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +0x00000000|0x0003e000 +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gEfiMdeModule= PkgTokenSpaceGuid.PcdFlashNvStorageVariableSize +#NV_VARIABLE_STORE +DATA =3D { + ## This is the EFI_FIRMWARE_VOLUME_HEADER + # ZeroVector [] + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + # FileSystemGuid: gEfiSystemNvDataFvGuid =3D + # { 0xFFF12B8D, 0x7696, 0x4C8B, + # { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }} + 0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C, + 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50, + # FvLength: 0x80000 + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + #Signature "_FVH" #Attributes + 0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00, + #HeaderLength #CheckSum #ExtHeaderOffset #Reserved #Revision + 0x48, 0x00, 0x2A, 0x09, 0x00, 0x00, 0x00, 0x02, + #Blockmap[0]: 7 Blocks * 0x10000 Bytes / Block + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + #Blockmap[1]: End + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ## This is the VARIABLE_STORE_HEADER +!if $(SECURE_BOOT_ENABLE) =3D=3D TRUE + # Signature: gEfiAuthenticatedVariableGuid =3D + # { 0xaaf32c78, 0x947b, 0x439a, + # { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }} + 0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43, + 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92, +!else + #Signature: gEfiVariableGuid =3D + # { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0= xfe, 0x7d }} + 0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41, + 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d, +!endif + #Size: 0x3E000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariable= Size) - 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) =3D 0x03DFB8 + # This can speed up the Variable Dispatch a bit. + 0xB8, 0xDF, 0x03, 0x00, + # FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32 + 0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +} + diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/build_config.c= fg b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/build_config.cfg new file mode 100644 index 0000000000..72512837f5 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/build_config.cfg @@ -0,0 +1,31 @@ +# @ build_config.cfg +# This is the BoardX58Ich10 board specific build settings +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# + + +[CONFIG] +WORKSPACE_PLATFORM_BIN =3D edk2-non-osi/Platform/Intel +EDK_SETUP_OPTION =3D +openssl_path =3D +PLATFORM_BOARD_PACKAGE =3D SimicsOpenBoardPkg +PROJECT =3D SimicsOpenBoardPkg/BoardX58Ich10 +BOARD =3D BoardX58Ich10 +FLASH_MAP_FDF =3D SimicsOpenBoardPkg/BoardX58Ich10/Include/Fdf/FlashMapInc= lude.fdf +PROJECT_DSC =3D SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.dsc +BOARD_PKG_PCD_DSC =3D SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgPcd.dsc +PrepRELEASE =3D DEBUG +SILENT_MODE =3D FALSE +EXT_CONFIG_CLEAR =3D +CapsuleBuild =3D FALSE +EXT_BUILD_FLAGS =3D +CAPSULE_BUILD =3D 0 +TARGET =3D DEBUG +TARGET_SHORT =3D D +PERFORMANCE_BUILD =3D FALSE +FSP_WRAPPER_BUILD =3D FALSE +FSP_BINARY_BUILD =3D FALSE +FSP_TEST_RELEASE =3D FALSE +SECURE_BOOT_ENABLE =3D FALSE --=20 2.16.2.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 (#46948): https://edk2.groups.io/g/devel/message/46948 Mute This Topic: https://groups.io/mt/33159243/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Fri Apr 26 02:55:24 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+46947+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+46947+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1567719524; cv=none; d=zoho.com; s=zohoarc; b=INGPxkS2BUco88HqLXoQRCujLalsx075kPz5gJ/JqOv2D8o4W/tzlJEWAN8MAX3KiUdXYeA8rEzcDaRakfI1e2G1F5FddkUHmWNKJ39wcGwGxkvKklxTFs+KReGG0t22gYuf9i3rGYzkgDml1wHkaHOAtRCQqmBiIdkOEPcg/y8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1567719524; h=Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To:ARC-Authentication-Results; bh=ysfHXa6hNZZArfFlg+uZoMFEzjsNXw356QtmF0qIW70=; b=i/eiw5SefzJdE8fg3o2e92liyWOKhouNKfbuxt/ae0uxLXHe6A8JIQ/+lJylu4KpyZPdCZD5kOswIGkScvQs1KUUcJm27JiznAXEXqgZJlVCb5qnxjvlS2mwNQEXH3zr5fraRj5Pgat2I2DuHqEarA4gINKF2gIfNLZGYtq+XvY= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+46947+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 156771952497244.86166217528523; Thu, 5 Sep 2019 14:38:44 -0700 (PDT) Return-Path: X-Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by groups.io with SMTP; Thu, 05 Sep 2019 14:38:43 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Sep 2019 14:38:43 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,471,1559545200"; d="scan'208";a="267151631" X-Received: from ydwei-desk.amr.corp.intel.com ([10.24.15.168]) by orsmga001.jf.intel.com with ESMTP; 05 Sep 2019 14:38:42 -0700 From: "David Wei" To: devel@edk2.groups.io Cc: Hao Wu , Liming Gao , Ankit Sinha , Agyeman Prince , Kubacki Michael A , Nate DeSimone , Michael D Kinney Subject: [edk2-devel] [edk2-platforms PATCH v5 7/7] Platform/Intel: Add build option for SIMICS QSP Platform Date: Thu, 5 Sep 2019 14:38:40 -0700 Message-Id: <2f93c64132242310122676002585584b1107d208.1567718650.git.david.y.wei@intel.com> In-Reply-To: References: In-Reply-To: References: Precedence: Bulk List-Unsubscribe: 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,david.y.wei@intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1567719524; bh=a/cxRXkMZGPwHFGUjFk7deSqJc9/ZuvneVoEdbGxUb0=; h=Cc:Date:From:Reply-To:Subject:To; b=mfNft9sp9F0aRE67kmzE2VEjCBDwXJ6g/kFHZxE4NNZxJ2Sdj5Hcdbg4JpqiX5xR4uC VKQWvtfVNeZdA+PELLlxK5XYak0+biu7B9bDlgD24NO/857Ug74KrGQrlCehxhdTTw/H2 Jw95wK3XxgMaOMFsnftNyAhotFxMQiv/vVA= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add build option in build script for SIMICS QSP(Quick Start Platform) Platf= orm Add Maintainers of Simics QSP related packages Cc: Hao Wu Cc: Liming Gao Cc: Ankit Sinha Cc: Agyeman Prince Cc: Kubacki Michael A Cc: Nate DeSimone Cc: Michael D Kinney Signed-off-by: David Wei --- Maintainers.txt | 12 ++++++++++++ Platform/Intel/build.cfg | 2 ++ Platform/Intel/build_bios.py | 3 +++ 3 files changed, 17 insertions(+) diff --git a/Maintainers.txt b/Maintainers.txt index b16432bf87..90eb3c3dd0 100644 --- a/Maintainers.txt +++ b/Maintainers.txt @@ -103,6 +103,10 @@ M: Chasel Chiu M: Michael Kubacki M: Nate DeSimone =20 +Platform/Intel/SimicsOpenBoardPkg +M: Wei David Y +M: Agyeman Prince + Platform/Intel/Tools M: Bob Feng M: Liming Gao @@ -155,6 +159,14 @@ M: Gillispie, Thad M: Bu, Daocheng M: Oram, Isaac W =20 +Silicon/Intel/SimicsX58SktPkg +M: Wei David Y +M: Agyeman Prince + +Silicon/Intel/SimicsIch10Pkg +M: Wei David Y +M: Agyeman Prince + Silicon/Intel/Tools M: Bob Feng M: Liming Gao diff --git a/Platform/Intel/build.cfg b/Platform/Intel/build.cfg index b6d32ada49..75cb446aa5 100644 --- a/Platform/Intel/build.cfg +++ b/Platform/Intel/build.cfg @@ -11,6 +11,7 @@ WORKSPACE =3D WORKSPACE_FSP_BIN =3D FSP EDK_TOOLS_BIN =3D edk2-BaseTools-win32 EDK_BASETOOLS =3D BaseTools +WORKSPACE_DRIVERS =3D edk2-platforms/Drivers WORKSPACE_PLATFORM =3D edk2-platforms/Platform/Intel WORKSPACE_SILICON =3D edk2-platforms/Silicon/Intel WORKSPACE_PLATFORM_BIN =3D @@ -52,6 +53,7 @@ NUMBER_OF_PROCESSORS =3D 0 [PLATFORMS] # board_name =3D path_to_board_build_config.cfg BoardMtOlympus =3D PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg +BoardX58Ich10 =3D SimicsOpenBoardPkg/BoardX58Ich10/build_config.cfg KabylakeRvp3 =3D KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg N1xxWU =3D ClevoOpenBoardPkg/N1xxWU/build_config.cfg WhiskeylakeURvp =3D WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.c= fg diff --git a/Platform/Intel/build_bios.py b/Platform/Intel/build_bios.py index 9152670dcb..46285df19a 100644 --- a/Platform/Intel/build_bios.py +++ b/Platform/Intel/build_bios.py @@ -104,6 +104,8 @@ def pre_build(build_config, build_type=3D"DEBUG", silen= t=3DFalse, toolchain=3DNone): config["WORKSPACE_PLATFORM= "]) config["WORKSPACE_SILICON"] =3D os.path.join(config["WORKSPACE"], config["WORKSPACE_SILICON"]) + config["WORKSPACE_DRIVERS"] =3D os.path.join(config["WORKSPACE"], + config["WORKSPACE_DRIVERS"]) config["WORKSPACE_PLATFORM_BIN"] =3D \ os.path.join(config["WORKSPACE"], config["WORKSPACE_PLATFORM_BIN"]) config["WORKSPACE_SILICON_BIN"] =3D \ @@ -115,6 +117,7 @@ def pre_build(build_config, build_type=3D"DEBUG", silen= t=3DFalse, toolchain=3DNone): config["PACKAGES_PATH"] =3D config["WORKSPACE_PLATFORM"] config["PACKAGES_PATH"] +=3D os.pathsep + config["WORKSPACE_SILICON"] config["PACKAGES_PATH"] +=3D os.pathsep + config["WORKSPACE_SILICON_BI= N"] + config["PACKAGES_PATH"] +=3D os.pathsep + config["WORKSPACE_DRIVERS"] config["PACKAGES_PATH"] +=3D os.pathsep + \ os.path.join(config["WORKSPACE"], "FSP") config["PACKAGES_PATH"] +=3D os.pathsep + \ --=20 2.16.2.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 (#46947): https://edk2.groups.io/g/devel/message/46947 Mute This Topic: https://groups.io/mt/33159242/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-