From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.151, mailfrom: david.y.wei@intel.com) Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by groups.io with SMTP; Fri, 09 Aug 2019 15:46:59 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Aug 2019 15:46:58 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,367,1559545200"; d="scan'208";a="199536455" Received: from ydwei-desk.amr.corp.intel.com ([10.24.15.168]) by fmsmga004.fm.intel.com with ESMTP; 09 Aug 2019 15:46:57 -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-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform Date: Fri, 9 Aug 2019 15:46:51 -0700 Message-Id: X-Mailer: git-send-email 2.16.2.windows.1 In-Reply-To: References: In-Reply-To: References: Overrides/MdeModulePkg/Library/PciHostBridgeLib - it is platform related. should be Customized Overrides/MdeModulePkg/Logo - the Logo image is Customized Overrides/MdePkg/Library/BasePciLibCf8 - use the functions specific for SIMICS Cc: Hao Wu Cc: Liming Gao Cc: Ankit Sinha Cc: Agyeman Prince Cc: Kubacki Michael A Cc: Nate DeSimone Cc: Michael D Kinney Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: David Wei --- .../Library/PciHostBridgeLib/PciHostBridgeLib.c | 419 ++++++ .../Library/PlatformBootManagerLib/BdsPlatform.c | 1553 +++++++++++++++++++ .../Library/PlatformBootManagerLib/PlatformData.c | 35 + .../Overrides/MdeModulePkg/Logo/Logo.c | 154 ++ .../MdePkg/Library/BasePciLibCf8/PciLib.c | 1221 +++++++++++++++ .../MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c | 1579 ++++++++++++++++++++ .../MinPlatformPkg/Acpi/AcpiTables/Facs/Facs.c | 84 ++ .../MinPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.c | 359 +++++ .../MinPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.c | 78 + .../MinPlatformPkg/Acpi/AcpiTables/Wsmt/Wsmt.c | 46 + .../Overrides/OvmfPkg/QemuVideoDxe/ComponentName.c | 205 +++ .../Overrides/OvmfPkg/QemuVideoDxe/Driver.c | 1011 +++++++++++++ .../QemuVideoDxe/DriverSupportedEfiVersion.c | 15 + .../Overrides/OvmfPkg/QemuVideoDxe/Gop.c | 417 ++++++ .../Overrides/OvmfPkg/QemuVideoDxe/Initialize.c | 341 +++++ .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c | 302 ++++ .../8259InterruptControllerDxe/8259.c | 622 ++++++++ .../Library/PciHostBridgeLib/PciHostBridge.h | 68 + .../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 50 + .../Library/PlatformBootManagerLib/BdsPlatform.h | 156 ++ .../PlatformBootManagerLib.inf | 69 + .../Overrides/MdeModulePkg/Logo/Logo.bmp | Bin 0 -> 141078 bytes .../Overrides/MdeModulePkg/Logo/Logo.idf | 10 + .../Overrides/MdeModulePkg/Logo/Logo.inf | 28 + .../Overrides/MdeModulePkg/Logo/Logo.uni | 16 + .../Overrides/MdeModulePkg/Logo/LogoDxe.inf | 55 + .../Overrides/MdeModulePkg/Logo/LogoDxe.uni | 16 + .../Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni | 14 + .../Overrides/MdeModulePkg/Logo/LogoExtra.uni | 14 + .../Library/BasePciLibCf8/DxePciLibX58Ich10.inf | 40 + .../MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h | 45 + .../Acpi/AcpiTables/AcpiPlatform.inf | 105 ++ .../Overrides/OvmfPkg/QemuVideoDxe/Qemu.h | 507 +++++++ .../OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf | 73 + .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm | 281 ++++ .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h | 701 +++++++++ .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh | 79 + .../8259InterruptControllerDxe/8259.h | 218 +++ .../8259InterruptControllerDxe/8259.inf | 46 + .../8259InterruptControllerDxe/Legacy8259.uni | 16 + .../8259InterruptControllerDxe/Legacy8259Extra.uni | 14 + 41 files changed, 11062 insertions(+) create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformData.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/PciLib.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Facs/Facs.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Wsmt/Wsmt.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/ComponentName.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Driver.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/DriverSupportedEfiVersion.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Gop.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Initialize.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridge.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.bmp create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.uni create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.uni create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtra.uni create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qemu.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.c new file mode 100644 index 0000000000..2aaa4b3e90 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.c @@ -0,0 +1,419 @@ +/** @file + OVMF's instance of the PCI Host Bridge Library. + + Copyright (C) 2016, Red Hat, Inc. + Copyright (c) 2016, 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[] = { + L"Mem", L"I/O", L"Bus" +}; + + +STATIC +CONST +OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH mRootBridgeDevicePathTemplate = { + { + { + 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 = { 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 behind any + PCI bridge hanging off this root bus. + + The caller is repsonsible for ensuring that + RootBusNumber <= 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, with + UID = 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 = 0; + + RootBus->Supports = Supports; + RootBus->Attributes = Attributes; + + RootBus->DmaAbove4G = FALSE; + + RootBus->AllocationAttributes = AllocAttributes; + RootBus->Bus.Base = RootBusNumber; + RootBus->Bus.Limit = 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 = (PcdGet16 (PcdSimicsX58HostBridgePciDevId) != + INTEL_ICH10_DEVICE_ID); + + DevicePath = AllocateCopyPool (sizeof mRootBridgeDevicePathTemplate, + &mRootBridgeDevicePathTemplate); + if (DevicePath == NULL) { + DEBUG ((EFI_D_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES)); + return EFI_OUT_OF_RESOURCES; + } + DevicePath->AcpiDevicePath.UID = RootBusNumber; + RootBus->DevicePath = (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 caller 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 = 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 = EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM; + if (PcdGet64 (PcdPciMmio64Size) > 0) { + AllocationAttributes |= EFI_PCI_HOST_BRIDGE_MEM64_DECODE; + MemAbove4G.Base = PcdGet64 (PcdPciMmio64Base); + MemAbove4G.Limit = PcdGet64 (PcdPciMmio64Base) + + PcdGet64 (PcdPciMmio64Size) - 1; + } else { + CopyMem (&MemAbove4G, &mNonExistAperture, sizeof (mNonExistAperture)); + } + + Io.Base = PcdGet64 (PcdPciIoBase); + Io.Limit = PcdGet64 (PcdPciIoBase) + (PcdGet64 (PcdPciIoSize) - 1); + Mem.Base = PcdGet64 (PcdPciMmio32Base); + Mem.Limit = PcdGet64 (PcdPciMmio32Base) + (PcdGet64 (PcdPciMmio32Size) - 1); + + *Count = 0; + ExtraRootBridges = 0; + + // + // Allocate the "main" root bridge, and any extra root bridges. + // + Bridges = AllocatePool ((1 + (UINTN)ExtraRootBridges) * sizeof *Bridges); + if (Bridges == NULL) { + DEBUG ((EFI_D_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES)); + return NULL; + } + Initialized = 0; + + // + // The "main" root bus is always there. + // + LastRootBridgeNumber = 0; + + // + // Scan all other root buses. If function 0 of any device on a bus returns a + // VendorId register value different from all-bits-one, then that bus is + // alive. + // + for (RootBridgeNumber = 1; + RootBridgeNumber <= PCI_MAX_BUS && Initialized < ExtraRootBridges; + ++RootBridgeNumber) { + UINTN Device; + + for (Device = 0; Device <= PCI_MAX_DEVICE; ++Device) { + if (PciRead16 (PCI_LIB_ADDRESS (RootBridgeNumber, Device, 0, + PCI_VENDOR_ID_OFFSET)) != MAX_UINT16) { + break; + } + } + if (Device <= 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, for any + // subordinate buses that might exist behind PCI bridges hanging off it. + // + Status = InitRootBridge ( + Attributes, + Attributes, + AllocationAttributes, + (UINT8) LastRootBridgeNumber, + (UINT8) (RootBridgeNumber - 1), + &Io, + &Mem, + &MemAbove4G, + &mNonExistAperture, + &mNonExistAperture, + &Bridges[Initialized] + ); + if (EFI_ERROR (Status)) { + goto FreeBridges; + } + ++Initialized; + LastRootBridgeNumber = RootBridgeNumber; + } + } + + // + // Install the last root bus (which might be the only, ie. main, root bus, if + // we've found no extra root buses). + // + Status = InitRootBridge ( + Attributes, + Attributes, + AllocationAttributes, + (UINT8) LastRootBridgeNumber, + PCI_MAX_BUS, + &Io, + &Mem, + &MemAbove4G, + &mNonExistAperture, + &mNonExistAperture, + &Bridges[Initialized] + ); + if (EFI_ERROR (Status)) { + goto FreeBridges; + } + ++Initialized; + + *Count = 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 == NULL && Count == 0) { + return; + } + ASSERT (Bridges != 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 resources + 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 = 0; + Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration; + while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) { + DEBUG ((EFI_D_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++)); + for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) { + ASSERT (Descriptor->ResType < + (sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr) / + sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr[0]) + ) + ); + DEBUG ((EFI_D_ERROR, " %s: Length/Alignment = 0x%lx / 0x%lx\n", + mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType], + Descriptor->AddrLen, Descriptor->AddrRangeMax + )); + if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) { + DEBUG ((EFI_D_ERROR, " Granularity/SpecificFlag = %ld / %02x%s\n", + Descriptor->AddrSpaceGranularity, Descriptor->SpecificFlag, + ((Descriptor->SpecificFlag & + EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE + ) != 0) ? L" (Prefetchable)" : L"" + )); + } + } + // + // Skip the END descriptor for root bridge + // + ASSERT (Descriptor->Desc == ACPI_END_TAG_DESCRIPTOR); + Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)( + (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1 + ); + } +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.c new file mode 100644 index 0000000000..0b66862e46 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.c @@ -0,0 +1,1553 @@ +/** @file + Platform BDS customizations. + + Copyright (c) 2004 - 2018 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[] = { + 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 = gBS->HandleProtocol ( + gImageHandle, + &gEfiLoadedImageProtocolGuid, + (VOID **) &LoadedImage + ); + ASSERT_EFI_ERROR (Status); + + EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid); + DevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle); + ASSERT (DevicePath != NULL); + DevicePath = AppendDevicePathNode ( + DevicePath, + (EFI_DEVICE_PATH_PROTOCOL *) &FileNode + ); + ASSERT (DevicePath != NULL); + + Status = EfiBootManagerInitializeLoadOption ( + &NewOption, + LoadOptionNumberUnassigned, + LoadOptionTypeBoot, + Attributes, + Description, + DevicePath, + NULL, + 0 + ); + ASSERT_EFI_ERROR (Status); + FreePool (DevicePath); + + BootOptions = EfiBootManagerGetLoadOptions ( + &BootOptionCount, LoadOptionTypeBoot + ); + + OptionIndex = EfiBootManagerFindLoadOption ( + &NewOption, BootOptions, BootOptionCount + ); + + if (OptionIndex == -1) { + Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN); + ASSERT_EFI_ERROR (Status); + } + EfiBootManagerFreeLoadOption (&NewOption); + EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); +} + +/** + Remove all MemoryMapped(...)/FvFile(...) and Fv(...)/FvFile(...) boot options + 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 firmware + 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() only + avoids exact duplicates. +**/ +VOID +RemoveStaleFvFileOptions ( + VOID + ) +{ + EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; + UINTN BootOptionCount; + UINTN Index; + + BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, + LoadOptionTypeBoot); + + for (Index = 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 = BootOptions[Index].FilePath; + if (!(DevicePathType (Node1) == HARDWARE_DEVICE_PATH && + DevicePathSubType (Node1) == HW_MEMMAP_DP) && + !(DevicePathType (Node1) == MEDIA_DEVICE_PATH && + DevicePathSubType (Node1) == MEDIA_PIWG_FW_VOL_DP)) { + continue; + } + + // + // If the second device path node is not FvFile(...), then keep the boot + // option. + // + Node2 = NextDevicePathNode (Node1); + if (DevicePathType (Node2) != MEDIA_DEVICE_PATH || + DevicePathSubType (Node2) != 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 the + // boot option. + // + SearchNode = Node1; + Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, + &SearchNode, &FvHandle); + + if (!EFI_ERROR (Status)) { + // + // The firmware volume was found; now let's see if it contains the FvFile + // 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 = gBS->HandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid, + (VOID **)&FvProtocol); + ASSERT_EFI_ERROR (Status); + + FvFileNode = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)Node2; + // + // Buffer==NULL means we request metadata only: BufferSize, FoundType, + // FileAttributes. + // + Status = 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 = EfiBootManagerDeleteLoadOptionVariable ( + BootOptions[Index].OptionNumber, LoadOptionTypeBoot); + DEBUG_CODE ( + CHAR16 *DevicePathString; + + DevicePathString = ConvertDevicePathToText(BootOptions[Index].FilePath, + 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 == NULL ? L"" : DevicePathString, + Status + )); + if (DevicePathString != 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 = SCAN_NULL; + Enter.UnicodeChar = CHAR_CARRIAGE_RETURN; + Status = EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL); + ASSERT_EFI_ERROR (Status); + + // + // Map F2 to Boot Manager Menu + // + F2.ScanCode = SCAN_F2; + F2.UnicodeChar = CHAR_NULL; + Esc.ScanCode = SCAN_ESC; + Esc.UnicodeChar = CHAR_NULL; + Status = EfiBootManagerGetBootManagerMenu (&BootOption); + ASSERT_EFI_ERROR (Status); + Status = EfiBootManagerAddKeyOptionVariable ( + NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL + ); + ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED); + Status = EfiBootManagerAddKeyOptionVariable ( + NULL, (UINT16) BootOption.OptionNumber, 0, &Esc, NULL + ); + ASSERT (Status == EFI_SUCCESS || Status == 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 triggers + // the preparation of S3 system information. That logic has a hard dependency + // 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 = 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 = NULL; + Status = gBS->HandleProtocol ( + DeviceHandle, + &gEfiDevicePathProtocolGuid, + (VOID*)&DevicePath + ); + if (EFI_ERROR (Status)) { + return Status; + } + TempDevicePath = DevicePath; + + // + // Register Keyboard + // + DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode); + + EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL); + + // + // Register COM1 + // + DevicePath = TempDevicePath; + gPnp16550ComPortDeviceNode.UID = 0; + + DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode); + DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode); + DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode); + + // + // Print Device Path + // + DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE); + if (DevPathStr != 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 = TempDevicePath; + gPnp16550ComPortDeviceNode.UID = 1; + + DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode); + DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode); + DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode); + + // + // Print Device Path + // + DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE); + if (DevPathStr != 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 == NULL || GopDevicePath == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Initialize the GopDevicePath to be PciDevicePath + // + *GopDevicePath = PciDevicePath; + TempPciDevicePath = PciDevicePath; + + Status = 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 = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiGraphicsOutputProtocolGuid, + NULL, + &GopHandleCount, + &GopHandleBuffer + ); + if (!EFI_ERROR (Status)) { + // + // Add all the child handles as possible Console Device + // + for (Index = 0; Index < GopHandleCount; Index++) { + Status = gBS->HandleProtocol (GopHandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath); + if (EFI_ERROR (Status)) { + continue; + } + if (CompareMem ( + PciDevicePath, + TempDevicePath, + GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH + ) == 0) { + // + // In current implementation, we only enable one of the child handles + // 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 device + // + + *GopDevicePath = TempDevicePath; + + // + // Delete the PCI device's path that added by + // GetPlugInPciVgaDevicePath(). Add the integrity GOP device path. + // + EfiBootManagerUpdateConsoleVariable (ConOutDev, NULL, PciDevicePath); + EfiBootManagerUpdateConsoleVariable (ConOutDev, TempDevicePath, NULL); + } + } + 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 = NULL; + GopDevicePath = NULL; + Status = gBS->HandleProtocol ( + DeviceHandle, + &gEfiDevicePathProtocolGuid, + (VOID*)&DevicePath + ); + if (EFI_ERROR (Status)) { + return Status; + } + + GetGopDevicePath (DevicePath, &GopDevicePath); + DevicePath = 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, ConIn, + 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 = NULL; + Status = gBS->HandleProtocol ( + DeviceHandle, + &gEfiDevicePathProtocolGuid, + (VOID*)&DevicePath + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode); + DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&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 = 0; + HandleBuffer = NULL; + Status = gBS->LocateHandleBuffer ( + ByProtocol, + Id, + NULL, + &HandleCount, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + + for (Index = 0; Index < HandleCount; Index++) { + Status = gBS->HandleProtocol (HandleBuffer[Index], Id, &Instance); + if (EFI_ERROR (Status)) { + continue; + } + + Status = (*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 = (EFI_PCI_IO_PROTOCOL*) Instance; + + // + // Check for all PCI device + // + Status = 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 = 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 == 0x8086) && + (Pci->Hdr.DeviceId == 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, ErrOut + + @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE. + + @retval EFI_SUCCESS - PCI Device check and Console variable update successfully. + @retval EFI_STATUS - PCI Device check or Console variable update fail. + +**/ +EFI_STATUS +DetectAndPreparePlatformPciDevicePaths ( + BOOLEAN DetectVgaOnly + ) +{ + mDetectVgaOnly = 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 array. +**/ +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, NULL); + + if (VarConout == NULL || VarConin == 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 = 0; PlatformConsole[Index].DevicePath != NULL; ++Index) { + // + // Update the console variable with the connect type + // + if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) { + EfiBootManagerUpdateConsoleVariable (ConIn, PlatformConsole[Index].DevicePath, NULL); + } + if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) { + EfiBootManagerUpdateConsoleVariable (ConOut, PlatformConsole[Index].DevicePath, NULL); + } + if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) { + 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 successfully. + +**/ +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 = EFI_SUCCESS; + + if (PciHdr->Device.InterruptPin != 0) { + + DevPathNode = DevicePathFromHandle (Handle); + ASSERT (DevPathNode != NULL); + DevPath = DevPathNode; + + RootBusNumber = 0; + if (DevicePathType (DevPathNode) == ACPI_DEVICE_PATH && + DevicePathSubType (DevPathNode) == ACPI_DP && + ((ACPI_HID_DEVICE_PATH *)DevPathNode)->HID == EISA_PNP_ID(0x0A03)) { + RootBusNumber = ((ACPI_HID_DEVICE_PATH *)DevPathNode)->UID; + } + + // + // Compute index into PciHostIrqs[] table by walking + // the device path and adding up all device numbers + // + Status = EFI_NOT_FOUND; + RootSlot = 0; + Idx = PciHdr->Device.InterruptPin - 1; + while (!IsDevicePathEnd (DevPathNode)) { + if (DevicePathType (DevPathNode) == HARDWARE_DEVICE_PATH && + DevicePathSubType (DevPathNode) == HW_PCI_DP) { + + Idx += ((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 != EFI_SUCCESS) { + Status = EFI_SUCCESS; + RootSlot = ((PCI_DEVICE_PATH *)DevPathNode)->Device; + } + } + + DevPathNode = NextDevicePathNode (DevPathNode); + } + if (EFI_ERROR (Status)) { + return Status; + } + if (RootBusNumber == 0 && RootSlot == 0) { + return Status; //bugbug: workaround; need SIMICS change B0/D0/F0 PCI_IntPin reg(0x3D) = 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 -= 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 = 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 -= RootSlot; + } + break; + default: + ASSERT (FALSE); // should never get here + } + Idx %= ARRAY_SIZE (PciHostIrqs); + IrqLine = PciHostIrqs[Idx]; + + DEBUG_CODE_BEGIN (); + { + CHAR16 *DevPathString; + STATIC CHAR16 Fallback[] = L""; + UINTN Segment, Bus, Device, Function; + + DevPathString = ConvertDevicePathToText (DevPath, FALSE, FALSE); + if (DevPathString == NULL) { + DevPathString = Fallback; + } + Status = PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function); + ASSERT_EFI_ERROR (Status); + + DEBUG ((EFI_D_VERBOSE, "%a: [%02x:%02x.%x] %s -> 0x%02x\n", __FUNCTION__, + (UINT32)Bus, (UINT32)Device, (UINT32)Function, DevPathString, + IrqLine)); + + if (DevPathString != Fallback) { + FreePool (DevPathString); + } + } + DEBUG_CODE_END (); + + // + // Set PCI Interrupt Line register for this device to PciHostIrqs[Idx] + // + Status = 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 register, +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)EdgeLevel); + IoWrite8(LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE, (UINT8)(EdgeLevel >> 8)); +} + +VOID +PciAcpiInitialization ( + ) +{ + UINTN Pmba; + + // + // Query Host Bridge DID to determine platform type + // + mHostBridgeDevId = PcdGet16 (PcdSimicsX58HostBridgePciDevId); + switch (mHostBridgeDevId) { + case INTEL_82441_DEVICE_ID: + Pmba = 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 = 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 = NULL; + Status = gBS->HandleProtocol ( + Handle, + &gEfiDevicePathProtocolGuid, + (VOID*)&DevicePath + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Print Device Path + // + DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE); + if (DevPathStr != NULL) { + DEBUG(( + EFI_D_INFO, + "Found Mass Storage device: %s\n", + DevPathStr + )); + FreePool(DevPathStr); + } + + Status = 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 = FALSE; + + if (ConnectedToFileSystem) { + return EFI_ALREADY_STARTED; + } + + Status = ConnectNvVarsToFileSystem (Handle); + if (EFI_ERROR (Status)) { + return Status; + } + + ConnectedToFileSystem = TRUE; + mEmuVariableEvent = + 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 = 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] != 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[] = { 0xDE, 0xAD, 0xBE, 0xEF }; + + Status = 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, rather + // than storing just a pointer to runtime or NVS storage. + // + Status = BootScript->Write(BootScript, EFI_BOOT_SCRIPT_INFORMATION_OPCODE, + (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 senarino + > 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 = NULL; + Status = 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 = 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 == BOOT_WITH_FULL_CONFIGURATION); + + // Perform some platform specific connect sequence + // + PlatformBdsConnectSequence (); + // + // Logo show + // + BootLogoEnableLogo(); + + 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 = sizeof (Handle); + Status = gBS->LocateHandle ( + ByRegisterNotify, + NULL, + mEfiDevPathNotifyReg, + &BufferSize, + &Handle + ); + + // + // If not found, we're done + // + if (EFI_NOT_FOUND == Status) { + break; + } + + if (EFI_ERROR (Status)) { + continue; + } + + // + // Get the DevicePath protocol on that handle + // + Status = 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) == MESSAGING_DEVICE_PATH) && + (DevicePathSubType(DevPathNode) == MSG_ATAPI_DP) + ) { + Atapi = (ATAPI_DEVICE_PATH*) DevPathNode; + PciOr16 ( + PCI_LIB_ADDRESS ( + 0, + 1, + 1, + (Atapi->PrimarySecondary == 1) ? 0x42: 0x40 + ), + BIT15 + ); + } + + // + // Next device path node + // + DevPathNode = NextDevicePathNode (DevPathNode); + } + } + + return; +} + + +VOID +InstallDevicePathCallback ( + VOID + ) +{ + DEBUG ((EFI_D_INFO, "Registered NotifyDevPath Event\n")); + mEfiDevPathEvent = 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 = PcdGet16 (PcdPlatformBootTimeOut); + + Black.Raw = 0x00000000; + White.Raw = 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/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformData.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformData.c new file mode 100644 index 0000000000..5f1b16dd56 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformData.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 - 2017 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "BdsPlatform.h" + +ACPI_HID_DEVICE_PATH gPnpPs2KeyboardDeviceNode = gPnpPs2Keyboard; +ACPI_HID_DEVICE_PATH gPnp16550ComPortDeviceNode = gPnp16550ComPort; +UART_DEVICE_PATH gUartDeviceNode = gUart; +VENDOR_DEVICE_PATH gTerminalTypeDeviceNode = gPcAnsiTerminal; + +// +// Platform specific keyboard device path +// + +// +// Predefined platform default console device path +// +PLATFORM_CONSOLE_CONNECT_ENTRY gPlatformConsole[] = { + { + NULL, + 0 + } +}; + +// +// Predefined platform connect sequence +// +EFI_DEVICE_PATH_PROTOCOL *gPlatformConnectSequence[] = { NULL }; + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.c new file mode 100644 index 0000000000..d4a75ad140 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.c @@ -0,0 +1,154 @@ +/** @file + Logo DXE Driver, install Edkii Platform Logo protocol. + + Copyright (c) 2016 - 2017 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct { + EFI_IMAGE_ID ImageId; + EDKII_PLATFORM_LOGO_DISPLAY_ATTRIBUTE Attribute; + INTN OffsetX; + INTN OffsetY; +} LOGO_ENTRY; + +EFI_HII_IMAGE_EX_PROTOCOL *mHiiImageEx; +EFI_HII_HANDLE mHiiHandle; +LOGO_ENTRY mLogos[] = { + { + IMAGE_TOKEN (IMG_LOGO), + EdkiiPlatformLogoDisplayAttributeCenter, + 0, + 0 + } +}; + +/** + Load a platform logo image and return its data and attributes. + + @param This The pointer to this protocol instance. + @param Instance The visible image instance is found. + @param Image Points to the image. + @param Attribute The display attributes of the image returned. + @param OffsetX The X offset of the image regarding the Attribute. + @param OffsetY The Y offset of the image regarding the Attribute. + + @retval EFI_SUCCESS The image was fetched successfully. + @retval EFI_NOT_FOUND The specified image could not be found. +**/ +EFI_STATUS +EFIAPI +GetImage ( + IN EDKII_PLATFORM_LOGO_PROTOCOL *This, + IN OUT UINT32 *Instance, + OUT EFI_IMAGE_INPUT *Image, + OUT EDKII_PLATFORM_LOGO_DISPLAY_ATTRIBUTE *Attribute, + OUT INTN *OffsetX, + OUT INTN *OffsetY + ) +{ + UINT32 Current; + if (Instance == NULL || Image == NULL || + Attribute == NULL || OffsetX == NULL || OffsetY == NULL) { + return EFI_INVALID_PARAMETER; + } + + Current = *Instance; + if (Current >= ARRAY_SIZE (mLogos)) { + return EFI_NOT_FOUND; + } + + (*Instance)++; + *Attribute = mLogos[Current].Attribute; + *OffsetX = mLogos[Current].OffsetX; + *OffsetY = mLogos[Current].OffsetY; + return mHiiImageEx->GetImageEx (mHiiImageEx, mHiiHandle, mLogos[Current].ImageId, Image); +} + +EDKII_PLATFORM_LOGO_PROTOCOL mPlatformLogo = { + GetImage +}; + +/** + Entrypoint of this module. + + This function is the entrypoint of this module. It installs the Edkii + Platform Logo protocol. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + +**/ +EFI_STATUS +EFIAPI +InitializeLogo ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HII_PACKAGE_LIST_HEADER *PackageList; + EFI_HII_DATABASE_PROTOCOL *HiiDatabase; + EFI_HANDLE Handle; + + Status = gBS->LocateProtocol ( + &gEfiHiiDatabaseProtocolGuid, + NULL, + (VOID **) &HiiDatabase + ); + ASSERT_EFI_ERROR (Status); + + Status = gBS->LocateProtocol ( + &gEfiHiiImageExProtocolGuid, + NULL, + (VOID **) &mHiiImageEx + ); + ASSERT_EFI_ERROR (Status); + + // + // Retrieve HII package list from ImageHandle + // + Status = gBS->OpenProtocol ( + ImageHandle, + &gEfiHiiPackageListProtocolGuid, + (VOID **) &PackageList, + ImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "HII Image Package with logo not found in PE/COFF resource section\n")); + return Status; + } + + // + // Publish HII package list to HII Database. + // + Status = HiiDatabase->NewPackageList ( + HiiDatabase, + PackageList, + NULL, + &mHiiHandle + ); + if (!EFI_ERROR (Status)) { + Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEdkiiPlatformLogoProtocolGuid, &mPlatformLogo, + NULL + ); + } + return Status; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/PciLib.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/PciLib.c new file mode 100644 index 0000000000..7544117a03 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/PciLib.c @@ -0,0 +1,1221 @@ +/** @file + PCI Library functions that use + (a) I/O ports 0xCF8 and 0xCFC to perform PCI Configuration cycles, layering + on top of one PCI CF8 Library instance; or + (b) PCI Library functions that use the 256 MB PCI Express MMIO window to + perform PCI Configuration cycles, layering on PCI Express Library. + + The decision is made in the entry point function, based on the OVMF platform + type, and then adhered to during the lifetime of the client module. + + Copyright (C) 2016, Red Hat, Inc. + Copyright (c) 2006 - 2012 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include + +#include + +#include +#include +#include +#include + +STATIC BOOLEAN mRunningOnIch10; + +RETURN_STATUS +EFIAPI +InitializeConfigAccessMethod ( + VOID + ) +{ + mRunningOnIch10 = (PcdGet16 (PcdSimicsX58HostBridgePciDevId) == + INTEL_ICH10_DEVICE_ID); + return RETURN_SUCCESS; +} + +/** + Registers a PCI device so PCI configuration registers may be accessed after + SetVirtualAddressMap(). + + Registers the PCI device specified by Address so all the PCI configuration registers + associated with that PCI device may be accessed after SetVirtualAddressMap() is called. + + If Address > 0x0FFFFFFF, then ASSERT(). + + @param Address The address that encodes the PCI Bus, Device, Function and + Register. + + @retval RETURN_SUCCESS The PCI device was registered for runtime access. + @retval RETURN_UNSUPPORTED An attempt was made to call this function + after ExitBootServices(). + @retval RETURN_UNSUPPORTED The resources required to access the PCI device + at runtime could not be mapped. + @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to + complete the registration. + +**/ +RETURN_STATUS +EFIAPI +PciRegisterForRuntimeAccess ( + IN UINTN Address + ) +{ + return mRunningOnIch10 ? + PciExpressRegisterForRuntimeAccess (Address) : + PciCf8RegisterForRuntimeAccess (Address); +} + +/** + Reads an 8-bit PCI configuration register. + + Reads and returns the 8-bit PCI configuration register specified by Address. + This function must guarantee that all PCI read and write operations are + serialized. + + If Address > 0x0FFFFFFF, then ASSERT(). + + @param Address The address that encodes the PCI Bus, Device, Function and + Register. + + @return The read value from the PCI configuration register. + +**/ +UINT8 +EFIAPI +PciRead8 ( + IN UINTN Address + ) +{ + return mRunningOnIch10 ? + PciExpressRead8 (Address) : + PciCf8Read8 (Address); +} + +/** + Writes an 8-bit PCI configuration register. + + Writes the 8-bit PCI configuration register specified by Address with the + value specified by Value. Value is returned. This function must guarantee + that all PCI read and write operations are serialized. + + If Address > 0x0FFFFFFF, then ASSERT(). + + @param Address The address that encodes the PCI Bus, Device, Function and + Register. + @param Value The value to write. + + @return The value written to the PCI configuration register. + +**/ +UINT8 +EFIAPI +PciWrite8 ( + IN UINTN Address, + IN UINT8 Value + ) +{ + return mRunningOnIch10 ? + PciExpressWrite8 (Address, Value) : + PciCf8Write8 (Address, Value); +} + +/** + Performs a bitwise OR of an 8-bit PCI configuration register with + an 8-bit value. + + Reads the 8-bit PCI configuration register specified by Address, performs a + bitwise OR between the read result and the value specified by + OrData, and writes the result to the 8-bit PCI configuration register + specified by Address. The value written to the PCI configuration register is + returned. This function must guarantee that all PCI read and write operations + are serialized. + + If Address > 0x0FFFFFFF, then ASSERT(). + + @param Address The address that encodes the PCI Bus, Device, Function and + Register. + @param OrData The value to OR with the PCI configuration register. + + @return The value written back to the PCI configuration register. + +**/ +UINT8 +EFIAPI +PciOr8 ( + IN UINTN Address, + IN UINT8 OrData + ) +{ + return mRunningOnIch10 ? + PciExpressOr8 (Address, OrData) : + PciCf8Or8 (Address, OrData); +} + +/** + Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit + value. + + Reads the 8-bit PCI configuration register specified by Address, performs a + bitwise AND between the read result and the value specified by AndData, and + writes the result to the 8-bit PCI configuration register specified by + Address. The value written to the PCI configuration register is returned. + This function must guarantee that all PCI read and write operations are + serialized. + + If Address > 0x0FFFFFFF, then ASSERT(). + + @param Address The address that encodes the PCI Bus, Device, Function and + Register. + @param AndData The value to AND with the PCI configuration register. + + @return The value written back to the PCI configuration register. + +**/ +UINT8 +EFIAPI +PciAnd8 ( + IN UINTN Address, + IN UINT8 AndData + ) +{ + return mRunningOnIch10 ? + PciExpressAnd8 (Address, AndData) : + PciCf8And8 (Address, AndData); +} + +/** + Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit + value, followed a bitwise OR with another 8-bit value. + + Reads the 8-bit PCI configuration register specified by Address, performs a + bitwise AND between the read result and the value specified by AndData, + performs a bitwise OR between the result of the AND operation and + the value specified by OrData, and writes the result to the 8-bit PCI + configuration register specified by Address. The value written to the PCI + configuration register is returned. This function must guarantee that all PCI + read and write operations are serialized. + + If Address > 0x0FFFFFFF, then ASSERT(). + + @param Address The address that encodes the PCI Bus, Device, Function and + Register. + @param AndData The value to AND with the PCI configuration register. + @param OrData The value to OR with the result of the AND operation. + + @return The value written back to the PCI configuration register. + +**/ +UINT8 +EFIAPI +PciAndThenOr8 ( + IN UINTN Address, + IN UINT8 AndData, + IN UINT8 OrData + ) +{ + return mRunningOnIch10 ? + PciExpressAndThenOr8 (Address, AndData, OrData) : + PciCf8AndThenOr8 (Address, AndData, OrData); +} + +/** + Reads a bit field of a PCI configuration register. + + Reads the bit field in an 8-bit PCI configuration register. The bit field is + specified by the StartBit and the EndBit. The value of the bit field is + returned. + + If Address > 0x0FFFFFFF, then ASSERT(). + If StartBit is greater than 7, then ASSERT(). + If EndBit is greater than 7, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Address The PCI configuration register to read. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..7. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..7. + + @return The value of the bit field read from the PCI configuration register. + +**/ +UINT8 +EFIAPI +PciBitFieldRead8 ( + IN UINTN Address, + IN UINTN StartBit, + IN UINTN EndBit + ) +{ + return mRunningOnIch10 ? + PciExpressBitFieldRead8 (Address, StartBit, EndBit) : + PciCf8BitFieldRead8 (Address, StartBit, EndBit); +} + +/** + Writes a bit field to a PCI configuration register. + + Writes Value to the bit field of the PCI configuration register. The bit + field is specified by the StartBit and the EndBit. All other bits in the + destination PCI configuration register are preserved. The new value of the + 8-bit register is returned. + + If Address > 0x0FFFFFFF, then ASSERT(). + If StartBit is greater than 7, then ASSERT(). + If EndBit is greater than 7, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). + + @param Address The PCI configuration register to write. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..7. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..7. + @param Value The new value of the bit field. + + @return The value written back to the PCI configuration register. + +**/ +UINT8 +EFIAPI +PciBitFieldWrite8 ( + IN UINTN Address, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT8 Value + ) +{ + return mRunningOnIch10 ? + PciExpressBitFieldWrite8 (Address, StartBit, EndBit, Value) : + PciCf8BitFieldWrite8 (Address, StartBit, EndBit, Value); +} + +/** + Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and + writes the result back to the bit field in the 8-bit port. + + Reads the 8-bit PCI configuration register specified by Address, performs a + bitwise OR between the read result and the value specified by + OrData, and writes the result to the 8-bit PCI configuration register + specified by Address. The value written to the PCI configuration register is + returned. This function must guarantee that all PCI read and write operations + are serialized. Extra left bits in OrData are stripped. + + If Address > 0x0FFFFFFF, then ASSERT(). + If StartBit is greater than 7, then ASSERT(). + If EndBit is greater than 7, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). + + @param Address The PCI configuration register to write. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..7. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..7. + @param OrData The value to OR with the PCI configuration register. + + @return The value written back to the PCI configuration register. + +**/ +UINT8 +EFIAPI +PciBitFieldOr8 ( + IN UINTN Address, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT8 OrData + ) +{ + return mRunningOnIch10 ? + PciExpressBitFieldOr8 (Address, StartBit, EndBit, OrData) : + PciCf8BitFieldOr8 (Address, StartBit, EndBit, OrData); +} + +/** + Reads a bit field in an 8-bit PCI configuration register, performs a bitwise + AND, and writes the result back to the bit field in the 8-bit register. + + Reads the 8-bit PCI configuration register specified by Address, performs a + bitwise AND between the read result and the value specified by AndData, and + writes the result to the 8-bit PCI configuration register specified by + Address. The value written to the PCI configuration register is returned. + This function must guarantee that all PCI read and write operations are + serialized. Extra left bits in AndData are stripped. + + If Address > 0x0FFFFFFF, then ASSERT(). + If StartBit is greater than 7, then ASSERT(). + If EndBit is greater than 7, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). + + @param Address The PCI configuration register to write. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..7. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..7. + @param AndData The value to AND with the PCI configuration register. + + @return The value written back to the PCI configuration register. + +**/ +UINT8 +EFIAPI +PciBitFieldAnd8 ( + IN UINTN Address, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT8 AndData + ) +{ + return mRunningOnIch10 ? + PciExpressBitFieldAnd8 (Address, StartBit, EndBit, AndData) : + PciCf8BitFieldAnd8 (Address, StartBit, EndBit, AndData); +} + +/** + Reads a bit field in an 8-bit port, performs a bitwise AND followed by a + bitwise OR, and writes the result back to the bit field in the + 8-bit port. + + Reads the 8-bit PCI configuration register specified by Address, performs a + bitwise AND followed by a bitwise OR between the read result and + the value specified by AndData, and writes the result to the 8-bit PCI + configuration register specified by Address. The value written to the PCI + configuration register is returned. This function must guarantee that all PCI + read and write operations are serialized. Extra left bits in both AndData and + OrData are stripped. + + If Address > 0x0FFFFFFF, then ASSERT(). + If StartBit is greater than 7, then ASSERT(). + If EndBit is greater than 7, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). + If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). + + @param Address The PCI configuration register to write. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..7. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..7. + @param AndData The value to AND with the PCI configuration register. + @param OrData The value to OR with the result of the AND operation. + + @return The value written back to the PCI configuration register. + +**/ +UINT8 +EFIAPI +PciBitFieldAndThenOr8 ( + IN UINTN Address, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT8 AndData, + IN UINT8 OrData + ) +{ + return mRunningOnIch10 ? + PciExpressBitFieldAndThenOr8 (Address, StartBit, EndBit, AndData, OrData) : + PciCf8BitFieldAndThenOr8 (Address, StartBit, EndBit, AndData, OrData); +} + +/** + Reads a 16-bit PCI configuration register. + + Reads and returns the 16-bit PCI configuration register specified by Address. + This function must guarantee that all PCI read and write operations are + serialized. + + If Address > 0x0FFFFFFF, then ASSERT(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + + @param Address The address that encodes the PCI Bus, Device, Function and + Register. + + @return The read value from the PCI configuration register. + +**/ +UINT16 +EFIAPI +PciRead16 ( + IN UINTN Address + ) +{ + return mRunningOnIch10 ? + PciExpressRead16 (Address) : + PciCf8Read16 (Address); +} + +/** + Writes a 16-bit PCI configuration register. + + Writes the 16-bit PCI configuration register specified by Address with the + value specified by Value. Value is returned. This function must guarantee + that all PCI read and write operations are serialized. + + If Address > 0x0FFFFFFF, then ASSERT(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + + @param Address The address that encodes the PCI Bus, Device, Function and + Register. + @param Value The value to write. + + @return The value written to the PCI configuration register. + +**/ +UINT16 +EFIAPI +PciWrite16 ( + IN UINTN Address, + IN UINT16 Value + ) +{ + return mRunningOnIch10 ? + PciExpressWrite16 (Address, Value) : + PciCf8Write16 (Address, Value); +} + +/** + Performs a bitwise OR of a 16-bit PCI configuration register with + a 16-bit value. + + Reads the 16-bit PCI configuration register specified by Address, performs a + bitwise OR between the read result and the value specified by + OrData, and writes the result to the 16-bit PCI configuration register + specified by Address. The value written to the PCI configuration register is + returned. This function must guarantee that all PCI read and write operations + are serialized. + + If Address > 0x0FFFFFFF, then ASSERT(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + + @param Address The address that encodes the PCI Bus, Device, Function and + Register. + @param OrData The value to OR with the PCI configuration register. + + @return The value written back to the PCI configuration register. + +**/ +UINT16 +EFIAPI +PciOr16 ( + IN UINTN Address, + IN UINT16 OrData + ) +{ + return mRunningOnIch10 ? + PciExpressOr16 (Address, OrData) : + PciCf8Or16 (Address, OrData); +} + +/** + Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit + value. + + Reads the 16-bit PCI configuration register specified by Address, performs a + bitwise AND between the read result and the value specified by AndData, and + writes the result to the 16-bit PCI configuration register specified by + Address. The value written to the PCI configuration register is returned. + This function must guarantee that all PCI read and write operations are + serialized. + + If Address > 0x0FFFFFFF, then ASSERT(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + + @param Address The address that encodes the PCI Bus, Device, Function and + Register. + @param AndData The value to AND with the PCI configuration register. + + @return The value written back to the PCI configuration register. + +**/ +UINT16 +EFIAPI +PciAnd16 ( + IN UINTN Address, + IN UINT16 AndData + ) +{ + return mRunningOnIch10 ? + PciExpressAnd16 (Address, AndData) : + PciCf8And16 (Address, AndData); +} + +/** + Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit + value, followed a bitwise OR with another 16-bit value. + + Reads the 16-bit PCI configuration register specified by Address, performs a + bitwise AND between the read result and the value specified by AndData, + performs a bitwise OR between the result of the AND operation and + the value specified by OrData, and writes the result to the 16-bit PCI + configuration register specified by Address. The value written to the PCI + configuration register is returned. This function must guarantee that all PCI + read and write operations are serialized. + + If Address > 0x0FFFFFFF, then ASSERT(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + + @param Address The address that encodes the PCI Bus, Device, Function and + Register. + @param AndData The value to AND with the PCI configuration register. + @param OrData The value to OR with the result of the AND operation. + + @return The value written back to the PCI configuration register. + +**/ +UINT16 +EFIAPI +PciAndThenOr16 ( + IN UINTN Address, + IN UINT16 AndData, + IN UINT16 OrData + ) +{ + return mRunningOnIch10 ? + PciExpressAndThenOr16 (Address, AndData, OrData) : + PciCf8AndThenOr16 (Address, AndData, OrData); +} + +/** + Reads a bit field of a PCI configuration register. + + Reads the bit field in a 16-bit PCI configuration register. The bit field is + specified by the StartBit and the EndBit. The value of the bit field is + returned. + + If Address > 0x0FFFFFFF, then ASSERT(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + If StartBit is greater than 15, then ASSERT(). + If EndBit is greater than 15, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Address The PCI configuration register to read. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..15. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..15. + + @return The value of the bit field read from the PCI configuration register. + +**/ +UINT16 +EFIAPI +PciBitFieldRead16 ( + IN UINTN Address, + IN UINTN StartBit, + IN UINTN EndBit + ) +{ + return mRunningOnIch10 ? + PciExpressBitFieldRead16 (Address, StartBit, EndBit) : + PciCf8BitFieldRead16 (Address, StartBit, EndBit); +} + +/** + Writes a bit field to a PCI configuration register. + + Writes Value to the bit field of the PCI configuration register. The bit + field is specified by the StartBit and the EndBit. All other bits in the + destination PCI configuration register are preserved. The new value of the + 16-bit register is returned. + + If Address > 0x0FFFFFFF, then ASSERT(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + If StartBit is greater than 15, then ASSERT(). + If EndBit is greater than 15, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). + + @param Address The PCI configuration register to write. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..15. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..15. + @param Value The new value of the bit field. + + @return The value written back to the PCI configuration register. + +**/ +UINT16 +EFIAPI +PciBitFieldWrite16 ( + IN UINTN Address, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT16 Value + ) +{ + return mRunningOnIch10 ? + PciExpressBitFieldWrite16 (Address, StartBit, EndBit, Value) : + PciCf8BitFieldWrite16 (Address, StartBit, EndBit, Value); +} + +/** + Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and + writes the result back to the bit field in the 16-bit port. + + Reads the 16-bit PCI configuration register specified by Address, performs a + bitwise OR between the read result and the value specified by + OrData, and writes the result to the 16-bit PCI configuration register + specified by Address. The value written to the PCI configuration register is + returned. This function must guarantee that all PCI read and write operations + are serialized. Extra left bits in OrData are stripped. + + If Address > 0x0FFFFFFF, then ASSERT(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + If StartBit is greater than 15, then ASSERT(). + If EndBit is greater than 15, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). + + @param Address The PCI configuration register to write. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..15. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..15. + @param OrData The value to OR with the PCI configuration register. + + @return The value written back to the PCI configuration register. + +**/ +UINT16 +EFIAPI +PciBitFieldOr16 ( + IN UINTN Address, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT16 OrData + ) +{ + return mRunningOnIch10 ? + PciExpressBitFieldOr16 (Address, StartBit, EndBit, OrData) : + PciCf8BitFieldOr16 (Address, StartBit, EndBit, OrData); +} + +/** + Reads a bit field in a 16-bit PCI configuration register, performs a bitwise + AND, and writes the result back to the bit field in the 16-bit register. + + Reads the 16-bit PCI configuration register specified by Address, performs a + bitwise AND between the read result and the value specified by AndData, and + writes the result to the 16-bit PCI configuration register specified by + Address. The value written to the PCI configuration register is returned. + This function must guarantee that all PCI read and write operations are + serialized. Extra left bits in AndData are stripped. + + If Address > 0x0FFFFFFF, then ASSERT(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + If StartBit is greater than 15, then ASSERT(). + If EndBit is greater than 15, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). + + @param Address The PCI configuration register to write. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..15. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..15. + @param AndData The value to AND with the PCI configuration register. + + @return The value written back to the PCI configuration register. + +**/ +UINT16 +EFIAPI +PciBitFieldAnd16 ( + IN UINTN Address, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT16 AndData + ) +{ + return mRunningOnIch10 ? + PciExpressBitFieldAnd16 (Address, StartBit, EndBit, AndData) : + PciCf8BitFieldAnd16 (Address, StartBit, EndBit, AndData); +} + +/** + Reads a bit field in a 16-bit port, performs a bitwise AND followed by a + bitwise OR, and writes the result back to the bit field in the + 16-bit port. + + Reads the 16-bit PCI configuration register specified by Address, performs a + bitwise AND followed by a bitwise OR between the read result and + the value specified by AndData, and writes the result to the 16-bit PCI + configuration register specified by Address. The value written to the PCI + configuration register is returned. This function must guarantee that all PCI + read and write operations are serialized. Extra left bits in both AndData and + OrData are stripped. + + If Address > 0x0FFFFFFF, then ASSERT(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + If StartBit is greater than 15, then ASSERT(). + If EndBit is greater than 15, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). + If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). + + @param Address The PCI configuration register to write. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..15. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..15. + @param AndData The value to AND with the PCI configuration register. + @param OrData The value to OR with the result of the AND operation. + + @return The value written back to the PCI configuration register. + +**/ +UINT16 +EFIAPI +PciBitFieldAndThenOr16 ( + IN UINTN Address, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT16 AndData, + IN UINT16 OrData + ) +{ + return mRunningOnIch10 ? + PciExpressBitFieldAndThenOr16 (Address, StartBit, EndBit, AndData, OrData) : + PciCf8BitFieldAndThenOr16 (Address, StartBit, EndBit, AndData, OrData); +} + +/** + Reads a 32-bit PCI configuration register. + + Reads and returns the 32-bit PCI configuration register specified by Address. + This function must guarantee that all PCI read and write operations are + serialized. + + If Address > 0x0FFFFFFF, then ASSERT(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + + @param Address The address that encodes the PCI Bus, Device, Function and + Register. + + @return The read value from the PCI configuration register. + +**/ +UINT32 +EFIAPI +PciRead32 ( + IN UINTN Address + ) +{ + return mRunningOnIch10 ? + PciExpressRead32 (Address) : + PciCf8Read32 (Address); +} + +/** + Writes a 32-bit PCI configuration register. + + Writes the 32-bit PCI configuration register specified by Address with the + value specified by Value. Value is returned. This function must guarantee + that all PCI read and write operations are serialized. + + If Address > 0x0FFFFFFF, then ASSERT(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + + @param Address The address that encodes the PCI Bus, Device, Function and + Register. + @param Value The value to write. + + @return The value written to the PCI configuration register. + +**/ +UINT32 +EFIAPI +PciWrite32 ( + IN UINTN Address, + IN UINT32 Value + ) +{ + return mRunningOnIch10 ? + PciExpressWrite32 (Address, Value) : + PciCf8Write32 (Address, Value); +} + +/** + Performs a bitwise OR of a 32-bit PCI configuration register with + a 32-bit value. + + Reads the 32-bit PCI configuration register specified by Address, performs a + bitwise OR between the read result and the value specified by + OrData, and writes the result to the 32-bit PCI configuration register + specified by Address. The value written to the PCI configuration register is + returned. This function must guarantee that all PCI read and write operations + are serialized. + + If Address > 0x0FFFFFFF, then ASSERT(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + + @param Address The address that encodes the PCI Bus, Device, Function and + Register. + @param OrData The value to OR with the PCI configuration register. + + @return The value written back to the PCI configuration register. + +**/ +UINT32 +EFIAPI +PciOr32 ( + IN UINTN Address, + IN UINT32 OrData + ) +{ + return mRunningOnIch10 ? + PciExpressOr32 (Address, OrData) : + PciCf8Or32 (Address, OrData); +} + +/** + Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit + value. + + Reads the 32-bit PCI configuration register specified by Address, performs a + bitwise AND between the read result and the value specified by AndData, and + writes the result to the 32-bit PCI configuration register specified by + Address. The value written to the PCI configuration register is returned. + This function must guarantee that all PCI read and write operations are + serialized. + + If Address > 0x0FFFFFFF, then ASSERT(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + + @param Address The address that encodes the PCI Bus, Device, Function and + Register. + @param AndData The value to AND with the PCI configuration register. + + @return The value written back to the PCI configuration register. + +**/ +UINT32 +EFIAPI +PciAnd32 ( + IN UINTN Address, + IN UINT32 AndData + ) +{ + return mRunningOnIch10 ? + PciExpressAnd32 (Address, AndData) : + PciCf8And32 (Address, AndData); +} + +/** + Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit + value, followed a bitwise OR with another 32-bit value. + + Reads the 32-bit PCI configuration register specified by Address, performs a + bitwise AND between the read result and the value specified by AndData, + performs a bitwise OR between the result of the AND operation and + the value specified by OrData, and writes the result to the 32-bit PCI + configuration register specified by Address. The value written to the PCI + configuration register is returned. This function must guarantee that all PCI + read and write operations are serialized. + + If Address > 0x0FFFFFFF, then ASSERT(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + + @param Address The address that encodes the PCI Bus, Device, Function and + Register. + @param AndData The value to AND with the PCI configuration register. + @param OrData The value to OR with the result of the AND operation. + + @return The value written back to the PCI configuration register. + +**/ +UINT32 +EFIAPI +PciAndThenOr32 ( + IN UINTN Address, + IN UINT32 AndData, + IN UINT32 OrData + ) +{ + return mRunningOnIch10 ? + PciExpressAndThenOr32 (Address, AndData, OrData) : + PciCf8AndThenOr32 (Address, AndData, OrData); +} + +/** + Reads a bit field of a PCI configuration register. + + Reads the bit field in a 32-bit PCI configuration register. The bit field is + specified by the StartBit and the EndBit. The value of the bit field is + returned. + + If Address > 0x0FFFFFFF, then ASSERT(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + If StartBit is greater than 31, then ASSERT(). + If EndBit is greater than 31, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Address The PCI configuration register to read. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..31. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..31. + + @return The value of the bit field read from the PCI configuration register. + +**/ +UINT32 +EFIAPI +PciBitFieldRead32 ( + IN UINTN Address, + IN UINTN StartBit, + IN UINTN EndBit + ) +{ + return mRunningOnIch10 ? + PciExpressBitFieldRead32 (Address, StartBit, EndBit) : + PciCf8BitFieldRead32 (Address, StartBit, EndBit); +} + +/** + Writes a bit field to a PCI configuration register. + + Writes Value to the bit field of the PCI configuration register. The bit + field is specified by the StartBit and the EndBit. All other bits in the + destination PCI configuration register are preserved. The new value of the + 32-bit register is returned. + + If Address > 0x0FFFFFFF, then ASSERT(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + If StartBit is greater than 31, then ASSERT(). + If EndBit is greater than 31, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). + + @param Address The PCI configuration register to write. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..31. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..31. + @param Value The new value of the bit field. + + @return The value written back to the PCI configuration register. + +**/ +UINT32 +EFIAPI +PciBitFieldWrite32 ( + IN UINTN Address, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT32 Value + ) +{ + return mRunningOnIch10 ? + PciExpressBitFieldWrite32 (Address, StartBit, EndBit, Value) : + PciCf8BitFieldWrite32 (Address, StartBit, EndBit, Value); +} + +/** + Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and + writes the result back to the bit field in the 32-bit port. + + Reads the 32-bit PCI configuration register specified by Address, performs a + bitwise OR between the read result and the value specified by + OrData, and writes the result to the 32-bit PCI configuration register + specified by Address. The value written to the PCI configuration register is + returned. This function must guarantee that all PCI read and write operations + are serialized. Extra left bits in OrData are stripped. + + If Address > 0x0FFFFFFF, then ASSERT(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + If StartBit is greater than 31, then ASSERT(). + If EndBit is greater than 31, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). + + @param Address The PCI configuration register to write. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..31. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..31. + @param OrData The value to OR with the PCI configuration register. + + @return The value written back to the PCI configuration register. + +**/ +UINT32 +EFIAPI +PciBitFieldOr32 ( + IN UINTN Address, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT32 OrData + ) +{ + return mRunningOnIch10 ? + PciExpressBitFieldOr32 (Address, StartBit, EndBit, OrData) : + PciCf8BitFieldOr32 (Address, StartBit, EndBit, OrData); +} + +/** + Reads a bit field in a 32-bit PCI configuration register, performs a bitwise + AND, and writes the result back to the bit field in the 32-bit register. + + Reads the 32-bit PCI configuration register specified by Address, performs a + bitwise AND between the read result and the value specified by AndData, and + writes the result to the 32-bit PCI configuration register specified by + Address. The value written to the PCI configuration register is returned. + This function must guarantee that all PCI read and write operations are + serialized. Extra left bits in AndData are stripped. + + If Address > 0x0FFFFFFF, then ASSERT(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + If StartBit is greater than 31, then ASSERT(). + If EndBit is greater than 31, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). + + @param Address The PCI configuration register to write. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..31. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..31. + @param AndData The value to AND with the PCI configuration register. + + @return The value written back to the PCI configuration register. + +**/ +UINT32 +EFIAPI +PciBitFieldAnd32 ( + IN UINTN Address, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT32 AndData + ) +{ + return mRunningOnIch10 ? + PciExpressBitFieldAnd32 (Address, StartBit, EndBit, AndData) : + PciCf8BitFieldAnd32 (Address, StartBit, EndBit, AndData); +} + +/** + Reads a bit field in a 32-bit port, performs a bitwise AND followed by a + bitwise OR, and writes the result back to the bit field in the + 32-bit port. + + Reads the 32-bit PCI configuration register specified by Address, performs a + bitwise AND followed by a bitwise OR between the read result and + the value specified by AndData, and writes the result to the 32-bit PCI + configuration register specified by Address. The value written to the PCI + configuration register is returned. This function must guarantee that all PCI + read and write operations are serialized. Extra left bits in both AndData and + OrData are stripped. + + If Address > 0x0FFFFFFF, then ASSERT(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + If StartBit is greater than 31, then ASSERT(). + If EndBit is greater than 31, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). + If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). + + @param Address The PCI configuration register to write. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..31. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..31. + @param AndData The value to AND with the PCI configuration register. + @param OrData The value to OR with the result of the AND operation. + + @return The value written back to the PCI configuration register. + +**/ +UINT32 +EFIAPI +PciBitFieldAndThenOr32 ( + IN UINTN Address, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT32 AndData, + IN UINT32 OrData + ) +{ + return mRunningOnIch10 ? + PciExpressBitFieldAndThenOr32 (Address, StartBit, EndBit, AndData, OrData) : + PciCf8BitFieldAndThenOr32 (Address, StartBit, EndBit, AndData, OrData); +} + +/** + Reads a range of PCI configuration registers into a caller supplied buffer. + + Reads the range of PCI configuration registers specified by StartAddress and + Size into the buffer specified by Buffer. This function only allows the PCI + configuration registers from a single PCI function to be read. Size is + returned. When possible 32-bit PCI configuration read cycles are used to read + from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit + and 16-bit PCI configuration read cycles may be used at the beginning and the + end of the range. + + If StartAddress > 0x0FFFFFFF, then ASSERT(). + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT(). + If Size > 0 and Buffer is NULL, then ASSERT(). + + @param StartAddress The starting address that encodes the PCI Bus, Device, + Function and Register. + @param Size The size in bytes of the transfer. + @param Buffer The pointer to a buffer receiving the data read. + + @return Size + +**/ +UINTN +EFIAPI +PciReadBuffer ( + IN UINTN StartAddress, + IN UINTN Size, + OUT VOID *Buffer + ) +{ + return mRunningOnIch10 ? + PciExpressReadBuffer (StartAddress, Size, Buffer) : + PciCf8ReadBuffer (StartAddress, Size, Buffer); +} + +/** + Copies the data in a caller supplied buffer to a specified range of PCI + configuration space. + + Writes the range of PCI configuration registers specified by StartAddress and + Size from the buffer specified by Buffer. This function only allows the PCI + configuration registers from a single PCI function to be written. Size is + returned. When possible 32-bit PCI configuration write cycles are used to + write from StartAdress to StartAddress + Size. Due to alignment restrictions, + 8-bit and 16-bit PCI configuration write cycles may be used at the beginning + and the end of the range. + + If StartAddress > 0x0FFFFFFF, then ASSERT(). + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT(). + If Size > 0 and Buffer is NULL, then ASSERT(). + + @param StartAddress The starting address that encodes the PCI Bus, Device, + Function and Register. + @param Size The size in bytes of the transfer. + @param Buffer The pointer to a buffer containing the data to write. + + @return Size written to StartAddress. + +**/ +UINTN +EFIAPI +PciWriteBuffer ( + IN UINTN StartAddress, + IN UINTN Size, + IN VOID *Buffer + ) +{ + return mRunningOnIch10 ? + PciExpressWriteBuffer (StartAddress, Size, Buffer) : + PciCf8WriteBuffer (StartAddress, Size, Buffer); +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c new file mode 100644 index 0000000000..b1d7552792 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c @@ -0,0 +1,1579 @@ +/** @file + ACPI Platform Driver + + Copyright (c) 2017 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "AcpiPlatform.h" + +#define MAX_CPU_NUM (FixedPcdGet32(PcdMaxCpuThreadCount) * FixedPcdGet32(PcdMaxCpuCoreCount) * 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[] = { + &Facs, + &Fadt, + &Hpet, + &Wsmt, +}; + +EFI_ACPI_TABLE_PROTOCOL *mAcpiTable; + +UINT32 mNumOfBitShift = 6; +BOOLEAN mForceX2ApicId; +BOOLEAN mX2ApicEnabled; + +EFI_MP_SERVICES_PROTOCOL *mMpService; +BOOLEAN mCpuOrderSorted; +EFI_CPU_ID_ORDER_MAP mCpuApicIdOrderTable[MAX_CPU_NUM]; +UINTN mNumberOfCPUs = 0; +UINTN mNumberOfEnabledCPUs = 0; +// +// following are possible APICID Map for SKX +// +static const UINT32 ApicIdMapA[] = { //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[] = { //for SKUs have number of cores <= 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[] = { //for SKUs have number of cores <= 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[] = { //for SKUs have number of cores <= 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 = NULL; + +/** + This function detect the APICID map and update ApicID Map pointer + + @param None + + @retval VOID + +**/ +VOID DetectApicIdMap(VOID) +{ + UINTN CoreCount; + + CoreCount = 0; + + if(mApicIdMap != NULL) { + return; //aleady initialized + } + + mApicIdMap = ApicIdMapA; // default to > 16C SKUs + + CoreCount = mNumberOfEnabledCPUs / 2; + DEBUG ((DEBUG_INFO, "CoreCount - %d\n", CoreCount)); + + if(CoreCount <= 16) { + + if(mNumOfBitShift == 4) { + mApicIdMap = ApicIdMapD; + } + + if(mNumOfBitShift == 5) { + mApicIdMap = ApicIdMapB; + } + + if(mNumOfBitShift == 6) { + mApicIdMap = ApicIdMapC; + } + + } + + return; +} + +/** + This function return the CoreThreadId of ApicId from ACPI ApicId Map array + + @param ApicId + + @retval Index of ACPI ApicId Map array + +**/ +UINT32 +GetIndexFromApicId ( + UINT32 ApicId + ) +{ + UINT32 CoreThreadId; + UINT32 i; + + ASSERT (mApicIdMap != NULL); + + CoreThreadId = ApicId & ((1 << mNumOfBitShift) - 1); + + for(i = 0; i < (FixedPcdGet32(PcdMaxCpuCoreCount) * FixedPcdGet32(PcdMaxCpuThreadCount)); i++) { + if(mApicIdMap[i] == CoreThreadId) { + break; + } + } + + ASSERT (i <= (FixedPcdGet32(PcdMaxCpuCoreCount) * FixedPcdGet32(PcdMaxCpuThreadCount))); + + return i; +} + +UINT32 +ApicId2SwProcApicId ( + UINT32 ApicId + ) +{ + UINT32 Index; + + for (Index = 0; Index < MAX_CPU_NUM; Index++) { + if ((mCpuApicIdOrderTable[Index].Flags == 1) && (mCpuApicIdOrderTable[Index].ApicId == ApicId)) { + return Index; + } + } + + return (UINT32) -1; + +} + +VOID +DebugDisplayReOrderTable( + VOID + ) +{ + UINT32 Index; + + DEBUG ((EFI_D_ERROR, "Index AcpiProcId ApicId Flags SwApicId Skt\n")); + for (Index=0; IndexAcpiApicCommon.Type; + LocalApicPtr = (EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE *)(&((ACPI_APIC_STRUCTURE_PTR *)ApicPtr)->AcpiLocalApic); + LocalX2ApicPtr = (EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE *)(&((ACPI_APIC_STRUCTURE_PTR *)ApicPtr)->AcpiLocalx2Apic); + + if(Type == EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC) { + if(!mX2ApicEnabled) { + LocalApicPtr->Flags = (UINT8)mCpuApicIdOrderTable[LocalApicCounter].Flags; + LocalApicPtr->ApicId = (UINT8)mCpuApicIdOrderTable[LocalApicCounter].ApicId; + LocalApicPtr->AcpiProcessorId = (UINT8)mCpuApicIdOrderTable[LocalApicCounter].AcpiProcessorId; + } else { + LocalApicPtr->Flags = 0; + LocalApicPtr->ApicId = 0xFF; + LocalApicPtr->AcpiProcessorId = (UINT8)0xFF; + Status = EFI_UNSUPPORTED; + } + } else if(Type == EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC) { + if(mX2ApicEnabled) { + LocalX2ApicPtr->Flags = (UINT8)mCpuApicIdOrderTable[LocalApicCounter].Flags; + LocalX2ApicPtr->X2ApicId = mCpuApicIdOrderTable[LocalApicCounter].ApicId; + LocalX2ApicPtr->AcpiProcessorUid = mCpuApicIdOrderTable[LocalApicCounter].AcpiProcessorId; + } else { + LocalX2ApicPtr->Flags = 0; + LocalX2ApicPtr->X2ApicId = (UINT32)-1; + LocalX2ApicPtr->AcpiProcessorUid = (UINT32)-1; + Status = EFI_UNSUPPORTED; + } + } else { + Status = EFI_UNSUPPORTED; + } + + return Status; + +} + +EFI_STATUS +SortCpuLocalApicInTable ( + VOID + ) +{ + EFI_STATUS Status; + EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer; + UINT32 Index; + UINT32 CurrProcessor; + UINT32 BspApicId; + UINT32 TempVal = 0; + EFI_CPU_ID_ORDER_MAP *CpuIdMapPtr; + UINT32 CoreThreadMask; + + Index = 0; + Status = EFI_SUCCESS; + + CoreThreadMask = (UINT32) ((1 << mNumOfBitShift) - 1); + + if(!mCpuOrderSorted) { + + Index = 0; + + for (CurrProcessor = 0; CurrProcessor < mNumberOfCPUs; CurrProcessor++) { + Status = mMpService->GetProcessorInfo ( + mMpService, + CurrProcessor, + &ProcessorInfoBuffer + ); + + if ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) != 0) { + if(ProcessorInfoBuffer.ProcessorId & 1) { //is 2nd thread + CpuIdMapPtr = (EFI_CPU_ID_ORDER_MAP *)&mCpuApicIdOrderTable[(Index - 1) + MAX_CPU_NUM / 2]; + } else { //is primary thread + CpuIdMapPtr = (EFI_CPU_ID_ORDER_MAP *)&mCpuApicIdOrderTable[Index]; + Index++; + } + CpuIdMapPtr->ApicId = (UINT32)ProcessorInfoBuffer.ProcessorId; + CpuIdMapPtr->Flags = ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) != 0); + CpuIdMapPtr->SocketNum = (UINT32)ProcessorInfoBuffer.Location.Package; + CpuIdMapPtr->AcpiProcessorId = (CpuIdMapPtr->SocketNum * FixedPcdGet32(PcdMaxCpuCoreCount) * FixedPcdGet32(PcdMaxCpuThreadCount)) + GetIndexFromApicId(CpuIdMapPtr->ApicId); //CpuIdMapPtr->ApicId; + CpuIdMapPtr->SwProcApicId = ((UINT32)(ProcessorInfoBuffer.Location.Package << mNumOfBitShift) + (((UINT32)ProcessorInfoBuffer.ProcessorId) & CoreThreadMask)); + if(mX2ApicEnabled) { //if X2Apic, re-order the socket # so it starts from base 0 and contiguous + //may not necessory!!!!! + } + + //update processorbitMask + if (CpuIdMapPtr->Flags == 1) { + + if(mForceX2ApicId) { + CpuIdMapPtr->SocketNum &= 0x7; + CpuIdMapPtr->AcpiProcessorId &= 0xFF; //keep lower 8bit due to use Proc obj in dsdt + CpuIdMapPtr->SwProcApicId &= 0xFF; + } + } + } else { //not enabled + CpuIdMapPtr = (EFI_CPU_ID_ORDER_MAP *)&mCpuApicIdOrderTable[Index]; + CpuIdMapPtr->ApicId = (UINT32)-1; + CpuIdMapPtr->Flags = 0; + CpuIdMapPtr->AcpiProcessorId = (UINT32)-1; + CpuIdMapPtr->SwProcApicId = (UINT32)-1; + CpuIdMapPtr->SocketNum = (UINT32)-1; + } //end if PROC ENABLE + } //end for CurrentProcessor + // + //keep for debug purpose + // + DEBUG(( EFI_D_ERROR, "::ACPI:: APIC ID Order Table Init. CoreThreadMask = %x, mNumOfBitShift = %x\n", CoreThreadMask, mNumOfBitShift)); + DebugDisplayReOrderTable(); + // + //make sure 1st entry is BSP + // + if(mX2ApicEnabled) { + BspApicId = (UINT32)AsmReadMsr64(0x802); + } else { + BspApicId = (*(volatile UINT32 *)(UINTN)0xFEE00020) >> 24; + } + DEBUG ((EFI_D_INFO, "BspApicId - 0x%x\n", BspApicId)); + + if(mCpuApicIdOrderTable[0].ApicId != BspApicId) { + // + //check to see if 1st entry is BSP, if not swap it + // + Index = ApicId2SwProcApicId(BspApicId); + + if(MAX_CPU_NUM <= Index) { + DEBUG ((EFI_D_ERROR, "Asserting the SortCpuLocalApicInTable Index Bufferflow\n")); + ASSERT_EFI_ERROR(EFI_INVALID_PARAMETER); + } + + TempVal = mCpuApicIdOrderTable[Index].ApicId; + mCpuApicIdOrderTable[Index].ApicId = mCpuApicIdOrderTable[0].ApicId; + mCpuApicIdOrderTable[0].ApicId = TempVal; + mCpuApicIdOrderTable[Index].Flags = mCpuApicIdOrderTable[0].Flags; + mCpuApicIdOrderTable[0].Flags = 1; + TempVal = mCpuApicIdOrderTable[Index].SwProcApicId; + mCpuApicIdOrderTable[Index].SwProcApicId = mCpuApicIdOrderTable[0].SwProcApicId; + mCpuApicIdOrderTable[0].SwProcApicId = TempVal; + // + //swap AcpiProcId + // + TempVal = mCpuApicIdOrderTable[Index].AcpiProcessorId; + mCpuApicIdOrderTable[Index].AcpiProcessorId = mCpuApicIdOrderTable[0].AcpiProcessorId; + mCpuApicIdOrderTable[0].AcpiProcessorId = TempVal; + + } + // + //Make sure no holes between enabled threads + // + for(CurrProcessor = 0; CurrProcessor < MAX_CPU_NUM; CurrProcessor++) { + + if(mCpuApicIdOrderTable[CurrProcessor].Flags == 0) { + // + //make sure disabled entry has ProcId set to FFs + // + mCpuApicIdOrderTable[CurrProcessor].ApicId = (UINT32)-1; + mCpuApicIdOrderTable[CurrProcessor].AcpiProcessorId = (UINT32)-1; + mCpuApicIdOrderTable[CurrProcessor].SwProcApicId = (UINT32)-1; + + for(Index = CurrProcessor+1; Index < MAX_CPU_NUM; Index++) { + if(mCpuApicIdOrderTable[Index].Flags == 1) { + // + //move enabled entry up + // + mCpuApicIdOrderTable[CurrProcessor].Flags = 1; + mCpuApicIdOrderTable[CurrProcessor].ApicId = mCpuApicIdOrderTable[Index].ApicId; + mCpuApicIdOrderTable[CurrProcessor].AcpiProcessorId = mCpuApicIdOrderTable[Index].AcpiProcessorId; + mCpuApicIdOrderTable[CurrProcessor].SwProcApicId = mCpuApicIdOrderTable[Index].SwProcApicId; + mCpuApicIdOrderTable[CurrProcessor].SocketNum = mCpuApicIdOrderTable[Index].SocketNum; + // + //disable moved entry + // + mCpuApicIdOrderTable[Index].Flags = 0; + mCpuApicIdOrderTable[Index].ApicId = (UINT32)-1; + mCpuApicIdOrderTable[Index].AcpiProcessorId = (UINT32)-1; + mCpuApicIdOrderTable[Index].SwProcApicId = (UINT32)-1; + break; + } + } + } + } + // + //keep for debug purpose + // + DEBUG ((EFI_D_ERROR, "APIC ID Order Table ReOrdered\n")); + DebugDisplayReOrderTable(); + + mCpuOrderSorted = 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[] = { + {EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC, sizeof (EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE)}, + {EFI_ACPI_4_0_IO_APIC, sizeof (EFI_ACPI_4_0_IO_APIC_STRUCTURE)}, + {EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE, sizeof (EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE)}, + {EFI_ACPI_4_0_NON_MASKABLE_INTERRUPT_SOURCE, sizeof (EFI_ACPI_4_0_NON_MASKABLE_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_SAPIC_STRUCTURE)}, + {EFI_ACPI_4_0_LOCAL_SAPIC, sizeof (EFI_ACPI_4_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE)}, + {EFI_ACPI_4_0_PLATFORM_INTERRUPT_SOURCES, sizeof (EFI_ACPI_4_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE)}, + {EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC, sizeof (EFI_ACPI_4_0_PROCESSOR_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, not 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 = (UINT32) TableSpecificHdrLength; + + for (Index = 0; Index < StructureCount; Index++) { + ASSERT (Structures[Index] != NULL); + if (Structures[Index] == NULL) { + return 0; + } + + TableLength += 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, not 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 = GetTableSize (TableSpecificHdrLength, Structures, StructureCount); + InternalTable = (EFI_ACPI_DESCRIPTION_HEADER *) AllocatePool (Size); + + if (InternalTable == NULL) { + Status = EFI_OUT_OF_RESOURCES; + DEBUG (( + DEBUG_ERROR, + "Failed to allocate %d bytes for ACPI Table\n", + Size + )); + } else { + Status = EFI_SUCCESS; + DEBUG (( + DEBUG_INFO, + "Successfully allocated %d bytes for ACPI Table at 0x%p\n", + Size, + InternalTable + )); + *Table = 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 == NULL) { + DEBUG ((DEBUG_ERROR, "Header pointer is NULL\n")); + return EFI_INVALID_PARAMETER; + } + + Header->Signature = Signature; + Header->Length = 0; // filled in by Build function + Header->Revision = Revision; + Header->Checksum = 0; // filled in by InstallAcpiTable + + CopyMem ( + (VOID *) &Header->OemId, + PcdGetPtr (PcdAcpiDefaultOemId), + sizeof (Header->OemId) + ); + + AcpiTableOemId = PcdGet64 (PcdAcpiDefaultOemTableId); + CopyMem ( + (VOID *) &Header->OemTableId, + (VOID *) &AcpiTableOemId, + sizeof (Header->OemTableId) + ); + + Header->OemRevision = OemRevision; + Header->CreatorId = 0; + Header->CreatorRevision = 0; + + return EFI_SUCCESS; +} + +/** + Initialize the MADT header. + + This function fills in the MADT's standard table header with correct values, + 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 == NULL) { + DEBUG ((DEBUG_ERROR, "MADT header pointer is NULL\n")); + return EFI_INVALID_PARAMETER; + } + + Status = 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 = PcdGet32(PcdLocalApicAddress); + MadtHeader->Flags = 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 table header passed in. + // + if (Header->Signature == EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE) { + TableNumEntries = sizeof (mMadtStructureTable) / sizeof (STRUCTURE_HEADER); + StructureTable = mMadtStructureTable; + } else { + return EFI_UNSUPPORTED; + } + + // + // Check the incoming structure against the table of supported structures. + // + EntryFound = FALSE; + for (Index = 0; Index < TableNumEntries; Index++) { + if (Structure->Type == StructureTable[Index].Type) { + if (Structure->Length == StructureTable[Index].Length) { + EntryFound = 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 = (STRUCTURE_HEADER *) AllocatePool (Structure->Length); + if (NewStructureInternal == 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 = 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 this + function. + + @param[in] AcpiHeader Pointer to the header structure. + @param[in] TableSpecificHdrLength Size of the table specific header, not 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] NewTable Newly allocated and initialized pointer 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 allocated. +**/ +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 == NULL) { + DEBUG ((DEBUG_ERROR, "AcpiHeader pointer is NULL\n")); + return EFI_INVALID_PARAMETER; + } + + if (AcpiHeader->Signature != EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE) { + DEBUG (( + DEBUG_ERROR, + "MADT header signature is expected, actually 0x%08x\n", + AcpiHeader->Signature + )); + return EFI_INVALID_PARAMETER; + } + + if (Structures == NULL) { + DEBUG ((DEBUG_ERROR, "Structure array pointer is NULL\n")); + return EFI_INVALID_PARAMETER; + } + + for (Index = 0; Index < StructureCount; Index++) { + if (Structures[Index] == NULL) { + DEBUG ((DEBUG_ERROR, "Structure pointer %d is NULL\n", Index)); + return EFI_INVALID_PARAMETER; + } + } + + // + // Allocate the memory needed for the table. + // + Status = AllocateTable ( + TableSpecificHdrLength, + Structures, + StructureCount, + &InternalTable + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Copy Header and patch in structure length, checksum is programmed later + // after all structures are populated. + // + CopyMem ( + (VOID *) InternalTable, + (VOID *) AcpiHeader, + TableSpecificHdrLength + ); + + InternalTable->Length = GetTableSize (TableSpecificHdrLength, Structures, StructureCount); + + // + // Copy all the sub structures to the table. + // + CurrPtr = ((UINT8 *) InternalTable) + TableSpecificHdrLength; + EndOfTablePtr = ((UINT8 *) InternalTable) + InternalTable->Length; + + for (Index = 0; Index < StructureCount; Index++) { + ASSERT (Structures[Index] != NULL); + if (Structures[Index] == NULL) { + break; + } + + CopyMem ( + (VOID *) CurrPtr, + (VOID *) Structures[Index], + Structures[Index]->Length + ); + + CurrPtr += Structures[Index]->Length; + ASSERT (CurrPtr <= EndOfTablePtr); + if (CurrPtr > EndOfTablePtr) { + break; + } + } + + // + // Update the return pointer. + // + *NewTable = (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 ProcLocalX2ApicStruct; + EFI_ACPI_4_0_LOCAL_X2APIC_NMI_STRUCTURE LocalX2ApicNmiStruct; + STRUCTURE_HEADER **MadtStructs; + UINTN MaxMadtStructCount; + UINTN MadtStructsIndex; + UINT32 CurrentIoApicAddress = (UINT32)(PcdGet32(PcdPcIoApicAddressBase)); + UINT32 PcIoApicEnable; + UINT32 PcIoApicMask; + UINTN PcIoApicIndex; + + DetectApicIdMap(); + + // Call for Local APIC ID Reorder + SortCpuLocalApicInTable (); + + NewMadtTable = NULL; + + MaxMadtStructCount = (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 = (STRUCTURE_HEADER **) AllocateZeroPool (MaxMadtStructCount * sizeof (STRUCTURE_HEADER *)); + if (MadtStructs == 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 = 0; + + // + // Initialize MADT Header Structure + // + Status = 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 = %d \n", mNumberOfCPUs)); + + // + // Build Processor Local APIC Structures and Processor Local X2APIC Structures + // + ProcLocalApicStruct.Type = EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC; + ProcLocalApicStruct.Length = sizeof (EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE); + + ProcLocalX2ApicStruct.Type = EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC; + ProcLocalX2ApicStruct.Length = sizeof (EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE); + ProcLocalX2ApicStruct.Reserved[0] = 0; + ProcLocalX2ApicStruct.Reserved[1] = 0; + + for (Index = 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 = (UINT8) mCpuApicIdOrderTable[Index].Flags; + ProcLocalApicStruct.ApicId = (UINT8) mCpuApicIdOrderTable[Index].ApicId; + ProcLocalApicStruct.AcpiProcessorId = (UINT8) mCpuApicIdOrderTable[Index].AcpiProcessorId; + + ASSERT (MadtStructsIndex < MaxMadtStructCount); + Status = CopyStructure ( + &MadtTableHeader.Header, + (STRUCTURE_HEADER *) &ProcLocalApicStruct, + &MadtStructs[MadtStructsIndex++] + ); + } else if (mCpuApicIdOrderTable[Index].ApicId != 0xFFFFFFFF) { + ProcLocalX2ApicStruct.Flags = (UINT8) mCpuApicIdOrderTable[Index].Flags; + ProcLocalX2ApicStruct.X2ApicId = mCpuApicIdOrderTable[Index].ApicId; + ProcLocalX2ApicStruct.AcpiProcessorUid = mCpuApicIdOrderTable[Index].AcpiProcessorId; + + ASSERT (MadtStructsIndex < MaxMadtStructCount); + Status = 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 = EFI_ACPI_4_0_IO_APIC; + IoApicStruct.Length = sizeof (EFI_ACPI_4_0_IO_APIC_STRUCTURE); + IoApicStruct.Reserved = 0; + + PcIoApicEnable = PcdGet32(PcdPcIoApicEnable); + + if (FixedPcdGet32(PcdMaxCpuSocketCount) <= 4) { + IoApicStruct.IoApicId = PcdGet8(PcdIoApicId); + IoApicStruct.IoApicAddress = PcdGet32(PcdIoApicAddress); + IoApicStruct.GlobalSystemInterruptBase = 0; + ASSERT (MadtStructsIndex < MaxMadtStructCount); + Status = 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; + } + } + + for (PcIoApicIndex = 0; PcIoApicIndex < PcdGet8(PcdPcIoApicCount); PcIoApicIndex++) { + PcIoApicMask = (1 << PcIoApicIndex); + if ((PcIoApicEnable & PcIoApicMask) == 0) { + continue; + } + + IoApicStruct.IoApicId = (UINT8)(PcdGet8(PcdPcIoApicIdBase) + PcIoApicIndex); + IoApicStruct.IoApicAddress = CurrentIoApicAddress; + CurrentIoApicAddress = (CurrentIoApicAddress & 0xFFFF8000) + 0x8000; + IoApicStruct.GlobalSystemInterruptBase = (UINT32)(24 + (PcIoApicIndex * 8)); + ASSERT (MadtStructsIndex < MaxMadtStructCount); + Status = 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 = EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE; + IntSrcOverrideStruct.Length = sizeof (EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE); + + // + // IRQ0=>IRQ2 Interrupt Source Override Structure + // + IntSrcOverrideStruct.Bus = 0x0; // Bus - ISA + IntSrcOverrideStruct.Source = 0x0; // Source - IRQ0 + IntSrcOverrideStruct.GlobalSystemInterrupt = 0x2; // Global System Interrupt - IRQ2 + IntSrcOverrideStruct.Flags = 0x0; // Flags - Conforms to specifications of the bus + + ASSERT (MadtStructsIndex < MaxMadtStructCount); + Status = 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 = 0x0; // Bus - ISA + IntSrcOverrideStruct.Source = 0x9; // Source - IRQ9 + IntSrcOverrideStruct.GlobalSystemInterrupt = 0x9; // Global System Interrupt - IRQ9 + IntSrcOverrideStruct.Flags = 0xD; // Flags - Level-tiggered, Active High + + ASSERT (MadtStructsIndex < MaxMadtStructCount); + Status = 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 = EFI_ACPI_4_0_LOCAL_APIC_NMI; + LocalApciNmiStruct.Length = sizeof (EFI_ACPI_4_0_LOCAL_APIC_NMI_STRUCTURE); + LocalApciNmiStruct.AcpiProcessorId = 0xFF; // Applies to all processors + LocalApciNmiStruct.Flags = 0x000D; // Flags - Level-tiggered, Active High + LocalApciNmiStruct.LocalApicLint = 0x1; + + ASSERT (MadtStructsIndex < MaxMadtStructCount); + Status = CopyStructure ( + &MadtTableHeader.Header, + (STRUCTURE_HEADER *) &LocalApciNmiStruct, + &MadtStructs[MadtStructsIndex++] + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "CopyMadtStructure (APIC NMI) failed: %r\n", Status)); + goto Done; + } + + // + // Build Local x2APIC NMI Structure + // + LocalX2ApicNmiStruct.Type = EFI_ACPI_4_0_LOCAL_X2APIC_NMI; + LocalX2ApicNmiStruct.Length = sizeof (EFI_ACPI_4_0_LOCAL_X2APIC_NMI_STRUCTURE); + LocalX2ApicNmiStruct.Flags = 0x000D; // Flags - Level-tiggered, Active High + LocalX2ApicNmiStruct.AcpiProcessorUid = 0xFFFFFFFF; // Applies to all processors + LocalX2ApicNmiStruct.LocalX2ApicLint = 0x01; + LocalX2ApicNmiStruct.Reserved[0] = 0x00; + LocalX2ApicNmiStruct.Reserved[1] = 0x00; + LocalX2ApicNmiStruct.Reserved[2] = 0x00; + + ASSERT (MadtStructsIndex < MaxMadtStructCount); + Status = CopyStructure ( + &MadtTableHeader.Header, + (STRUCTURE_HEADER *) &LocalX2ApicNmiStruct, + &MadtStructs[MadtStructsIndex++] + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "CopyMadtStructure (x2APIC NMI) failed: %r\n", Status)); + goto Done; + } + + // + // Build Madt Structure from the Madt Header and collection of pointers in MadtStructs[] + // + Status = 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 = mAcpiTable->InstallAcpiTable ( + mAcpiTable, + NewMadtTable, + NewMadtTable->Header.Length, + &TableHandle + ); + +Done: + // + // Free memory + // + for (MadtStructsIndex = 0; MadtStructsIndex < MaxMadtStructCount; MadtStructsIndex++) { + if (MadtStructs[MadtStructsIndex] != NULL) { + FreePool (MadtStructs[MadtStructsIndex]); + } + } + + FreePool (MadtStructs); + + if (NewMadtTable != 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_ALLOCATION_STRUCTURE *Segment; + UINTN Index; + UINTN SegmentCount; + PCI_SEGMENT_INFO *PciSegmentInfo; + UINTN TableHandle; + + PciSegmentInfo = GetPciSegmentInfo (&SegmentCount); + + McfgTable = AllocateZeroPool ( + sizeof(EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER) + + sizeof(EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE) * SegmentCount + ); + if (McfgTable == NULL) { + DEBUG ((DEBUG_ERROR, "Could not allocate MCFG structure\n")); + return EFI_OUT_OF_RESOURCES; + } + + Status = InitializeHeader ( + &McfgTable->Header, + EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_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 enumerated so far + // + McfgTable->Header.Length = (UINT32)(sizeof (EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER) + + sizeof (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE) * SegmentCount); + + Segment = (VOID *)(McfgTable + 1); + + for (Index = 0; Index < SegmentCount; Index++) { + Segment[Index].PciSegmentGroupNumber = PciSegmentInfo[Index].SegmentNumber; + Segment[Index].BaseAddress = PciSegmentInfo[Index].BaseAddress; + Segment[Index].StartBusNumber = PciSegmentInfo[Index].StartBusNumber; + Segment[Index].EndBusNumber = PciSegmentInfo[Index].EndBusNumber; + } + + // + // Publish Madt Structure to ACPI + // + Status = 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 revision. + 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 = NULL; + + // + // By default, a table belongs in all ACPI table versions published. + // Some tables will override this because they have different versions of the table. + // + TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table; + + // + // Update the OEM and creator information for every table except FACS. + // + if (Table->Signature != EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) { + TempOemId = (UINT8 *)PcdGetPtr(PcdAcpiDefaultOemId); + CopyMem (&TableHeader->OemId, TempOemId, 6); + + // + // Skip OEM table ID and creator information for DSDT, SSDT and PSDT tables, since these are + // created by an ASL compiler and the creator information is useful. + // + if (Table->Signature != EFI_ACPI_1_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE && + Table->Signature != EFI_ACPI_1_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE && + Table->Signature != EFI_ACPI_1_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE + ) { + TempOemTableId = PcdGet64(PcdAcpiDefaultOemTableId); + CopyMem (&TableHeader->OemTableId, &TempOemTableId, 8); + + // + // Update the creator ID + // + TableHeader->CreatorId = PcdGet32(PcdAcpiDefaultCreatorId); + + // + // Update the creator revision + // + TableHeader->CreatorRevision = PcdGet32(PcdAcpiDefaultCreatorRevision); + } + } + + + // + // By default, a table belongs in all ACPI table versions published. + // Some tables will override this because they have different versions of the table. + // + *Version = 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 = (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *) Table; + + FadtHeader->PreferredPmProfile = PcdGet8 (PcdFadtPreferredPmProfile); + FadtHeader->IaPcBootArch = PcdGet16 (PcdFadtIaPcBootArch); + FadtHeader->Flags = PcdGet32 (PcdFadtFlags); + + FadtHeader->AcpiEnable = PcdGet8 (PcdAcpiEnableSwSmi); + FadtHeader->AcpiDisable = PcdGet8 (PcdAcpiDisableSwSmi); + + FadtHeader->Pm1aEvtBlk = PcdGet16 (PcdAcpiPm1AEventBlockAddress); + FadtHeader->Pm1bEvtBlk = PcdGet16 (PcdAcpiPm1BEventBlockAddress); + FadtHeader->Pm1aCntBlk = PcdGet16 (PcdAcpiPm1AControlBlockAddress); + FadtHeader->Pm1bCntBlk = PcdGet16 (PcdAcpiPm1BControlBlockAddress); + FadtHeader->Pm2CntBlk = PcdGet16 (PcdAcpiPm2ControlBlockAddress); + FadtHeader->PmTmrBlk = PcdGet16 (PcdAcpiPmTimerBlockAddress); + FadtHeader->Gpe0Blk = PcdGet16 (PcdAcpiGpe0BlockAddress); + FadtHeader->Gpe1Blk = PcdGet16 (PcdAcpiGpe1BlockAddress); + + FadtHeader->XPm1aEvtBlk.Address = PcdGet16 (PcdAcpiPm1AEventBlockAddress); + FadtHeader->XPm1bEvtBlk.Address = PcdGet16 (PcdAcpiPm1BEventBlockAddress); + if (FadtHeader->XPm1bEvtBlk.Address == 0) { + FadtHeader->XPm1bEvtBlk.AccessSize = 0; + } + FadtHeader->XPm1aCntBlk.Address = PcdGet16 (PcdAcpiPm1AControlBlockAddress); + FadtHeader->XPm1bCntBlk.Address = PcdGet16 (PcdAcpiPm1BControlBlockAddress); + if (FadtHeader->XPm1bCntBlk.Address == 0) { + FadtHeader->XPm1bCntBlk.AccessSize = 0; + } + FadtHeader->XPm2CntBlk.Address = PcdGet16 (PcdAcpiPm2ControlBlockAddress); + //if (FadtHeader->XPm2CntBlk.Address == 0) { + FadtHeader->XPm2CntBlk.AccessSize = 0; + //} + FadtHeader->XPmTmrBlk.Address = PcdGet16 (PcdAcpiPmTimerBlockAddress); + FadtHeader->XGpe0Blk.Address = PcdGet16 (PcdAcpiGpe0BlockAddress); + FadtHeader->XGpe1Blk.Address = PcdGet16 (PcdAcpiGpe1BlockAddress); + if (FadtHeader->XGpe1Blk.Address == 0) { + FadtHeader->XGpe1Blk.AccessSize = 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 = (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *)Table; + HpetBaseAddress = PcdGet32 (PcdHpetBaseAddress); + HpetTable->BaseAddressLower32Bit.Address = HpetBaseAddress; + HpetTable->BaseAddressLower32Bit.RegisterBitWidth = 0; + HpetCapabilitiesData = MmioRead32 (HpetBaseAddress + HPET_GENERAL_CAPABILITIES_ID_OFFSET); + HpetCapabilities.Uint64 = HpetCapabilitiesData; + HpetCapabilitiesData = MmioRead32 (HpetBaseAddress + HPET_GENERAL_CAPABILITIES_ID_OFFSET + 4); + HpetCapabilities.Uint64 |= LShiftU64 (HpetCapabilitiesData, 32); + HpetBlockId.Bits.Revision = HpetCapabilities.Bits.Revision; + HpetBlockId.Bits.NumberOfTimers = HpetCapabilities.Bits.NumberOfTimers; + HpetBlockId.Bits.CounterSize = HpetCapabilities.Bits.CounterSize; + HpetBlockId.Bits.Reserved = 0; + HpetBlockId.Bits.LegacyRoute = HpetCapabilities.Bits.LegacyRoute; + HpetBlockId.Bits.VendorId = HpetCapabilities.Bits.VendorId; + HpetTable->EventTimerBlockId = HpetBlockId.Uint32; + HpetTable->MainCounterMinimumClockTickInPeriodicMode = (UINT16)HpetCapabilities.Bits.CounterClockPeriod; + DEBUG(( EFI_D_ERROR, "ACPI HPET table @ address 0x%x\n", Table )); + DEBUG(( EFI_D_ERROR, " HPET base 0x%x\n", PcdGet32 (PcdHpetBaseAddress) )); + break; + + case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE: + ASSERT(FALSE); + break; + + default: + break; + } + return EFI_SUCCESS; +} + +/** + This function calculates RCR based on PCI Device ID and Vendor ID from the devices + available on the platform. + It also includes other instances of BIOS change to calculate CRC and provides 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 = 0; + HandleBuffer = NULL; + + Status = 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 = HandleCount + 1; + HWChange = AllocateZeroPool( sizeof(UINT32) * HWChangeSize ); + ASSERT( HWChange != NULL ); + + if (HWChange == NULL) return; + + // + // add HWChange inputs: PCI devices + // + for (Index = 0; HandleCount > 0; HandleCount--) { + PciId = 0; + Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID **) &PciIo); + if (!EFI_ERROR (Status)) { + Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0, 1, &PciId); + if (EFI_ERROR (Status)) { + continue; + } + HWChange[Index++] = PciId; + } + } + + // + // Locate FACP Table + // + Handle = 0; + Status = LocateAcpiTableBySignature ( + EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, + (EFI_ACPI_DESCRIPTION_HEADER **) &pFADT, + &Handle + ); + if (EFI_ERROR (Status) || (pFADT == NULL)) { + return; //Table not found or out of memory resource for pFADT table + } + + // + // add HWChange inputs: others + // + HWChange[Index++] = (UINT32)pFADT->XDsdt; + + // + // Calculate CRC value with HWChange data. + // + Status = gBS->CalculateCrc32(HWChange, HWChangeSize, &CRC); + DEBUG((DEBUG_INFO, "CRC = %x and Status = %r\n", CRC, Status)); + + // + // Set HardwareSignature value based on CRC value. + // + FacsPtr = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)pFADT->FirmwareCtrl; + FacsPtr->HardwareSignature = 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 = 0; Index < sizeof(mLocalTable)/sizeof(mLocalTable[0]); Index++) { + CurrentTable = mLocalTable[Index]; + + PlatformUpdateTables (CurrentTable, &Version); + + TableHandle = 0; + + if (Version != EFI_ACPI_TABLE_VERSION_NONE) { + Status = mAcpiTable->InstallAcpiTable ( + mAcpiTable, + CurrentTable, + CurrentTable->Length, + &TableHandle + ); + ASSERT_EFI_ERROR (Status); + } + } +} + + +VOID +EFIAPI +AcpiEndOfDxeEvent ( + EFI_EVENT Event, + VOID *ParentImageHandle + ) +{ + + if (Event != NULL) { + gBS->CloseEvent(Event); + } + + + // + // Calculate Hardware Signature value based on current platform configurations + // + 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 = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&mMpService); + ASSERT_EFI_ERROR (Status); + + Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&mAcpiTable); + ASSERT_EFI_ERROR (Status); + + // + // Create an End of DXE event. + // + Status = 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 <= MAX_CPU_NUM && mNumberOfEnabledCPUs >= 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 &= 0x1F; + DEBUG ((DEBUG_INFO, "mNumOfBitShift - 0x%x\n", mNumOfBitShift)); + + UpdateLocalTable (); + + InstallMadtFromScratch (); + InstallMcfgFromScratch (); + + return EFI_SUCCESS; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Facs/Facs.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Facs/Facs.c new file mode 100644 index 0000000000..a16c13466a --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Facs/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 modified + for bug fixes, no porting is required. + + Copyright (c) 2017 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 = { + 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/Overrides/MinPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.c new file mode 100644 index 0000000000..8aa10a4a5b --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Fadt/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 modified + for bug fixes, no porting is required. + + Copyright (c) 2017 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 = { + { + 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/Overrides/MinPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.c new file mode 100644 index 0000000000..aa386ba149 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.c @@ -0,0 +1,78 @@ +/** @file + This file contains a structure definition for the ACPI 1.0 High Precision Event Timer + Description Table (HPET). The contents of this file should only be modified + for bug fixes, no porting is required. + + Copyright (c) 2017 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_MEMORY +#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 = { + { + 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/Overrides/MinPlatformPkg/Acpi/AcpiTables/Wsmt/Wsmt.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Wsmt/Wsmt.c new file mode 100644 index 0000000000..12e2feacb4 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Wsmt/Wsmt.c @@ -0,0 +1,46 @@ +/** @file + ACPI WSMT table + + Copyright (c) 2017 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 = { + { + 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/Overrides/OvmfPkg/QemuVideoDxe/ComponentName.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/ComponentName.c new file mode 100644 index 0000000000..dd9cc80e42 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/ComponentName.c @@ -0,0 +1,205 @@ +/** @file + Component name for the QEMU video controller. + + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "Qemu.h" + +// +// EFI Component Name Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gQemuVideoComponentName = { + QemuVideoComponentNameGetDriverName, + QemuVideoComponentNameGetControllerName, + "eng" +}; + +// +// EFI Component Name 2 Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gQemuVideoComponentName2 = { + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) QemuVideoComponentNameGetDriverName, + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) QemuVideoComponentNameGetControllerName, + "en" +}; + + +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mQemuVideoDriverNameTable[] = { + { "eng;en", L"QEMU Video Driver" }, + { NULL , NULL } +}; + +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mQemuVideoControllerNameTable[] = { + { "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 of 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 specified + 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_PROTOCOL 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 caller 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 format. + + @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 specified 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 support + 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 == &gQemuVideoComponentName) + ); +} + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified 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 specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + 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 returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL 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 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 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 caller 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 format. + + @param ControllerName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + controller specified by ControllerHandle and + ChildHandle in the language specified by + Language from the point of view of the driver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable name 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 valid + 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 currently + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +QemuVideoComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + EFI_STATUS Status; + + // + // This is a device driver, so ChildHandle must be NULL. + // + if (ChildHandle != NULL) { + return EFI_UNSUPPORTED; + } + + // + // Make sure this driver is currently managing ControllHandle + // + Status = 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 == &gQemuVideoComponentName) + ); +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Driver.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Driver.c new file mode 100644 index 0000000000..e49e7a465c --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Driver.c @@ -0,0 +1,1011 @@ +/** @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 +**/ + +#include "Qemu.h" +#include + +EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding = { + QemuVideoControllerDriverSupported, + QemuVideoControllerDriverStart, + QemuVideoControllerDriverStop, + 0x10, + NULL, + NULL +}; + +QEMU_VIDEO_CARD gQemuVideoCardList[] = { + { + 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 = 0; + + while (gQemuVideoCardList[Index].VendorId != 0) { + if (gQemuVideoCardList[Index].SubClass == SubClass && + gQemuVideoCardList[Index].VendorId == VendorId && + gQemuVideoCardList[Index].DeviceId == 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 = 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 = PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint32, + 0, + sizeof (Pci) / sizeof (UINT32), + &Pci + ); + if (EFI_ERROR (Status)) { + goto Done; + } + + Status = EFI_UNSUPPORTED; + if (!IS_PCI_DISPLAY (&Pci)) { + goto Done; + } + Card = QemuVideoDetect(Pci.Hdr.ClassCode[1], Pci.Hdr.VendorId, Pci.Hdr.DeviceId); + if (Card != NULL) { + DEBUG ((EFI_D_INFO, "QemuVideo: %s detected\n", Card->Name)); + Status = 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 bus. + @retval EFI_ALREADY_STARTED The controller is already controlled by the 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 = gBS->RaiseTPL (TPL_CALLBACK); + + // + // Allocate Private context data for GOP inteface. + // + Private = AllocateZeroPool (sizeof (QEMU_VIDEO_PRIVATE_DATA)); + if (Private == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto RestoreTpl; + } + + // + // Set up context record + // + Private->Signature = QEMU_VIDEO_PRIVATE_DATA_SIGNATURE; + + // + // Open PCI I/O Protocol + // + Status = 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 = Private->PciIo->Pci.Read ( + Private->PciIo, + EfiPciIoWidthUint32, + 0, + sizeof (Pci) / sizeof (UINT32), + &Pci + ); + if (EFI_ERROR (Status)) { + goto ClosePciIo; + } + + // + // Determine card variant. + // + Card = QemuVideoDetect(Pci.Hdr.ClassCode[1], Pci.Hdr.VendorId, Pci.Hdr.DeviceId); + if (Card == NULL) { + Status = EFI_DEVICE_ERROR; + goto ClosePciIo; + } + Private->Variant = Card->Variant; + + // + // IsQxl is based on the detected Card->Variant, which at a later point might + // not match Private->Variant. + // + IsQxl = (BOOLEAN)(Card->Variant == QEMU_VIDEO_BOCHS); + + // + // Save original PCI attributes + // + Status = Private->PciIo->Attributes ( + Private->PciIo, + EfiPciIoAttributeOperationGet, + 0, + &Private->OriginalPciAttributes + ); + + if (EFI_ERROR (Status)) { + goto ClosePciIo; + } + + // + // Set new PCI attributes + // + Status = Private->PciIo->Attributes ( + Private->PciIo, + EfiPciIoAttributeOperationEnable, + EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_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 == QEMU_VIDEO_BOCHS_MMIO) { + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *MmioDesc; + + Status = Private->PciIo->GetBarAttributes ( + Private->PciIo, + PCI_BAR_IDX2, + NULL, + (VOID**) &MmioDesc + ); + if (EFI_ERROR (Status) || + MmioDesc->ResType != ACPI_ADDRESS_SPACE_TYPE_MEM) { + DEBUG ((EFI_D_INFO, "QemuVideo: No mmio bar, fallback to port io\n")); + Private->Variant = 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 == QEMU_VIDEO_BOCHS_MMIO || + Private->Variant == QEMU_VIDEO_BOCHS) { + UINT16 BochsId; + BochsId = BochsRead(Private, VBE_DISPI_INDEX_ID); + if ((BochsId & 0xFFF0) != VBE_DISPI_ID0) { + DEBUG ((EFI_D_INFO, "QemuVideo: BochsID mismatch (got 0x%x)\n", BochsId)); + Status = EFI_DEVICE_ERROR; + goto RestoreAttributes; + } + } + + // + // Get ParentDevicePath + // + Status = 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 = ACPI_DEVICE_PATH; + AcpiDeviceNode.Header.SubType = ACPI_ADR_DP; + AcpiDeviceNode.ADR = 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 = AppendDevicePathNode ( + ParentDevicePath, + (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode + ); + if (Private->GopDevicePath == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto RestoreAttributes; + } + + // + // Create new child handle and install the device path protocol on it. + // + Status = 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 = QemuVideoCirrusModeSetup (Private); + break; + case QEMU_VIDEO_BOCHS_MMIO: + case QEMU_VIDEO_BOCHS: + Status = QemuVideoBochsModeSetup (Private, IsQxl); + break; + default: + ASSERT (FALSE); + Status = EFI_DEVICE_ERROR; + break; + } + if (EFI_ERROR (Status)) { + goto UninstallGopDevicePath; + } + + // + // Start the GOP software stack. + // + Status = QemuVideoGraphicsOutputConstructor (Private); + if (EFI_ERROR (Status)) { + goto FreeModeData; + } + + Status = gBS->InstallMultipleProtocolInterfaces ( + &Private->Handle, + &gEfiGraphicsOutputProtocolGuid, + &Private->GraphicsOutput, + NULL + ); + if (EFI_ERROR (Status)) { + goto DestructQemuVideoGraphics; + } + + // + // Reference parent handle from child handle. + // + Status = 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 == QEMU_VIDEO_BOCHS_MMIO || + Private->Variant == QEMU_VIDEO_BOCHS) { + InstallVbeShim (Card->Name, Private->GraphicsOutput.Mode->FrameBufferBase); + } +#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, EfiPciIoAttributeOperationSet, + 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 == 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 == 1); + Status = 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 = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput); + ASSERT (Private->Handle == ChildHandleBuffer[0]); + + QemuVideoGraphicsOutputDestructor (Private); + // + // Remove the GOP protocol interface from the system + // + Status = 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 = gBS->LocateProtocol(&gEfiDxeSmmReadyToLockProtocolGuid, NULL, &Interface); + if (!EFI_ERROR(Status)) { + return; + } + + Status = 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 = gBS->LocateProtocol(&gEfiDxeSmmReadyToLockProtocolGuid, NULL, &Interface); + if (!EFI_ERROR(Status)) { + return; + } + Status = 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 = 0; + for (RedIndex = 0; RedIndex < 8; RedIndex++) { + for (GreenIndex = 0; GreenIndex < 8; GreenIndex++) { + for (BlueIndex = 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 = 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 = 0; Index < 15; Index++) { + outw (Private, SEQ_ADDRESS_REGISTER, ModeData->SeqSettings[Index]); + } + + if (Private->Variant == QEMU_VIDEO_CIRRUS_5430) { + outb (Private, SEQ_ADDRESS_REGISTER, 0x0f); + Byte = (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 = 0; Index < 28; Index++) { + outw (Private, CRTC_ADDRESS_REGISTER, (UINT16) ((ModeData->CrtcSettings[Index] << 8) | Index)); + } + + for (Index = 0; Index < 9; Index++) { + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((GraphicsController[Index] << 8) | Index)); + } + + inb (Private, INPUT_STATUS_1_REGISTER); + + for (Index = 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 == QEMU_VIDEO_BOCHS_MMIO) { + Status = 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 == QEMU_VIDEO_BOCHS_MMIO) { + Status = 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 = 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 == QEMU_VIDEO_BOCHS_MMIO) { + Status = 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->ColorDepth); + BochsWrite (Private, VBE_DISPI_INDEX_XRES, (UINT16) ModeData->Width); + BochsWrite (Private, VBE_DISPI_INDEX_VIRT_WIDTH, (UINT16) ModeData->Width); + BochsWrite (Private, VBE_DISPI_INDEX_YRES, (UINT16) ModeData->Height); + BochsWrite (Private, VBE_DISPI_INDEX_VIRT_HEIGHT, (UINT16) ModeData->Height); + + 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 = 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 = PcdGet32 (PcdDriverSupportedEfiVersion); + Status = gBS->InstallMultipleProtocolInterfaces ( + &ImageHandle, + &gEfiDriverSupportedEfiVersionProtocolGuid, + &gQemuVideoDriverSupportedEfiVersion, + NULL + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/DriverSupportedEfiVersion.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/DriverSupportedEfiVersion.c new file mode 100644 index 0000000000..c2d82e7324 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/DriverSupportedEfiVersion.c @@ -0,0 +1,15 @@ +/** @file + Driver supported version protocol for the QEMU video driver. + + Copyright (c) 2007 - 2010 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "Qemu.h" + +EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL gQemuVideoDriverSupportedEfiVersion = { + 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/Overrides/OvmfPkg/QemuVideoDxe/Gop.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Gop.c new file mode 100644 index 0000000000..19ff5209d2 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Gop.c @@ -0,0 +1,417 @@ +/** @file + Graphics Output Protocol functions for the QEMU video controller. + + Copyright (c) 2007 - 2018 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "Qemu.h" + +STATIC +VOID +QemuVideoCompleteModeInfo ( + IN QEMU_VIDEO_MODE_DATA *ModeData, + OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info + ) +{ + Info->Version = 0; + if (ModeData->ColorDepth == 8) { + Info->PixelFormat = PixelBitMask; + Info->PixelInformation.RedMask = PIXEL_RED_MASK; + Info->PixelInformation.GreenMask = PIXEL_GREEN_MASK; + Info->PixelInformation.BlueMask = PIXEL_BLUE_MASK; + Info->PixelInformation.ReservedMask = 0; + } else if (ModeData->ColorDepth == 24) { + Info->PixelFormat = PixelBitMask; + Info->PixelInformation.RedMask = PIXEL24_RED_MASK; + Info->PixelInformation.GreenMask = PIXEL24_GREEN_MASK; + Info->PixelInformation.BlueMask = PIXEL24_BLUE_MASK; + Info->PixelInformation.ReservedMask = 0; + } else if (ModeData->ColorDepth == 32) { + DEBUG ((EFI_D_INFO, "PixelBlueGreenRedReserved8BitPerColor\n")); + Info->PixelFormat = PixelBlueGreenRedReserved8BitPerColor; + } + Info->PixelsPerScanLine = 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 = &Private->ModeData[Mode->Mode]; + Info = Mode->Info; + QemuVideoCompleteModeInfo (ModeData, Info); + + Private->PciIo->GetBarAttributes ( + Private->PciIo, + 0, + NULL, + (VOID**) &FrameBufDesc + ); + + Mode->FrameBufferBase = FrameBufDesc->AddrRangeMin; + Mode->FrameBufferSize = Info->HorizontalResolution * Info->VerticalResolution; + Mode->FrameBufferSize = Mode->FrameBufferSize * ((ModeData->ColorDepth + 7) / 8); + Mode->FrameBufferSize = 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 information about ModeNumber. + SizeOfInfo - A pointer to the size, in bytes, of the Info buffer. + + 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 the 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 = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This); + + if (Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) { + return EFI_INVALID_PARAMETER; + } + + *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION)); + if (*Info == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); + + ModeData = &Private->ModeData[ModeNumber]; + (*Info)->HorizontalResolution = ModeData->HorizontalResolution; + (*Info)->VerticalResolution = 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 = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This); + + if (ModeNumber >= This->Mode->MaxMode) { + return EFI_UNSUPPORTED; + } + + ModeData = &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->InternalModeIndex]); + break; + default: + ASSERT (FALSE); + return EFI_DEVICE_ERROR; + } + + This->Mode->Mode = ModeNumber; + This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution; + This->Mode->Info->VerticalResolution = ModeData->VerticalResolution; + This->Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); + + QemuVideoCompleteModeData (Private, This->Mode); + + // + // Re-initialize the frame buffer configure when mode changes. + // + Status = FrameBufferBltConfigure ( + (VOID*) (UINTN) This->Mode->FrameBufferBase, + This->Mode->Info, + Private->FrameBufferBltConfigure, + &Private->FrameBufferBltConfigureSize + ); + if (Status == RETURN_BUFFER_TOO_SMALL) { + // + // Frame buffer configure may be larger in new mode. + // + if (Private->FrameBufferBltConfigure != NULL) { + FreePool (Private->FrameBufferBltConfigure); + } + Private->FrameBufferBltConfigure = + AllocatePool (Private->FrameBufferBltConfigureSize); + ASSERT (Private->FrameBufferBltConfigure != NULL); + + // + // Create the configuration for FrameBufferBltLib + // + Status = FrameBufferBltConfigure ( + (VOID*) (UINTN) This->Mode->FrameBufferBase, + This->Mode->Info, + Private->FrameBufferBltConfigure, + &Private->FrameBufferBltConfigureSize + ); + } + ASSERT (Status == RETURN_SUCCESS); + + // + // Per UEFI Spec, need to clear the visible portions of the output display to black. + // + ZeroMem (&Black, sizeof (Black)); + Status = FrameBufferBlt ( + Private->FrameBufferBltConfigure, + &Black, + EfiBltVideoFill, + 0, 0, + 0, 0, + This->Mode->Info->HorizontalResolution, This->Mode->Info->VerticalResolution, + 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 device + +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 operation. + If a Delta of 0 is used, the entire BltBuffer will be operated on. + If a subrectangle of the BltBuffer is used, then Delta represents + 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 = 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 = gBS->RaiseTPL (TPL_NOTIFY); + + switch (BltOperation) { + case EfiBltVideoToBltBuffer: + case EfiBltBufferToVideo: + case EfiBltVideoFill: + case EfiBltVideoToVideo: + Status = FrameBufferBlt ( + Private->FrameBufferBltConfigure, + BltBuffer, + BltOperation, + SourceX, + SourceY, + DestinationX, + DestinationY, + Width, + Height, + Delta + ); + break; + + default: + Status = 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 = &Private->GraphicsOutput; + GraphicsOutput->QueryMode = QemuVideoGraphicsOutputQueryMode; + GraphicsOutput->SetMode = QemuVideoGraphicsOutputSetMode; + GraphicsOutput->Blt = QemuVideoGraphicsOutputBlt; + + // + // Initialize the private data + // + Status = gBS->AllocatePool ( + EfiBootServicesData, + sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE), + (VOID **) &Private->GraphicsOutput.Mode + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->AllocatePool ( + EfiBootServicesData, + sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), + (VOID **) &Private->GraphicsOutput.Mode->Info + ); + if (EFI_ERROR (Status)) { + goto FreeMode; + } + Private->GraphicsOutput.Mode->MaxMode = (UINT32) Private->MaxMode; + Private->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER; + Private->FrameBufferBltConfigure = NULL; + Private->FrameBufferBltConfigureSize = 0; + + // + // Initialize the hardware + // + Status = GraphicsOutput->SetMode (GraphicsOutput, 0); + if (EFI_ERROR (Status)) { + goto FreeInfo; + } + + DrawLogo ( + Private, + Private->ModeData[Private->GraphicsOutput.Mode->Mode].HorizontalResolution, + Private->ModeData[Private->GraphicsOutput.Mode->Mode].VerticalResolution + ); + + return EFI_SUCCESS; + +FreeInfo: + FreePool (Private->GraphicsOutput.Mode->Info); + +FreeMode: + FreePool (Private->GraphicsOutput.Mode); + Private->GraphicsOutput.Mode = NULL; + + return Status; +} + +EFI_STATUS +QemuVideoGraphicsOutputDestructor ( + QEMU_VIDEO_PRIVATE_DATA *Private + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +{ + if (Private->FrameBufferBltConfigure != NULL) { + FreePool (Private->FrameBufferBltConfigure); + } + + if (Private->GraphicsOutput.Mode != NULL) { + if (Private->GraphicsOutput.Mode->Info != NULL) { + gBS->FreePool (Private->GraphicsOutput.Mode->Info); + } + gBS->FreePool (Private->GraphicsOutput.Mode); + } + + return EFI_SUCCESS; +} + + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Initialize.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Initialize.c new file mode 100644 index 0000000000..fbf40e9eaf --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Initialize.c @@ -0,0 +1,341 @@ +/** @file + Graphics Output Protocol functions for the QEMU video controller. + + Copyright (c) 2007 - 2010 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "Qemu.h" + + +/// +/// Generic Attribute Controller Register Settings +/// +UINT8 AttributeController[21] = { + 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] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF +}; + +// +// 640 x 480 x 256 color @ 60 Hertz +// +UINT8 Crtc_640_480_256_60[28] = { + 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] = { + 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] = { + 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, + 0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e +}; + +UINT16 Seq_640_480_32bpp_60[15] = { + 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] = { + 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] = { + 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] = { + 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, + 0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e +}; + +UINT16 Seq_800_600_32bpp_60[15] = { + 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b, + 0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e +}; + +UINT8 Crtc_960_720_32bpp_60[28] = { + 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] = { + 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] = { + 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] = { + 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] = { + 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] = { + 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1507, 0x0008, 0x4a0b, + 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e +}; + +UINT8 Crtc_1024_768_32bpp_60[28] = { + 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] = { + 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[] = { +// { 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 = AllocatePool ( + sizeof (Private->ModeData[0]) * QEMU_VIDEO_CIRRUS_MODE_COUNT + ); + if (Private->ModeData == NULL) { + return EFI_OUT_OF_RESOURCES; + } + ModeData = Private->ModeData; + VideoMode = &QemuVideoCirrusModes[0]; + for (Index = 0; Index < QEMU_VIDEO_CIRRUS_MODE_COUNT; Index ++) { + ModeData->InternalModeIndex = Index; + ModeData->HorizontalResolution = VideoMode->Width; + ModeData->VerticalResolution = VideoMode->Height; + ModeData->ColorDepth = 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 = ModeData - Private->ModeData; + + return EFI_SUCCESS; +} + +/// +/// Table of supported video modes +/// +QEMU_VIDEO_BOCHS_MODES QemuVideoBochsModes[] = { + { 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 = 0; + DrawStart = 0xFFFFFFFF; + AvailableFbSize = 0; + if (EFI_ERROR ( + Private->PciIo->Mem.Read (Private->PciIo, EfiPciIoWidthUint32, + PCI_BAR_IDX2, 0, 1, &Signature)) || + Signature != SIGNATURE_32 ('Q', 'X', 'R', 'O') || + EFI_ERROR ( + Private->PciIo->Mem.Read (Private->PciIo, EfiPciIoWidthUint32, + PCI_BAR_IDX2, 36, 1, &DrawStart)) || + DrawStart != 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 QXL " + "ROM\n", __FUNCTION__)); + return EFI_NOT_FOUND; + } + } else { + AvailableFbSize = BochsRead (Private, VBE_DISPI_INDEX_VIDEO_MEMORY_64K); + AvailableFbSize *= SIZE_64KB; + } + DEBUG ((EFI_D_INFO, "%a: AvailableFbSize=0x%x\n", __FUNCTION__, + AvailableFbSize)); + + // + // Setup Video Modes + // + Private->ModeData = AllocatePool ( + sizeof (Private->ModeData[0]) * QEMU_VIDEO_BOCHS_MODE_COUNT + ); + if (Private->ModeData == NULL) { + return EFI_OUT_OF_RESOURCES; + } + ModeData = Private->ModeData; + VideoMode = &QemuVideoBochsModes[0]; + for (Index = 0; Index < QEMU_VIDEO_BOCHS_MODE_COUNT; Index ++) { + UINTN RequiredFbSize; + + ASSERT (VideoMode->ColorDepth % 8 == 0); + RequiredFbSize = (UINTN) VideoMode->Width * VideoMode->Height * + (VideoMode->ColorDepth / 8); + if (RequiredFbSize <= AvailableFbSize) { + ModeData->InternalModeIndex = Index; + ModeData->HorizontalResolution = VideoMode->Width; + ModeData->VerticalResolution = VideoMode->Height; + ModeData->ColorDepth = 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 = ModeData - Private->ModeData; + + return EFI_SUCCESS; +} + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c new file mode 100644 index 0000000000..aa4648f813 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/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 "Qemu.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 Resolution, +// Advanced Settings dialog. It should be short. +// +STATIC CONST CHAR8 mProductRevision[] = "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 vector + 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 card'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)) == 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 = 0x00000; + SegmentC = 0xC0000; + SegmentF = 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 overwrite + // the IVT used in real mode. + // + // The allocation request may fail, eg. if LegacyBiosDxe has already run. + // + Segment0Pages = 1; + Int0x10 = (IVT_ENTRY *)(UINTN)Segment0 + 0x10; + Segment0AllocationStatus = 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 shim if + // it's already present. + // + Handler = (Int0x10->Segment << 4) + Int0x10->Offset; + if (Handler >= 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 == 0x0000); + ASSERT (Int0x10->Offset == 0x0000); + } + + HostBridgeDevId = 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 = 4; + + ASSERT (sizeof mVbeShim <= EFI_PAGES_TO_SIZE (SegmentCPages)); + CopyMem ((VOID *)(UINTN)SegmentC, mVbeShim, sizeof mVbeShim); + + // + // Fill in the VBE INFO structure. + // + VbeInfoFull = (VBE_INFO *)(UINTN)SegmentC; + VbeInfo = &VbeInfoFull->Base; + Ptr = VbeInfoFull->Buffer; + + CopyMem (VbeInfo->Signature, "VESA", 4); + VbeInfo->VesaVersion = 0x0300; + + VbeInfo->OemNameAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr; + CopyMem (Ptr, "QEMU", 5); + Ptr += 5; + + VbeInfo->Capabilities = BIT0; // DAC can be switched into 8-bit mode + + VbeInfo->ModeListAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr; + *(UINT16*)Ptr = 0x00f1; // mode number + Ptr += 2; + *(UINT16*)Ptr = 0xFFFF; // mode list terminator + Ptr += 2; + + VbeInfo->VideoMem64K = (UINT16)((1024 * 768 * 4 + 65535) / 65536); + VbeInfo->OemSoftwareVersion = 0x0000; + + VbeInfo->VendorNameAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr; + CopyMem (Ptr, "OVMF", 5); + Ptr += 5; + + VbeInfo->ProductNameAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr; + Printed = AsciiSPrint ((CHAR8 *)Ptr, + sizeof VbeInfoFull->Buffer - (Ptr - VbeInfoFull->Buffer), "%s", + CardName); + Ptr += Printed + 1; + + VbeInfo->ProductRevAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr; + CopyMem (Ptr, mProductRevision, sizeof mProductRevision); + Ptr += sizeof mProductRevision; + + ASSERT (sizeof VbeInfoFull->Buffer >= Ptr - VbeInfoFull->Buffer); + ZeroMem (Ptr, sizeof VbeInfoFull->Buffer - (Ptr - VbeInfoFull->Buffer)); + + // + // Fil in the VBE MODE INFO structure. + // + VbeModeInfo = (VBE_MODE_INFO *)(VbeInfoFull + 1); + + // + // bit0: mode supported by present hardware configuration + // bit1: optional information available (must be =1 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 = BIT7 | BIT5 | BIT4 | BIT3 | BIT1 | BIT0; + + // + // bit0: exists + // bit1: bit1: readable + // bit2: writeable + // + VbeModeInfo->WindowAAttr = BIT2 | BIT1 | BIT0; + + VbeModeInfo->WindowBAttr = 0x00; + VbeModeInfo->WindowGranularityKB = 0x0040; + VbeModeInfo->WindowSizeKB = 0x0040; + VbeModeInfo->WindowAStartSegment = 0xA000; + VbeModeInfo->WindowBStartSegment = 0x0000; + VbeModeInfo->WindowPositioningAddress = 0x0000; + VbeModeInfo->BytesPerScanLine = 1024 * 4; + + VbeModeInfo->Width = 1024; + VbeModeInfo->Height = 768; + VbeModeInfo->CharCellWidth = 8; + VbeModeInfo->CharCellHeight = 16; + VbeModeInfo->NumPlanes = 1; + VbeModeInfo->BitsPerPixel = 32; + VbeModeInfo->NumBanks = 1; + VbeModeInfo->MemoryModel = 6; // direct color + VbeModeInfo->BankSizeKB = 0; + VbeModeInfo->NumImagePagesLessOne = 0; + VbeModeInfo->Vbe3 = 0x01; + + VbeModeInfo->RedMaskSize = 8; + VbeModeInfo->RedMaskPos = 16; + VbeModeInfo->GreenMaskSize = 8; + VbeModeInfo->GreenMaskPos = 8; + VbeModeInfo->BlueMaskSize = 8; + VbeModeInfo->BlueMaskPos = 0; + VbeModeInfo->ReservedMaskSize = 8; + VbeModeInfo->ReservedMaskPos = 24; + + // + // bit1: Bytes in reserved field may be used by application + // + VbeModeInfo->DirectColorModeInfo = BIT1; + + VbeModeInfo->LfbAddress = (UINT32)FrameBufferBase; + VbeModeInfo->OffScreenAddress = 0; + VbeModeInfo->OffScreenSizeKB = 0; + + VbeModeInfo->BytesPerScanLineLinear = 1024 * 4; + VbeModeInfo->NumImagesLessOneBanked = 0; + VbeModeInfo->NumImagesLessOneLinear = 0; + VbeModeInfo->RedMaskSizeLinear = 8; + VbeModeInfo->RedMaskPosLinear = 16; + VbeModeInfo->GreenMaskSizeLinear = 8; + VbeModeInfo->GreenMaskPosLinear = 8; + VbeModeInfo->BlueMaskSizeLinear = 8; + VbeModeInfo->BlueMaskPosLinear = 0; + VbeModeInfo->ReservedMaskSizeLinear = 8; + VbeModeInfo->ReservedMaskPosLinear = 24; + VbeModeInfo->MaxPixelClockHz = 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 = (UINT16) ((UINT32)SegmentC >> 4); + Int0x10->Offset = (UINT16) ((UINTN) (VbeModeInfo + 1) - SegmentC); + + DEBUG ((EFI_D_INFO, "%a: VBE shim installed\n", __FUNCTION__)); +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c new file mode 100644 index 0000000000..b57bacdda4 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c @@ -0,0 +1,622 @@ +/** @file + This contains the installation function for the driver. + + Copyright (c) 2005 - 2018 Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "8259.h" + +// +// Global for the Legacy 8259 Protocol that is produced by this driver +// +EFI_LEGACY_8259_PROTOCOL mInterrupt8259 = { + Interrupt8259SetVectorBase, + Interrupt8259GetMask, + Interrupt8259SetMask, + Interrupt8259SetMode, + Interrupt8259GetVector, + Interrupt8259EnableIrq, + Interrupt8259DisableIrq, + Interrupt8259GetInterruptLine, + Interrupt8259EndOfInterrupt +}; + +// +// Global for the handle that the Legacy 8259 Protocol is installed +// +EFI_HANDLE m8259Handle = NULL; + +UINT8 mMasterBase = 0xff; +UINT8 mSlaveBase = 0xff; +EFI_8259_MODE mMode = Efi8259ProtectedMode; +UINT16 mProtectedModeMask = 0xffff; +UINT16 mLegacyModeMask; +UINT16 mProtectedModeEdgeLevel = 0x0000; +UINT16 mLegacyModeEdgeLevel; + +// +// Worker Functions +// + +/** + Write to mask and edge/level triggered registers of master and slave 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 register, + 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) EdgeLevel); + IoWrite8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE, (UINT8) (EdgeLevel >> 8)); +} + +/** + Read from mask and edge/level triggered registers of master and slave PICs. + + @param[out] Mask low byte for master PIC mask register, + high byte for slave PIC mask register. + @param[out] EdgeLevel low byte for master PIC edge/level triggered register, + high byte for slave PIC edge/level triggered register. + +**/ +VOID +Interrupt8259ReadMask ( + OUT UINT16 *Mask, + OUT UINT16 *EdgeLevel + ) +{ + UINT16 MasterValue; + UINT16 SlaveValue; + + if (Mask != NULL) { + MasterValue = IoRead8 (LEGACY_8259_MASK_REGISTER_MASTER); + SlaveValue = IoRead8 (LEGACY_8259_MASK_REGISTER_SLAVE); + + *Mask = (UINT16) (MasterValue | (SlaveValue << 8)); + } + + if (EdgeLevel != NULL) { + MasterValue = IoRead8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER); + SlaveValue = IoRead8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE); + + *EdgeLevel = (UINT16) (MasterValue | (SlaveValue << 8)); + } +} + +// +// Legacy 8259 Protocol Interface Functions +// + +/** + Sets the base address for the 8259 master and slave PICs. + + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance. + @param[in] MasterBase Interrupt vectors for IRQ0-IRQ7. + @param[in] SlaveBase Interrupt vectors for IRQ8-IRQ15. + + @retval EFI_SUCCESS The 8259 PIC was programmed successfully. + @retval EFI_DEVICE_ERROR There was an error while writing to the 8259 PIC. + +**/ +EFI_STATUS +EFIAPI +Interrupt8259SetVectorBase ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN UINT8 MasterBase, + IN UINT8 SlaveBase + ) +{ + UINT8 Mask; + EFI_TPL OriginalTpl; + + OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); + // + // Set vector base for slave PIC + // + if (SlaveBase != mSlaveBase) { + mSlaveBase = SlaveBase; + + // + // Initialization sequence is needed for setting vector base. + // + + // + // Preserve interrtup mask register before initialization sequence + // because it will be cleared during initialization + // + Mask = IoRead8 (LEGACY_8259_MASK_REGISTER_SLAVE); + + // + // ICW1: cascade mode, ICW4 write required + // + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, 0x11); + + // + // ICW2: new vector base (must be multiple of 8) + // + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, mSlaveBase); + + // + // ICW3: slave indentification code must be 2 + // + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0x02); + + // + // ICW4: fully nested mode, non-buffered mode, normal EOI, IA processor + // + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0x01); + + // + // Restore interrupt mask register + // + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, Mask); + } + + // + // Set vector base for master PIC + // + if (MasterBase != mMasterBase) { + mMasterBase = MasterBase; + + // + // Initialization sequence is needed for setting vector base. + // + + // + // Preserve interrtup mask register before initialization sequence + // because it will be cleared during initialization + // + Mask = IoRead8 (LEGACY_8259_MASK_REGISTER_MASTER); + + // + // ICW1: cascade mode, ICW4 write required + // + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, 0x11); + + // + // ICW2: new vector base (must be multiple of 8) + // + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, mMasterBase); + + // + // ICW3: slave PIC is cascaded on IRQ2 + // + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0x04); + + // + // ICW4: fully nested mode, non-buffered mode, normal EOI, IA processor + // + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0x01); + + // + // Restore interrupt mask register + // + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, Mask); + } + + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, LEGACY_8259_EOI); + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, LEGACY_8259_EOI); + + gBS->RestoreTPL (OriginalTpl); + + return EFI_SUCCESS; +} + +/** + Gets the current 16-bit real mode and 32-bit protected-mode IRQ masks. + + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance. + @param[out] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15. + @param[out] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15. + @param[out] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15. + @param[out] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-IRQ15. + + @retval EFI_SUCCESS The 8259 PIC was programmed successfully. + @retval EFI_DEVICE_ERROR There was an error while reading the 8259 PIC. + +**/ +EFI_STATUS +EFIAPI +Interrupt8259GetMask ( + IN EFI_LEGACY_8259_PROTOCOL *This, + OUT UINT16 *LegacyMask, OPTIONAL + OUT UINT16 *LegacyEdgeLevel, OPTIONAL + OUT UINT16 *ProtectedMask, OPTIONAL + OUT UINT16 *ProtectedEdgeLevel OPTIONAL + ) +{ + if (LegacyMask != NULL) { + *LegacyMask = mLegacyModeMask; + } + + if (LegacyEdgeLevel != NULL) { + *LegacyEdgeLevel = mLegacyModeEdgeLevel; + } + + if (ProtectedMask != NULL) { + *ProtectedMask = mProtectedModeMask; + } + + if (ProtectedEdgeLevel != NULL) { + *ProtectedEdgeLevel = mProtectedModeEdgeLevel; + } + + return EFI_SUCCESS; +} + +/** + Sets the current 16-bit real mode and 32-bit protected-mode IRQ masks. + + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance. + @param[in] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15. + @param[in] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15. + @param[in] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15. + @param[in] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-IRQ15. + + @retval EFI_SUCCESS The 8259 PIC was programmed successfully. + @retval EFI_DEVICE_ERROR There was an error while writing the 8259 PIC. + +**/ +EFI_STATUS +EFIAPI +Interrupt8259SetMask ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN UINT16 *LegacyMask, OPTIONAL + IN UINT16 *LegacyEdgeLevel, OPTIONAL + IN UINT16 *ProtectedMask, OPTIONAL + IN UINT16 *ProtectedEdgeLevel OPTIONAL + ) +{ + if (LegacyMask != NULL) { + mLegacyModeMask = *LegacyMask; + } + + if (LegacyEdgeLevel != NULL) { + mLegacyModeEdgeLevel = *LegacyEdgeLevel; + } + + if (ProtectedMask != NULL) { + mProtectedModeMask = *ProtectedMask; + } + + if (ProtectedEdgeLevel != NULL) { + mProtectedModeEdgeLevel = *ProtectedEdgeLevel; + } + + return EFI_SUCCESS; +} + +/** + Sets the mode of the PICs. + + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance. + @param[in] Mode 16-bit real or 32-bit protected mode. + @param[in] Mask The value with which to set the interrupt mask. + @param[in] EdgeLevel The value with which to set the edge/level mask. + + @retval EFI_SUCCESS The mode was set successfully. + @retval EFI_INVALID_PARAMETER The mode was not set. + +**/ +EFI_STATUS +EFIAPI +Interrupt8259SetMode ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_8259_MODE Mode, + IN UINT16 *Mask, OPTIONAL + IN UINT16 *EdgeLevel OPTIONAL + ) +{ + if (Mode == mMode) { + return EFI_SUCCESS; + } + + if (Mode == Efi8259LegacyMode) { + // + // In Efi8259ProtectedMode, mask and edge/level trigger registers should + // be changed through this protocol, so we can track them in the + // corresponding module variables. + // + Interrupt8259ReadMask (&mProtectedModeMask, &mProtectedModeEdgeLevel); + + if (Mask != NULL) { + // + // Update the Mask for the new mode + // + mLegacyModeMask = *Mask; + } + + if (EdgeLevel != NULL) { + // + // Update the Edge/Level triggered mask for the new mode + // + mLegacyModeEdgeLevel = *EdgeLevel; + } + + mMode = Mode; + + // + // Write new legacy mode mask/trigger level + // + Interrupt8259WriteMask (mLegacyModeMask, mLegacyModeEdgeLevel); + + return EFI_SUCCESS; + } + + if (Mode == Efi8259ProtectedMode) { + // + // Save the legacy mode mask/trigger level + // + Interrupt8259ReadMask (&mLegacyModeMask, &mLegacyModeEdgeLevel); + // + // Always force Timer to be enabled after return from 16-bit code. + // This always insures that on next entry, timer is counting. + // + mLegacyModeMask &= 0xFFFE; + + if (Mask != NULL) { + // + // Update the Mask for the new mode + // + mProtectedModeMask = *Mask; + } + + if (EdgeLevel != NULL) { + // + // Update the Edge/Level triggered mask for the new mode + // + mProtectedModeEdgeLevel = *EdgeLevel; + } + + mMode = Mode; + + // + // Write new protected mode mask/trigger level + // + Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel); + + return EFI_SUCCESS; + } + + return EFI_INVALID_PARAMETER; +} + +/** + Translates the IRQ into a vector. + + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance. + @param[in] Irq IRQ0-IRQ15. + @param[out] Vector The vector that is assigned to the IRQ. + + @retval EFI_SUCCESS The Vector that matches Irq was returned. + @retval EFI_INVALID_PARAMETER Irq is not valid. + +**/ +EFI_STATUS +EFIAPI +Interrupt8259GetVector ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_8259_IRQ Irq, + OUT UINT8 *Vector + ) +{ + if ((UINT32)Irq > Efi8259Irq15) { + return EFI_INVALID_PARAMETER; + } + + if (Irq <= Efi8259Irq7) { + *Vector = (UINT8) (mMasterBase + Irq); + } else { + *Vector = (UINT8) (mSlaveBase + (Irq - Efi8259Irq8)); + } + + return EFI_SUCCESS; +} + +/** + Enables the specified IRQ. + + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance. + @param[in] Irq IRQ0-IRQ15. + @param[in] LevelTriggered 0 = Edge triggered; 1 = Level triggered. + + @retval EFI_SUCCESS The Irq was enabled on the 8259 PIC. + @retval EFI_INVALID_PARAMETER The Irq is not valid. + +**/ +EFI_STATUS +EFIAPI +Interrupt8259EnableIrq ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_8259_IRQ Irq, + IN BOOLEAN LevelTriggered + ) +{ + if ((UINT32)Irq > Efi8259Irq15) { + return EFI_INVALID_PARAMETER; + } + + mProtectedModeMask = (UINT16) (mProtectedModeMask & ~(1 << Irq)); + if (LevelTriggered) { + mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel | (1 << Irq)); + } else { + mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel & ~(1 << Irq)); + } + + Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel); + + return EFI_SUCCESS; +} + +/** + Disables the specified IRQ. + + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance. + @param[in] Irq IRQ0-IRQ15. + + @retval EFI_SUCCESS The Irq was disabled on the 8259 PIC. + @retval EFI_INVALID_PARAMETER The Irq is not valid. + +**/ +EFI_STATUS +EFIAPI +Interrupt8259DisableIrq ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_8259_IRQ Irq + ) +{ + if ((UINT32)Irq > Efi8259Irq15) { + return EFI_INVALID_PARAMETER; + } + + mProtectedModeMask = (UINT16) (mProtectedModeMask | (1 << Irq)); + + mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel & ~(1 << Irq)); + + Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel); + + return EFI_SUCCESS; +} + +/** + Reads the PCI configuration space to get the interrupt number that is assigned to the card. + + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance. + @param[in] PciHandle PCI function for which to return the vector. + @param[out] Vector IRQ number that corresponds to the interrupt line. + + @retval EFI_SUCCESS The interrupt line value was read successfully. + +**/ +EFI_STATUS +EFIAPI +Interrupt8259GetInterruptLine ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_HANDLE PciHandle, + OUT UINT8 *Vector + ) +{ + EFI_PCI_IO_PROTOCOL *PciIo; + UINT8 InterruptLine; + EFI_STATUS Status; + + Status = gBS->HandleProtocol ( + PciHandle, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo + ); + if (EFI_ERROR (Status)) { + return EFI_INVALID_PARAMETER; + } + + PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint8, + PCI_INT_LINE_OFFSET, + 1, + &InterruptLine + ); + // + // Interrupt line is same location for standard PCI cards, standard + // bridge and CardBus bridge. + // + *Vector = InterruptLine; + + return EFI_SUCCESS; +} + +/** + Issues the End of Interrupt (EOI) commands to PICs. + + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance. + @param[in] Irq The interrupt for which to issue the EOI command. + + @retval EFI_SUCCESS The EOI command was issued. + @retval EFI_INVALID_PARAMETER The Irq is not valid. + +**/ +EFI_STATUS +EFIAPI +Interrupt8259EndOfInterrupt ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_8259_IRQ Irq + ) +{ + if ((UINT32)Irq > Efi8259Irq15) { + return EFI_INVALID_PARAMETER; + } + + if (Irq >= Efi8259Irq8) { + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, LEGACY_8259_EOI); + } + + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, LEGACY_8259_EOI); + + return EFI_SUCCESS; +} + +/** + Driver Entry point. + + @param[in] ImageHandle ImageHandle of the loaded driver. + @param[in] SystemTable Pointer to the EFI System Table. + + @retval EFI_SUCCESS One or more of the drivers returned a success code. + @retval !EFI_SUCCESS Error installing Legacy 8259 Protocol. + +**/ +EFI_STATUS +EFIAPI +Install8259 ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_8259_IRQ Irq; + + // + // Initialze mask values from PCDs + // + mLegacyModeMask = PcdGet16 (Pcd8259LegacyModeMask); + mLegacyModeEdgeLevel = PcdGet16 (Pcd8259LegacyModeEdgeLevel); + + // + // Clear all pending interrupt + // + for (Irq = Efi8259Irq0; Irq <= Efi8259Irq15; Irq++) { + Interrupt8259EndOfInterrupt (&mInterrupt8259, Irq); + } + + // + // Set the 8259 Master base to 0x68 and the 8259 Slave base to 0x70 + // + Status = Interrupt8259SetVectorBase (&mInterrupt8259, PROTECTED_MODE_BASE_VECTOR_MASTER, PROTECTED_MODE_BASE_VECTOR_SLAVE); + + // + // Set all 8259 interrupts to edge triggered and disabled + // + Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel); + + // + // Install 8259 Protocol onto a new handle + // + Status = gBS->InstallProtocolInterface ( + &m8259Handle, + &gEfiLegacy8259ProtocolGuid, + EFI_NATIVE_INTERFACE, + &mInterrupt8259 + ); + return Status; +} diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridge.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridge.h new file mode 100644 index 0000000000..3bf31067fa --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridge.h @@ -0,0 +1,68 @@ +/** @file + Header file of OVMF instance of PciHostBridgeLib. + + Copyright (c) 2016 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 behind any + PCI bridge hanging off this root bus. + + The caller is repsonsible for ensuring that + RootBusNumber <= 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, with + UID = 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/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf new file mode 100644 index 0000000000..8c6de3dca6 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf @@ -0,0 +1,50 @@ +## @file +# OVMF's instance of the PCI Host Bridge Library. +# +# Copyright (C) 2016, Red Hat, Inc. +# Copyright (c) 2016 - 2018 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PciHostBridgeLib + FILE_GUID = 2F04EC41-C3A0-43EB-AC6A-409F973F4439 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = PciHostBridgeLib + +# +# The following information is for reference only and not required by the build +# tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + PciHostBridgeLib.c + PciHostBridge.h + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + DevicePathLib + MemoryAllocationLib + PciLib + +[Pcd] + gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase + gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId + gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.h new file mode 100644 index 0000000000..1fb031b752 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.h @@ -0,0 +1,156 @@ +/** @file + Platform BDS customizations include file. + + Copyright (c) 2006 - 2017 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 + ); + +#endif // _PLATFORM_SPECIFIC_BDS_PLATFORM_H_ diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf new file mode 100644 index 0000000000..55da35e87d --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf @@ -0,0 +1,69 @@ +## @file +# Platform BDS customizations library. +# +# Copyright (c) 2007 - 2018 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PlatformBootManagerLib + FILE_GUID = 8AE4756F-0C71-4C06-84D4-4C71F204D514 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = PlatformBootManagerLib|DXE_DRIVER + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + BdsPlatform.c + PlatformData.c + BdsPlatform.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + BaseLib + MemoryAllocationLib + UefiBootServicesTableLib + BaseMemoryLib + DebugLib + PcdLib + UefiBootManagerLib + BootLogoLib + DevicePathLib + PciLib + NvVarsFileLib + LoadLinuxLib + UefiLib + +[Pcd] + gSimicsX58PkgTokenSpaceGuid.PcdEmuVariableEvent + gSimicsX58PkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut + gSimicsX58PkgTokenSpaceGuid.PcdShellFile + +[Pcd.IA32, Pcd.X64] + gEfiMdePkgTokenSpaceGuid.PcdFSBClock + +[Protocols] + gEfiDecompressProtocolGuid + gEfiPciRootBridgeIoProtocolGuid + gEfiS3SaveStateProtocolGuid # PROTOCOL SOMETIMES_CONSUMED + gEfiDxeSmmReadyToLockProtocolGuid # PROTOCOL SOMETIMES_PRODUCED + gEfiLoadedImageProtocolGuid # PROTOCOL SOMETIMES_PRODUCED + gEfiFirmwareVolume2ProtocolGuid # PROTOCOL SOMETIMES_CONSUMED + +[Guids] + gEfiEndOfDxeEventGroupGuid diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.bmp b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.bmp new file mode 100644 index 0000000000000000000000000000000000000000..86d7030833a096f545393735d931d9f4f2fbf8c0 GIT binary patch literal 141078 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 +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#image IMG_LOGO Logo.bmp diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.inf new file mode 100644 index 0000000000..3380f3c1d5 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.inf @@ -0,0 +1,28 @@ +## @file +# The default logo bitmap picture shown on setup screen, which is corresponding to gEfiDefaultBmpLogoGuid. +# +# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = Logo + MODULE_UNI_FILE = Logo.uni + FILE_GUID = 7BB28B99-61BB-11D5-9A5D-0090273FC14D + MODULE_TYPE = USER_DEFINED + VERSION_STRING = 1.0 + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64 +# + +[Binaries] + BIN|Logo.bmp|* + +[UserExtensions.TianoCore."ExtraFiles"] + LogoExtra.uni diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.uni new file mode 100644 index 0000000000..9d1bbaffa9 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.uni @@ -0,0 +1,16 @@ +// /** @file +// The default logo bitmap picture shown on setup screen, which is corresponding to gEfiDefaultBmpLogoGuid. +// +// This module provides the default logo bitmap picture shown on setup screen, which corresponds to gEfiDefaultBmpLogoGuid. +// +// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Provides the default logo bitmap picture shown on setup screen, which corresponds to gEfiDefaultBmpLogoGuid" + +#string STR_MODULE_DESCRIPTION #language en-US "This module provides the default logo bitmap picture shown on setup screen, which corresponds to gEfiDefaultBmpLogoGuid." + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.inf new file mode 100644 index 0000000000..01102b138f --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.inf @@ -0,0 +1,55 @@ +## @file +# The default logo bitmap picture shown on setup screen. +# +# Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = LogoDxe + MODULE_UNI_FILE = LogoDxe.uni + FILE_GUID = F74D20EE-37E7-48FC-97F7-9B1047749C69 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = InitializeLogo +# +# This flag specifies whether HII resource section is generated into PE image. +# + UEFI_HII_RESOURCE_SECTION = TRUE + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + Logo.bmp + Logo.c + Logo.idf + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + UefiBootServicesTableLib + UefiDriverEntryPoint + DebugLib + +[Protocols] + gEfiHiiDatabaseProtocolGuid ## CONSUMES + gEfiHiiImageExProtocolGuid ## CONSUMES + gEfiHiiPackageListProtocolGuid ## PRODUCES CONSUMES + gEdkiiPlatformLogoProtocolGuid ## PRODUCES + +[Depex] + gEfiHiiDatabaseProtocolGuid AND + gEfiHiiImageExProtocolGuid + +[UserExtensions.TianoCore."ExtraFiles"] + LogoDxeExtra.uni diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.uni new file mode 100644 index 0000000000..9635701b60 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.uni @@ -0,0 +1,16 @@ +// /** @file +// The default logo bitmap picture shown on setup screen. +// +// This module provides the default logo bitmap picture shown on setup screen, through EDKII Platform Logo protocol. +// +// Copyright (c) 2016, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Provides the default logo bitmap picture shown on setup screen." + +#string STR_MODULE_DESCRIPTION #language en-US "This module provides the default logo bitmap picture shown on setup screen, through EDKII Platform Logo protocol." + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni new file mode 100644 index 0000000000..c6ea34b81d --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni @@ -0,0 +1,14 @@ +// /** @file +// Logo Localized Strings and Content +// +// Copyright (c) 2016, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"Logo Image File" + + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtra.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtra.uni new file mode 100644 index 0000000000..041179fb75 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtra.uni @@ -0,0 +1,14 @@ +// /** @file +// Logo Localized Strings and Content +// +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"Logo Image File" + + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf new file mode 100644 index 0000000000..e5ca95e20e --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf @@ -0,0 +1,40 @@ +## @file +# An instance of the PCI Library that is based on both the PCI CF8 Library and +# the PCI Express Library. +# +# This PciLib instance caches the SimicsX58 platform type (X58-ICH10) in +# its entry point function, then delegates function calls to one of the +# PciCf8Lib or PciExpressLib "backends" as appropriate. +# +# Copyright (C) 2016, Red Hat, Inc. +# Copyright (c) 2007 - 2014 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DxePciLibX58Ich10 + FILE_GUID = FC214B5D-B5B5-4E54-9B28-5E94532E5E2A + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = PciLib|DXE_DRIVER DXE_RUNTIME_DRIVER SMM_CORE DXE_SMM_DRIVER UEFI_DRIVER UEFI_APPLICATION + CONSTRUCTOR = InitializeConfigAccessMethod + +# VALID_ARCHITECTURES = IA32 X64 + +[Sources] + PciLib.c + +[Packages] + MdePkg/MdePkg.dec + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec + +[LibraryClasses] + PcdLib + PciCf8Lib + PciExpressLib + +[Pcd] + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h new file mode 100644 index 0000000000..2deb2a88eb --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h @@ -0,0 +1,45 @@ +/** @file + This is an implementation of the ACPI platform driver. + + Copyright (c) 2017 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/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.inf new file mode 100644 index 0000000000..b4b52b6622 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.inf @@ -0,0 +1,105 @@ +## @file +# Component information file for AcpiPlatform module +# +# Copyright (c) 2017 Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = AcpiPlatform + FILE_GUID = FC90EB7A-3E0A-483C-A26C-484D36593FF4 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = 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/Overrides/OvmfPkg/QemuVideoDxe/Qemu.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qemu.h new file mode 100644 index 0000000000..f6ef44a14f --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qemu.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_MASK, 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 = 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_SIGNATURE) + + +// +// 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 gQemuVideoDriverSupportedEfiVersion; + +// +// 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 of 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 specified + 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_PROTOCOL 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 caller 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 format. + + @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 specified 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 support + 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 controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified 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 specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + 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 returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL 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 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 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 caller 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 format. + + @param ControllerName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + controller specified by ControllerHandle and + ChildHandle in the language specified by + Language from the point of view of the driver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable name 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 valid + 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 currently + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +QemuVideoComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + 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/Overrides/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf new file mode 100644 index 0000000000..8370559016 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf @@ -0,0 +1,73 @@ +## @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 = 0x00010005 + BASE_NAME = QemuVideoDxe + FILE_GUID = e3752948-b9a1-4770-90c4-df41c38986be + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = InitializeQemuVideo + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# +# DRIVER_BINDING = gQemuVideoDriverBinding +# COMPONENT_NAME = gQemuVideoComponentName +# + +[Sources.common] + ComponentName.c + Driver.c + DriverSupportedEfiVersion.c + Gop.c + Initialize.c + Qemu.h + +[Sources.Ia32, Sources.X64] + VbeShim.c + VbeShim.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + OptionRomPkg/OptionRomPkg.dec + OvmfPkg/OvmfPkg.dec + SimicsOpenBoardPkg/SimicsOpenBoardPkg.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 + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId + gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm new file mode 100644 index 0000000000..cb2a60d827 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm @@ -0,0 +1,281 @@ +;------------------------------------------------------------------------------ +; @file +; A minimal Int10h stub that allows the Windows 2008 R2 SP1 UEFI guest's buggy, +; 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_ENABLED + + 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/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h new file mode 100644 index 0000000000..cc9b6e14cd --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/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[] = { + /* 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/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh new file mode 100644 index 0000000000..7669f8a219 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh @@ -0,0 +1,79 @@ +#!/bin/sh +### +# @file +# Shell script to assemble and dump the fake Int10h handler from NASM source 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=$(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 closes +# 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 CRLF +# 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[] = {\n' + paste -d ' ' -- "$STEM".offsets "$STEM".insns "$STEM".bytes + printf '};\n' + printf '#endif\n' +} \ +| unix2dos >"$STEM".h diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h new file mode 100644 index 0000000000..a9673f9c87 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h @@ -0,0 +1,218 @@ +/** @file + Driver implementing the Tiano Legacy 8259 Protocol + +Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _8259_H__ +#define _8259_H__ + +#include +#include + +#include +#include +#include +#include +#include + +#include + +// 8259 Hardware definitions + +#define LEGACY_MODE_BASE_VECTOR_MASTER 0x08 +#define LEGACY_MODE_BASE_VECTOR_SLAVE 0x70 + +#define PROTECTED_MODE_BASE_VECTOR_MASTER 0x68 +#define PROTECTED_MODE_BASE_VECTOR_SLAVE 0x70 + +#define LEGACY_8259_CONTROL_REGISTER_MASTER 0x20 +#define LEGACY_8259_MASK_REGISTER_MASTER 0x21 +#define LEGACY_8259_CONTROL_REGISTER_SLAVE 0xA0 +#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 + +#define LEGACY_8259_EOI 0x20 + +// Protocol Function Prototypes + +/** + Sets the base address for the 8259 master and slave PICs. + + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance. + @param[in] MasterBase Interrupt vectors for IRQ0-IRQ7. + @param[in] SlaveBase Interrupt vectors for IRQ8-IRQ15. + + @retval EFI_SUCCESS The 8259 PIC was programmed successfully. + @retval EFI_DEVICE_ERROR There was an error while writing to the 8259 PIC. + +**/ +EFI_STATUS +EFIAPI +Interrupt8259SetVectorBase ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN UINT8 MasterBase, + IN UINT8 SlaveBase + ); + +/** + Gets the current 16-bit real mode and 32-bit protected-mode IRQ masks. + + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance. + @param[out] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15. + @param[out] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15. + @param[out] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15. + @param[out] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-IRQ15. + + @retval EFI_SUCCESS The 8259 PIC was programmed successfully. + @retval EFI_DEVICE_ERROR There was an error while reading the 8259 PIC. + +**/ +EFI_STATUS +EFIAPI +Interrupt8259GetMask ( + IN EFI_LEGACY_8259_PROTOCOL *This, + OUT UINT16 *LegacyMask, OPTIONAL + OUT UINT16 *LegacyEdgeLevel, OPTIONAL + OUT UINT16 *ProtectedMask, OPTIONAL + OUT UINT16 *ProtectedEdgeLevel OPTIONAL + ); + +/** + Sets the current 16-bit real mode and 32-bit protected-mode IRQ masks. + + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance. + @param[in] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15. + @param[in] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15. + @param[in] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15. + @param[in] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-IRQ15. + + @retval EFI_SUCCESS The 8259 PIC was programmed successfully. + @retval EFI_DEVICE_ERROR There was an error while writing the 8259 PIC. + +**/ +EFI_STATUS +EFIAPI +Interrupt8259SetMask ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN UINT16 *LegacyMask, OPTIONAL + IN UINT16 *LegacyEdgeLevel, OPTIONAL + IN UINT16 *ProtectedMask, OPTIONAL + IN UINT16 *ProtectedEdgeLevel OPTIONAL + ); + +/** + Sets the mode of the PICs. + + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance. + @param[in] Mode 16-bit real or 32-bit protected mode. + @param[in] Mask The value with which to set the interrupt mask. + @param[in] EdgeLevel The value with which to set the edge/level mask. + + @retval EFI_SUCCESS The mode was set successfully. + @retval EFI_INVALID_PARAMETER The mode was not set. + +**/ +EFI_STATUS +EFIAPI +Interrupt8259SetMode ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_8259_MODE Mode, + IN UINT16 *Mask, OPTIONAL + IN UINT16 *EdgeLevel OPTIONAL + ); + +/** + Translates the IRQ into a vector. + + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance. + @param[in] Irq IRQ0-IRQ15. + @param[out] Vector The vector that is assigned to the IRQ. + + @retval EFI_SUCCESS The Vector that matches Irq was returned. + @retval EFI_INVALID_PARAMETER Irq is not valid. + +**/ +EFI_STATUS +EFIAPI +Interrupt8259GetVector ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_8259_IRQ Irq, + OUT UINT8 *Vector + ); + +/** + Enables the specified IRQ. + + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance. + @param[in] Irq IRQ0-IRQ15. + @param[in] LevelTriggered 0 = Edge triggered; 1 = Level triggered. + + @retval EFI_SUCCESS The Irq was enabled on the 8259 PIC. + @retval EFI_INVALID_PARAMETER The Irq is not valid. + +**/ +EFI_STATUS +EFIAPI +Interrupt8259EnableIrq ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_8259_IRQ Irq, + IN BOOLEAN LevelTriggered + ); + +/** + Disables the specified IRQ. + + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance. + @param[in] Irq IRQ0-IRQ15. + + @retval EFI_SUCCESS The Irq was disabled on the 8259 PIC. + @retval EFI_INVALID_PARAMETER The Irq is not valid. + +**/ +EFI_STATUS +EFIAPI +Interrupt8259DisableIrq ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_8259_IRQ Irq + ); + +/** + Reads the PCI configuration space to get the interrupt number that is assigned to the card. + + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance. + @param[in] PciHandle PCI function for which to return the vector. + @param[out] Vector IRQ number that corresponds to the interrupt line. + + @retval EFI_SUCCESS The interrupt line value was read successfully. + +**/ +EFI_STATUS +EFIAPI +Interrupt8259GetInterruptLine ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_HANDLE PciHandle, + OUT UINT8 *Vector + ); + +/** + Issues the End of Interrupt (EOI) commands to PICs. + + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance. + @param[in] Irq The interrupt for which to issue the EOI command. + + @retval EFI_SUCCESS The EOI command was issued. + @retval EFI_INVALID_PARAMETER The Irq is not valid. + +**/ +EFI_STATUS +EFIAPI +Interrupt8259EndOfInterrupt ( + IN EFI_LEGACY_8259_PROTOCOL *This, + IN EFI_8259_IRQ Irq + ); + +#endif diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf new file mode 100644 index 0000000000..e66b21c914 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf @@ -0,0 +1,46 @@ +## @file +# 8259 Interrupt Controller driver that provides Legacy 8259 protocol. +# +# Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = Legacy8259 + MODULE_UNI_FILE = Legacy8259.uni + FILE_GUID = 79CA4208-BBA1-4a9a-8456-E1E66A81484E + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = Install8259 + +[Sources] + 8259.c + 8259.h + +[Packages] + MdePkg/MdePkg.dec + PcAtChipsetPkg/PcAtChipsetPkg.dec + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec + +[LibraryClasses] + UefiBootServicesTableLib + DebugLib + UefiDriverEntryPoint + IoLib + PcdLib + +[Protocols] + gEfiLegacy8259ProtocolGuid ## PRODUCES + gEfiPciIoProtocolGuid ## SOMETIMES_CONSUMES + +[Pcd] + gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeMask ## CONSUMES + gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel ## CONSUMES + +[Depex] + TRUE + +[UserExtensions.TianoCore."ExtraFiles"] + Legacy8259Extra.uni diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni new file mode 100644 index 0000000000..d035292419 --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni @@ -0,0 +1,16 @@ +// /** @file +// 8259 Interrupt Controller driver that provides Legacy 8259 protocol. +// +// 8259 Interrupt Controller driver that provides Legacy 8259 protocol. +// +// Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "8259 Interrupt Controller driver that provides Legacy 8259 protocol" + +#string STR_MODULE_DESCRIPTION #language en-US "8259 Interrupt Controller driver that provides Legacy 8259 protocol." + diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni new file mode 100644 index 0000000000..ee43f6923c --- /dev/null +++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni @@ -0,0 +1,14 @@ +// /** @file +// Legacy8259 Localized Strings and Content +// +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"Legacy 8259 Interrupt Controller DXE Driver" + + -- 2.16.2.windows.1