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 <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Agyeman Prince <prince.agyeman@intel.com>
Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../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.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiDxe.h>
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/X58Ich10.h>
+
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Protocol/PciRootBridgeIo.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PciHostBridgeLib.h>
+#include <Library/PciLib.h>
+#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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BdsPlatform.h"
+#include <Guid/RootBridgesConnectedEventGroup.h>
+#include <Protocol/FirmwareVolume2.h>
+
+#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"<unavailable>" : 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"<failed to convert>";
+ 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. <BR>
+
+ 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/HiiImageEx.h>
+#include <Protocol/PlatformLogo.h>
+#include <Protocol/HiiPackageList.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+
+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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+
+#include <IndustryStandard/X58Ich10.h>
+
+#include <Library/PciLib.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/PciExpressLib.h>
+#include <Library/PcdLib.h>
+
+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. <BR>
+
+ 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; Index<MAX_CPU_NUM; Index++) {
+ DEBUG ((EFI_D_ERROR, " %02d 0x%02X 0x%02X %d 0x%02X %d\n",
+ Index, mCpuApicIdOrderTable[Index].AcpiProcessorId,
+ mCpuApicIdOrderTable[Index].ApicId,
+ mCpuApicIdOrderTable[Index].Flags,
+ mCpuApicIdOrderTable[Index].SwProcApicId,
+ mCpuApicIdOrderTable[Index].SocketNum));
+ }
+}
+
+EFI_STATUS
+AppendCpuMapTableEntry (
+ IN VOID *ApicPtr,
+ IN UINT32 LocalApicCounter
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE *LocalApicPtr;
+ EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE *LocalX2ApicPtr;
+ UINT8 Type;
+
+ Status = EFI_SUCCESS;
+ Type = ((ACPI_APIC_STRUCTURE_PTR *)ApicPtr)->AcpiApicCommon.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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+
+#include <IndustryStandard/Acpi.h>
+
+//
+// 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include <IndustryStandard/Acpi.h>
+
+//
+// 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/HighPrecisionEventTimerTable.h>
+
+//
+// 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
+#include <Library/PcdLib.h>
+
+//
+// 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. <BR>
+
+ 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "Qemu.h"
+#include <IndustryStandard/Acpi.h>
+
+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. <BR>
+
+ 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. <BR>
+
+ 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. <BR>
+
+ 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:
+ <http://www.cs.cmu.edu/~ralf/files.html>
+ <http://www.ctyme.com/rbrown.htm>
+
+ Copyright (C) 2014, Red Hat, Inc.
+ Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <IndustryStandard/LegacyVgaBios.h>
+#include <Library/DebugLib.h>
+#include <Library/PciLib.h>
+#include <Library/PrintLib.h>
+#include <SimicsPlatforms.h>
+
+#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. <BR>
+
+ 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. <BR>
+
+ 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. <BR>
+#
+# 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
+#define _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
+
+
+#include <PiDxe.h>
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/SmBios.h>
+#include <IndustryStandard/PeImage.h>
+
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/UefiBootManagerLib.h>
+#include <Library/BootLogoLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/NvVarsFileLib.h>
+
+#include <Protocol/Decompress.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/SimpleFileSystem.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/S3SaveState.h>
+#include <Protocol/DxeSmmReadyToLock.h>
+#include <Protocol/LoadedImage.h>
+
+#include <Guid/Acpi.h>
+#include <Guid/SmBios.h>
+#include <Guid/Mps.h>
+#include <Guid/HobList.h>
+#include <Guid/GlobalVariable.h>
+#include <Guid/EventGroup.h>
+
+#include <SimicsPlatforms.h>
+
+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. <BR>
+#
+# 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
zcmeHwJ9Hz-kzh@gFoN)Qu|weq&F~F*XbyPdaEHTfE*dKcjU5ohf-&!%BU8pXGG)q?
zD^tc9GS`(UQ>MIoGG)r#cb?2OW$Gd_vnu0Pg~E?y>sT{Q)F&%4G9u%Xk&#)e|2h0&
zn&2`0PLf>1@BjWNN&Xl7`zYzU`~UYcP5w_masS+n@=v#$bm8A8pL~*ZKm9cM6#l(=
z^C_Iaf!{aDCtrS<d<p+Pc?<u(e4D(*e{bKy^(^^xHcMvkZ-xI>tK`$wx5>BPew+N{
zCqGF({r0EHo1gqN`6>SUDV+cGXUUiF?`J>zS@QFr|2+Bf=f6mP@rz$1Z-4R2<d?tv
zW%A`Oeg)^hN`Cb#`2FRtlefS6b@J<9|2p~dSHDSq^PAr!Z-4zC$qfGe$A7@@Z+@Hn
z_P4)H-u~uyaQ?gGcfW(*-~K-N{qKLDtbX^0<PU%NLo)l_AL0Cu$shj+zrX)e@~1!j
zDf#vfe@_1V=RYT_KmKR(E&Th>|AgN^{U!O!U;dK(*MI$2^6j7hn*8;ze@*`Ox4)It
zdHsE*z$*n_Dey{xR|>pR;FSWe6nLe;D+OLD@JfMK3cOO_l>)C6c%=ZLK$`j}9J%#+
z`g{~f-@JKc$n%k3)||b2c=-M+LnK+A>$>;;@$vEfKfY?L=VAb__wxr}$K&JI&mkaS
zw~kS*1G~9@9j0;vimRVfxy_Y(?c(tf7y|!~-77nSYEzvqlcpIQf^ZIl@W;O*3M7fT
z!9kZ0_+7Z-@1+@3FK$(@q_Qx*CNCLHfLrh%DN_M$JaLeE@0@S|JKldEOG8tTLJSzc
zYJ|Dn!`@e*DIXr+U-e-^H5^DwWD+9bE5=`ek8z`XKS_FDqrkua>L0^f)%(?nEBo=A
z_fYpY?}i^&&`AMu>PnMqa+)M3U!$^re1FlY5cqf;0Cy_D)w70^J`w{D#QyQ|9Rf@{
z8kVb`(W3$AHjlEeUB&Ltb>`mu&NuNEoIQM&cK+Snc~b#~A`kH2n~2dD(13?{J;ulG
z|Id&fV>kskN%9G{)3wsUdQ;W(-n%jm@Z%%a^j$>b;a#Vy<Dc-|$FJd0z%bzRz4!P4
z{sCjp0*YfS>J9)L?rr`_zY37>O@Q{_-78}U2meqcS?f20ZdoD)$&5I7LUsP#5!2mA
zEIv!W^NqXXbtyvT1i?FFELrj6Q@p|h8in*2V;#tu|Ax1|Dk=1pD}m+Uwxe4Bj5U1+
zJNV<fsLOyKaN}*L9!@<z9mh8h<ni$wkx9P7lK%h4Z%*B<7Jsrp4EO5e<5xcS!ohMF
zJ_0O6y=;Bij258V7V**nn0p+qQDwP~>Dq?`cmO&E`M9W{0!H{GGAQ{1E-QX`E<5s}
zixRkn@-arZCEI?0@4(@!dEW!@f%90CZ#9t*CtDBKkZs|re|+@#d>x=TP>&8u37Fif
zP;WRXRfWgu@yZqbfd>-qeS<tg%t&h+Aa47}cR8#P>jS!=`3l7Lc);J!$~z?;OIihj
zxJtjk;$;D^S?~^kMG7IeoW6RCcaSk~q(8<IzH0o9OmK=1x&^#M_~DWL3Z%@l%Bx4@
zQb6AQ0u=1$cz8ZPP&8e|HGe+wWG;a{KAZ!dmCOWS0ZA+r)prfR?Qf3}ZHIRt%l`lv
zzO}JApCzUJ@O1P=5WkZCa0l!MTn7vs`QQIzf_!;+1fA~c0XAemf*X$MP!igY&BDW#
zd-rkbYJv*{4EhQVuCL$*Dm%m{luAOUt{}bp7>!hUi69=~R-0q&3OmUD4Bta0ky`-E
zBMCQ&c4z~>MVXJ@dBmalpL?R*f<qBnTQ#X(J_tX?h<1tLTfD%Bj#$v8##j&Vqk}Yl
z@AY!xHNnH@N%pU<a<nu~HUmE#yNG;vNkH|7S}oL&{>V4s^ECYzID`MbpMsHs!vn@!
z&V+3w2Pj#D`tZXJ_M-sGAqlrXPlBcONaEABVz;s4SiqS=@9#jn@OTgGC#?-dgT$2G
z--!^SMEK$C2MRMB*}oyW&Rm32W4K0r<wWA0cjG*hKmZaaM^HJ~Vp3Cse}#_#BI4uv
z?}PKYf)sz2zQKnMuroQOk$1S&{|Qw)?8fju9MHeU6|8@9k`j?5-ef({?Vfmz{NTul
z6~lkvK)7~A<pUsHuchXjkS)~s1>zt017ZiRi1VxPE@+rB{(^ty{I0;Y<X_;P2a4d3
zzTPsx848;6ue=%x{w`7+O9gX_Fu@+d-G_0CQt1Jgj02h4c>L1?!h9HEL8Lugef_t;
zp{PGRq8g8|BDz@ifQQ!rNT?+7E-FwFyj#SjQa(^$Ab&|ne*?-yfnolYlQqW=01AB<
z`2nRtKFVKgL(mTh)C&}X`>xkSc+-}ThiiC5@cGo?>P&AiC2xWXLl_@<ZAS2fn>B~y
zEP9hpAtG3)%foU#Ho^kTkU&H`)PUUf_74!O_alHGC?AjDQv~}Fsb9)RL?Ea%Qe=$y
zhXSsny77dg7WC*bJj9k_&vlFfOrd>PIjS`$P>+v5YSQ(Be8ll!kPo0&7$ISGu3jg5
zXsxgbZ_sH7fPv9?AP+Yl!AUOpf$xFw@~#>p8DWL)(2C0&tEB~kMLm!50Ugba{s5Us
z{jxvCJA`Zj-WP~}DDcsbfH{urt^(i(j^2?UIN(APg@+Rg<Px4DH&KuPFrJR#rf;?B
zU-?Il{bQ^byA-_PT`lAX@&y408LS4N0a^3MwID!3+5?Pt9q;bCP7`5;K~m|xn9z2*
z>AQp%c031C0MSbO0qqHgqY^dWo@^!kv6Qptfgi3X1$_k|p?4zHpiv*AdsRkDKJvp4
zCm;S4$mS{S0Q*XVe}%Ys?dtt2B$q2SM)p<m;qHcx>;OAaaYNG3l=>gnf&eMdp2>%o
z=g?`O9Y^r5u=@fRaNGm>3J*Lli5*cdsZ`zZu8ix(;hvL#HxLPh>lAxe&{qJ{*>j-T
zxp#cZ&g$A6<iop~AV{7GB|qS0Cm%j|=!XJm&x4gg_WNFq-6+ThAcfEZU}xf;_f_Fu
zcj6*&ffzxTI(}$a&VJDDSqF04`;~k^V}kt%@&V){;uxqD?;wMq2+^Qppxxuh6E6KR
zJo^TR`e2}fJ;%pzH=2)NKVbCl)CxWd_5;oku&)D1;=FPgmV0jy`9Z251JJTdy~Wyq
zmtH6;zz^;0#~4uv^5JwTigFn02i=EN5hSti9rSSO-H;DQIAW}^{cyxP!JbD3d3}ZN
zfu3>%iSkkUSMU%B1_L+W2G?fj#&8u}NoPMCO%bpc0?=+K7Y}~e4JT-u0UxXixi*Gh
zIGlXAVJO)1f5UnLVAmAXaT^aO;V4#6*vZF3u;&2GBU!=<_5-pV%C>9--mZXie*!<6
z><6ePY@xE}kwK;20D^trTk6uDd-;H-I6}j3nY4jg4Jiqz_FYR+BAt^PLs>wQ%xgJd
zuaCaq3@Yg#m6nMlC-M;iZzf34d`@{+@&UT97RiyDq}mL)eTmB7g~n9&qa1%k>X+@0
zcN~L|v{hZf8oJ;_91jwI*R>1&c*9b?=T1I#{CK$doA3Fa^Iix*K76-7`y2AZhl_)F
zV)bLZ7vzHj#VZ61{a}RWn-1Rs@HzmhX9EppR<NKCVs~(WK^wdqVOaV=2iI4w0|Ppt
zIwy`^BB_8n5%nFE+Vim|sk0j(?EnkM=Z?wf@8XTm(ykMU(x6w32r*QA!#fI&(Y}s%
z8JG`j{I%nUleUr|jvrWW&@vUk@+4?~he~;`_IK<^?429bS8y4eJNHTn%Lg#9*7CTH
zvy!#I+dZi4ITWwt!;Q9}E-#LbA)Yjk7k)|_=v=X^s>ew?VhMH}q}|yOjAp>C;O~NF
z#yA9O<?1bWQch96hj1!!U7!wN;=4}JIqyD>^5IJP;pZ5tf&&e%Iy_*QiUz=&53jF0
zKcc=W-=nYsIgn-8;)nM=tM>BEEq+lx0HzyEMf>5ZgNm>&-%{+g{t9lO2Z{q^IHbM`
z*G@jd_yb-H_8bRQuKSk*!hmQg9d48mnp*l-*hR;_(GTAb;}3X^lo~rkeG_=gQvmFd
zRszWjhAU^!12IrO0P{*dI4txuT(wvTk9HN9wX&Oa@)6pBRUs9z{jO#B2apT|0W}|?
zx!x77g?xYoeuJO@k^{u}k%mMkCs-KkcTFw*D-<T2)WzyQ13`fw?_VJ%&Lj7|+IvM2
z8$1hu(W3DOHCG4;tHHjGEr9ci9~@Rts;<04<eNba%q?$69fkVJH8<D~#0F79&0O_I
zk1z(LgTN4fcZ_8NKb(9-`vJYjJq1WXJ|dcFIfWix4m}?oH-Gx>AH4AdLyq#{`yxJq
z3oJFpli(sous~4&?4EeHm_DjGuOLB#-H@`94++clDgch~-QR~%4a_ZXoBkCN&DZ3r
zLx0rWDes|tkT7hh()H88A0i*fC8w_dRwW<NBk4eD2*QPbo|mDisQBFJ<GTTtz+&%C
zTsa&|c>Ceh<rrRt|D9JvT91IkL4=qT(5IEYf=6Co1^EcD5MYHQ!UiP2hn@=@IBR%-
zqp}|WtFj-y6GJ`zKja7YM?Bmeln-~qyQKjQ=Picuh?5VeC7b|K`+<O>zAE9u%|Nwq
zC-4Jme0K&9zj*_#et6@sD97h`1Bft&$8hRQV5CTJh>=)ChU0VV%=M_?sZo7pB8il!
zkfcqrAh*6}+mGPgx`sl}189H}BH)j}54=Q-!r@vIu8DjAsi=Ioj$OGsp%+4tO2xaH
zJa;@A@7_U0@B0`S{^0}GNyq2N54<P+-O@J=MybTH`PcQRAZcOR1MP=bT~Gx>5=r5@
zkjrj)I8fd-%17C`VCV#OVn=gIzUr~qh_csK4RSY_d;ndlYaC7aVc!^Gdi&u#13!OW
z>MQpSV(@jC!L0-jJGHO$Jr0n+c2gVgoL7OqjDO^YKdv80eFcF15dl}I*Pe{sD?k7!
z5mH}}AO1Exi?Bk6b&}`ncg|!j<kk<Ue0bheN}kTnmhurr9|(d?*7D&5#s@4=uv}xH
z6kzQ<12?5q%15B;<2Rp2goEuu#RszFDuKTj<+Lo4#qq;+9<1JRT*wE$iSJUtWfh-5
zYAM*GfBm$)QT>Abz&1HcgflqsAMgWu5ZvXkLWgzQ+0_rCbC5_DlMk%bIV!X|kFBR1
zizm7UGkyU6V~nr?kub~3X?K_*a#G{4K2QCisvHlxU<y$KSeL7*Qq4#o_y?`^u`9gt
z@pgFNCD>bGZqHp3qyX$2@~O)q!gn7Ovs_On_5%t5KYXrA)Kw*tfR=0h7;!`leFgjd
z4HR)*!k?qKx;|PdpMU`Nmq`9nK4SH*HHaGG<}M)F)eo&fP{!^FfI#fO3U8GJ@RyE}
zUJ`v%LnnY2z<Wud!}_DLA6|mT?yegpIXKuI+&!Qy1?<kDTYNMA2RQxi7(~crlK3+C
zx3V8_j+PB71bzT4#G1kKt@qI)Yy=cIkbFR$0PF&pTggh$&V>5<j-wS*X-?W5y?t*+
z^5G@uhAy<#pTa%35!!~+t5C{iV1mYWhxhGD`EcN%2$~F^=K(K7`{Cr(QSkxhx?BhK
zP<#d{2aFVlA<0*jrTY9EAUEDEk1=8w^c8p{NE+aW8;x2>9z#AVn*ohM`2ZaJpbbx>
zG*rE|M7_Kb{9C;3I=gES_)5-k0$}byaR^Uc4Q02CNerd@0I7Y~b9FnOBLvs^$Bub$
z75GtN2>0>8QLFd09>41N&W(cPMa8}2T1dwt;EN-y>hPM+OPY`GqI~=aiQ=5P2+JWE
z2sFmp52df1Jr61~%15vt1a~D4;RazD_EY~K`mVuIz_vJ7wtNbx|ELV^1)YHTxPg*j
zsy!2&D!@~uh4<7#HX8a`rGMqPR#6e5xEH<--mY6}Hg>%NeE`ho0)ZI2=pyjqGw39h
zn~hBQ!dK@w>v4lgFvl2l*)@{h-^Kc&-G{LsOg@mB&YlAy@H~1`Wv`9m;EDu^#kN!u
zfb_#~5i}0L0Xv*_!b?0J-bKF#@)@v%Zz?`RQio6-_JvRfYVq>Qm5&$L9mc*MFCPxz
zS1yiN(y#>V6f)of{DAElzd<7gfqW_;6=$IWudgt4>gB_Cni5t((h&&ihvPu@Japq=
z&mCm1ukbWdpK5hL77pyY(0C$3{(k)XJ($dffm~Qa5%0${udguri&VnWpkW+fU^Ltd
zr!GDWmwr~N8V^EoS89we2CYAKr(bpaoSvg~1sDOKrW`-K?*e3}G{0t%czhdxxdkLn
z;X?2E*tzb=TLVe&?_&Md92>l_^-;+Oyb0$38r3JDi}FE~k-J01A>1G$v~}HRWUwuj
zd^mL;>PEofG}s1^I4{6hK6rpw%2Uy6eV>2zwHuBKz$sSeE!q2C$%h}XeqDA>Y)NPz
z*bgDZ6iG)QtRKjBD1C(#@x~DCxj!%M2lfen0D8!+$f0n9h)`Ly{jblz^77$5BIt#o
zZUpS=fNDdy%g;t3nX5-w%2Uxd!9y9la7_@a3NS)OsT*S>AAjW3rn4dy!oEY|>IkRG
zuo&<jWi7}@1&b2M^#PcXs=(}X0tf|}K<@(&CLhofJx@Y+!5LhiVFef=_acLKz`~D#
z(T6EBrvRL*$#XuOmcxYdGVr66U`Iv&LZID+2^b-Jeth$<Ujy!V4n9KZd*c<hC@kJ_
zaRg*3z{J}%NJ9Vdfr>KZumc(BD?Z-tJC{q9a<Wpg->t1h7Wl3TjjrxM;}CgF>)ict
z76H4z?}d)NW!+_^q!MpHoIH_IL2Q6>kf(*DgVtDpOMZL-_5&9^;iw3BN%#?h_>S~r
z2MJvo3szZumimR!dJ1|+q5wj0c;&0)!=nV_xt`b8uA^XaXfa7>-mz+U?F)qU`1r$*
zLq-o0CrAMbUMUbI$$|k9<Bzh`=V|ss*BEf`#s=Whet3TuEQsR=b$Ek+@%YupKCa-S
z&K9gtXGtKab}vI3DHw#^Ig9Zes-p+UqPT+#Ze0l!`rVJ9Aga2ML<Dd+#k=mPB!QI*
zNz{(BjzCb}O(c41Ip7{d@UM^)Fcd)z^VV^tYCz~8;YIktG7U%~*Re4CZ8sxa)l_#<
z8bf>@&p{lqqVhk)-%a3`Hy~Rt6xoj-*darET&u!J5351Izz;k{r^p@OaY+?UUxi1m
z`p}O`P&kOO0GHZn3=RTjZ^OF)1*@zMH{>i4!e4}M!3x!55npYEV+Cus6Q{32Kq;O>
zb@YH<;se;#O}C&BuN*;ks~X>ORXUd7AE!G)-3U0GMpfWOG;Dm1K>SdFLoom&yayO{
zj9n|<V~Bsu$L9$w*z(+PML;~9WE!v{fw03oKK{52IUqj!94He2&}ry+4%Ol9@;@gZ
z)fL`7kbF3|3flu9;c(0ibq9VxWkeNteS&?Fl=2!SLh)VIhbk#xcnc^?I}luoevKY@
zfCN9KZPBm@fe`T+quhrV_^#*u<B*@DVju_F4}ND@-k{Cf1(%Qh8R|g}!~Y&usLAoe
zRf;-19NvI9et3LB_1{DN6QBeNYrqKOpC2D0?I4AxjBJ(_B=I#EqLelv-V{h8jUL{O
zOZ!$q`H)Y(`vns7@yGkM>XWyQK@^G!7$nTke{{y6lNCFFkl*`fr>tq54T5S1LGnXp
z)3I>>)M+HAlfq^($ExWSZaWHiQL^UG+r9r<>Xibo6nLe;D+OLD@JfMK3cOO_l>)C6
zc%{HA1zsueN`Y4jyi(wm0<RR<mI7I)+w1jD`u*-+87A9S`&wR7Ano=C!?V%l_3iEb
z{r%+rW;FOa;0S&Q;lpc2);k$qT;EL>t9)G@`ShHvqL2)H`PbdS`Diq{I6oVn4o>>r
zxL^EBMm_EHPe-@YWl=GrI>|@X8kd*cf*Rb?!Obi$)<sd|tHpeBcRe~Aym+Q``opV<
z#S6!j;_Snd^^!a3`J(Dr;iOnhZ!S(>u4T-+gUcz=P!j+3dj7#q>8Hb*hUL?nGZ2%K
zZ7=6H>z?1&;2aq<{7?m?tE3|~s#xBh^<J1YN&A-#7+1I-Zbz=C?TFb$)dc%wc{6xP
z9O>UIZ9K)@`wvuMbtj@B#^sEBl<H}Fi>$3JH`eP9l^?w}!e1;d53|}v(s#S--u1$8
zZjBBEw{AYrAxLj!w@2J97FYf4h<EVPozZNg6^~fEJy;Ho!|?&Ok`HWVKEHZa85vGi
zt%YN~UOX$Vd$6sI{Rq8oH61;hk?dW~x8TNl?e^Q)gDlVX>PG)6s(|%+dH+0aeR?+8
zLRGET#fNG=pd0k(l;RuCi~034n33M)HaNoI{OZ}{cz?M{&)Qk^z^VNH?1_i$>EN~v
zh8TQX%xAON{q^vPG2EXC6hb=MPBkyC4z>3&#iI7Sb2i;%Ir8Ofa(8n%g7`E9sQVu@
zH-HZ5@NTxs^Ss#9?jRz?-RaXcxqH#9tBNHE#7mBS)^@ap2i@W5>iXv9_I@&*v8kOJ
zb259X37@oo)ugNP<@EMq@PUr}8u;NK!FB>L^?81IGnp-6KBVbbUiP0Newv=#*85e(
zYJPX|Bxr1;+>r}(PR?&&3bctK#qG)Qbyhm453Uuf+11HY^ob+Wx-Iz5>D81@N-O3}
zj&4NK;Y`&UZWQ_S#l$$<QgrWf+3<GJptt77o)bN*4Rz+TW7oYm@s0za*W?Q?jvJIX
ztDWeWyA9Kh)8dy7H9N2OH&>TO#QwaF9m~tVSBI({H5)jxx;~mktz$=i_XLhaJHk9y
zskD1p*H@3mkUC{Gzlb06eJ*-Df4$kDZXB?>IfjI!L%RdycZ1`5+0Rez78rETXZ8s3
z7!r~WY|jd2jgP_o7R`ToMY6$-JwRMt9hyezi9PPvkd~Xdyz29d3zzr$;u9=Q7DGPr
z>F_+X0g^<UNDIENIXqj9n%*+2ZM>QG@2z@@`}zTB+QTr<-DEnSFP6(C#@!*${qp>@
z_u;5FNPxY#gb3nnzVL0BO?~QaEmN|ydsAmE&kx$_-i=jDep?qE>71NhL58~?xk4EJ
z{_1@20XP6@_w?fWex}ori+nM?y*#UNDIxLN)LDx|PEmC(tq|hs+D=f&`e#>@hAg0B
zIlVqVdD#P&&fwy9Y7*A#iDGeoHMD1SdRM07GlMUv9_Yv}tQwYArU-TiqkF43*LSPQ
z<!P<Z9|-N8!KA(6b&EWv#ofh;CFq@z>H6H)DU)sSOox_{T3%ZG?hdYMoIcJExLRDl
zOpc_zv)j!b$~7mSURtU*y)YSab0AOj#E7sL%aOs>&fwa_MDfDkSlygj{mTISbhm&T
zn-le8dy4s`Wk}4hYjK#MQuiiSU!7U(NNY4_^^!hW-B_)8I_j&MI;VG*snnRqJ9BFU
zc53y@<slL@(@VpwEiY9|((IzahDY?p*^3%arYE*@Bybj&#mw-X1{N`9Zi`k$x~*=U
z8OCFEr9h;8L#qkI?aS%&<nyT(z~^pky>FvU?-qC3G?)@{zjvlwZ%Qln=eZ6cXQOS!
zJc3<azl>D5{x*gqqVLXDS`}FgDQ--k)aV;Ex6&I;XCw2oZ;wg^(sh@`^gtg5uW3ZP
z+h>-BsY6-aFK$(*vW)t2uW!>Ni6y~zau}GMZI`{L8na%E+R^NIrLt?oOlm~y?-Wxx
z;4|Ic>FGXg=o{K<B0Doo#aPjlden_4%Y6lTpH{-Vy*+eQXil+^=^WWek7J6vJpvP{
zF~u^I=C`+tPoh|o-%F|6lfv7)o(?wVzbb@{8%vop-Z6x3p9ytiMo<MRo6_S9oNI3t
zlV{uFB(;3VT0|QjtZsz=)VtN1V<z=W>z>oqy{5Pl;x=d&bVyj7+~3|p-s|0DzCo=i
z1>73Z{R%cDBRJY)O#03>;eI-AUJ$mrJ>j?**@MO1u0Gb4_N}BXZ)C@EayvSQ<n~^-
z+l6hHPR~X+O>y7#^Nd8YrtI*10h!^$)05DK!Rh&BW84>}AQ(fe*xzbLAFHpe(Ol@1
zLA{@gLG^(M;ifn*QoqB=diD&fL^}1!QxH_Y9QH+s4fX}OxTz1tL#_>DNH)@b+iWLO
zncXSfw-U2lClgg9XxGL4s3tO%^)K#f-Q%a1ka}g6&u-52u-g&4Gq|jsQ^@bQ4e4Gh
z8Wnmx&3I^Dq^AmwTtHqo3M>|P=W29BD(Rfv){VU;(upUp9pe;+PPTo9Re<$#(SS+s
zqE629Ti*SRF~f?>P^*S@_0VI^E9%<Hs#r}fnz(_r!!)y2hK?`?o3&}x$aJV%>Cjl*
z3eBv+bw@Q?E5BtvkCiAjVI?$deJ4Fv{U+xlkB;HX!8=8}HSsWsrsWS`7violJLDb1
z{lRAE(^k3R{TsUtIiESru5?Q|DO)tDukw3}J2oMhT_Wb{$nQ6HtWbOZPFp$vS3Kb^
zKs{T+7i|NaAYR%9#WwKhVn++%wtImYOW>DG2^sQ(yjjU1Y7^^6=72=>t|kC`KFf??
zDGIpzc5^$}HNlC3cglelkc;gGA$>K!m2<CoV0P}sc5-;Cgb;aZ%{{iG&X%RDnYMMY
z-5f<`Cz&sqsZF)U+HUiZY=nei$CNd;XHs&?T|M@Od0{Jz`Cc(lvm)!JnE{(`t1i=l
zNeXVUQ`NoKqisz3iSh!MEb3y;sju&tMzctu?sZL-G251}3T}%Vh64$*dAXe)!FueO
zQ65;*8!#@m@OeARR_C|Wm}euc5Z7xxBh!W|*5c{iLp&{N3`J5aabdZoTKBN}cTAJ`
zi=4$8Qtdfxk!_-rr{}E4+EbC+2w<dJ$6`o+9Sa=k%&JxeuUppLvludG0&t=<R(k=-
zE@k)U3G>#tytvt3S^3s>tz^`F=QTGH(wItE@5&CG&XN=ZKkbIv^z>SJ#;pb9MET3i
zP+Qr&`A*8pQ>|yjk=F}muQrl*+X9v?U&;BsEr41KSuy3;Q+b<hCqi_t2v4^%LOywu
zlbCgTCvep78*FCJPita%TM((fXwOJa$}e}7aIEJ<&lRmX!IgJiwDcYHT8{~pyq=Ex
z7E`7x2_3p8XP4J^um{Uza({Pyc_t(9zNoGdY$A^W5t#d*n(pDw3fJRfjHL=T&hM#U
zc+0dJmCeouXqn>k8s;rb8g&NeFabsMCaj!*FHeXG1$fo;;oEi}v+Bm1S^)t2XZvou
zqPKVlgG9YjmEF+p69e5_>Af*!WDI|n<|YJgcMk~)V|CX<F--*wv2vAGMj9ri^RD0G
z$V^+lU1Wjc5zaGX-3OzbwlVCn0n*)4=3zA=MU9w`Iizh$bzj^JrK(OZh!~YjoHtB{
zz=ti)&QHzt7X(}DG&MBKIyYBOSg+UL>*^6r&P;?-JS(#!^BOX>H0_=m2gNNjLcVE3
z_r<kbTa>D5fh)C>Apn26DvH(gs%93Fw~1Yy7=wj^4R=}bEiR1d(isi?^wc8E7G9}x
zc5}Kmw4)tu!+3OthW}FbdjC5+6T`<$nL8+0vm%ac`efynH<GY>%@M(?Vk(engi!xb
zn-HF`t1L*1P_i=DEFV#c+}c>m+pFC>f{=ncAJE30F}YLNAJw7pgDtl-%B;~RA4=EL
zd()FlkEG_*)lq)r=9%=4k}0YJjhPiT3Uvru3V|@9I-LrS=G2(N<sM3)2lqI*m%oW*
zx(ma~xh*C<n&B&ggEprDO0^20cA!w!Gn8=_7W`HMx1OtU^gxa7D-MX01)sG^jMSJl
zQ@|d{bjX7f+k7^`vgO8VmXaD<|7t&xF<Z?KZ_FN5@oze&$yBJnU@-wizkUNb!40@v
z3MbP@7Y3UyiPE{^khU<!R%o1uu4QFgUS|R~uub=543etI;C-{@Qp;~vRR3M5NkN&f
zn4Bq=apLi-CC?k^7&cumtWZi}V<#(#YNlYY;6qt*=U=TIn1Gzhi6v%VbggRkk*0fO
zDkQcN9egY4K-MfcLzHs|MR;r(P}ZG%(Qb3P)QYjU3|eSX*>}=&Igl#uNlE41ZJ1e5
zLmH}&^e*O9nPIJ`MpTVUguLR*7tBm^No^$`5bRJ&jnJSvwH6mGSV*HPy8DTq3t7-H
zh>8tN<<OW`-BaR3&9x%-QfxWUS0yC*)io?Lpa@t?Sfou?eGHWJq^VV*f>R?+b!j`)
z6s0ZC)1g%A#VrA$I@7XAw$<>03V=>2;d8`EM@g3=zrIo2vZ=?ev4o|Vup;R>_pcCU
zaYL*oX+Ama8^$T8?IUIPIn}}A1wlW%5Xk40Te4mmN~bA_sfshwdH_<YM?;?cun1%}
zt6lve!e4!f1Hcd&nA(6q5gJ91&BANbmQ(9!y|l}{^i&E+ensF6qzanVi*{F)B@-V#
zS<RZKMJD!!e#H_tSb|R+3}FW*V+0P=UhvGWQzO>GZMqo^mcBC~0iLGTxcoRPfI4bJ
zi#Zt+D)DJhSju1%g_Nq4tQBDvwAfC`THc+Pp+nrL#pH-kM>=E)BNaA;HiI5BVazx~
zRMW5{YzXLc2(7PDrPvFCeR|ejVaf3rO?&L9fdya1kf~mQie`GjnAS1Bs>-K>la3zd
z!1r~S2c^3pRAy|FP|`5f=^fxmZ<Uf(f@<-bsR;5t5fGIbJ+B)QW=dT})t0Ip)D^K(
zpbw1YBI}jT+CQ;AtRtd0U7d@uUh`p_8n*&Jiu&AP%i<g_aa+?WC%v*G1I%p5P1$`S
zhcd)Ks2*9|(N`0TK;}jmR`Nn2G8^?w8jzcR56nss$;I-m3PGi_0o?kC3#>C0!XwjN
zs^``Y2~}`~#QS<O_?nAx12&N#xt(BiqNh;S`85$}AfwJ#1<-V8nk1${kl_N)k<4(A
z*9#F{u9$a#6J;aTGoq8U*Hq)H%hB8-0!hy}tzim>;jQ!G*ZEaVH7bS!pmRQRnVw2f
z#WH;Q*7B~Wqz6U(tk2a6V6pH)&N8)<f;bzQR9HFF{1pNnNdvNn1)p+o1gzeJ6B%-a
z0`*Z>^XqY9NnI+3O#o5Y^u${EuHu`3oa#%69p^u7%R$c7B2J?E(^G5=ISTIZmk11n
zBeo{euhu>j*@5>@q&8cxx%`xMxL=*F4ajkTNouWz<0@Z!d_ZTR_^>{+voM4Xf6<eD
zn=Xjz3Tm;4V}(m9d74M>Dmy3a#8W=XH(K1d-o&)86K+CM6-<U|d3eLJ>BjW2l5J47
zysnA{hdWWh8KOxu8R=MB=%~r2N!0(UNlQ8{l4!!L$Oy=2r0IVWk;Yf7uPTcSGHdcx
zrwC~7^K5+szx{8iusa=ED`U(CSE2H*5V3+pgp|L-I+)f!o95ii-T9@vYQ<mpd`V_a
zXz+kBG)|$nA+)kTGXO$Y&U;VE5Tqw9196AT+S8#>NkwFu^50h1<!kt>Qx-Qaa8eMl
z@+Ehm%$+p(eqPq{D%i}BBBzI{hDzfv9OO#Iy6N~psUkXl54EfH%L}5eq=&|)SoCVC
z7A;oQAw$GCy`v`c!C>?KLDX~tK*@<;=o-iK&_q1>AjCI-sF_wW)1uaQuHwj|1l18?
zRciFrj>v4aqM}LBCgY=H#MKM2)r2)p&siS2nf$pVniiXv(o7<`zew5sL;tF&Ju0>;
zxI~600TJnh<(CmdsmZyzQd5xa7B^XwiMa?t>FfZx<kH-ub-}z1*q$RA{#@s)#C9I^
zOe!q8KCL6?E_mz#@K7-@qVLq|XV%`1^pj;Ys;-r%M(};f*C?ftkf_i6!9T6nQ3;ix
z)P&*#hTJ;}<n!xj73=Ui(0w`ATF}%D846L0UDSRHWPH|>{xX}bR(-ggctEQq#z=0S
z-;iWh>M2hNF$0uJWA;Zk_xE>KL#?O}M1BQE`J}|-O=JXH#oT2SxR}HWB*k+!S*@}P
z`6xPqQD>RN3K=rt9k^%NbY8=WN^v#E>9A~0uLM#!9qxu&;!Ib2$o1$dgw+-1oCbkq
zD3u9-3dFBQt=nX*n1Hw!cUP^&yg7@#r)o+X*ebSkX^qkW3(CO}U81VO<s>%cP>`eH
zRZK%sNsdfkNa0zl@mNC>tyPdKD%bF?m2%6o7qW9{9)TfC5};_n;E0c8Dl|19DjGzy
z))6N;{kM!UU==K3Tlz{PU`6!m8$GmgqIm2zRsI`Ldqs21z{<!0FBI80CauTnFi+GX
zUfR)QxRlWp+$$L{BnCz%WwZ1ZHEqt)RW~<GXUs!fox7`gyb09i@yd>xv4$el;opqN
z;Y+9xHAP6SJP=twGR8wkgHrBT{-){#)M~Y8qiNH{2AoDhB8=r(Otd4X{(&EBdw#M7
zQU@v`J#o5Hg$_{>SDuZKNS&15M4aSOOJ+V)a*h!ii=d1%Su-NXa`fRH#dIvhqau9~
z4Rv4+ottZ*-*iiUcZ&warM+JB*quyAAba+z=|z@&Ao~EVvkBMuOsYeqB=zpFq%j@5
zUi0h)nbw40SePx=_*7?dR)I#$l|kntblG6i5}B~g*1V-M3bjKxLUtphB<T-GJ##*N
z#k!Q4t-6h`cX%!-t48-ali?I<?7_Vf;!b94WH6DDO3KxmgKgEu8h4ewt3o!&G``Bf
z*uNPDGto_C@Sf&Erd&{iE=MO!>!>MzvH)0iU*`SDhdB+>v~6_9bXWPXup?tOzz;Fg
z(UU<TD3b5cKiZ<bxttseP|GXh@oWnv+5M<{C4sVlhICi;^3KgzgS|G0y%rvMSItNx
zwc`{&)MF(Q$=G`vbPiTVuBD`LSUJZ{!@nv8gV<B0msvbRMwfO=;7_e}YH~lBfiZOC
zDY&WZI;hl`I3JAC?Ep!GPJ$kZoF5_ablpM83Q0BKqiF}J4CU>p9#U%uK)HLrlyFCF
zmZEO${U;V+wIk$#N=aY7AcFywQ%W_xoZ=&E61sxq`G_Ffl}Ycrdi;7BBzA4)K*4$+
zBTU6TsGiKw2PiqUq6GIRI8`ZB%)t^d9x|Vs&<!YDw~OH+DRXQkhK#JPSW@pcEzabu
z7NQ~clj$1N7W=&q3@fvuRM-Zm{maUz2z8?5WCK+#(zp;$QifOAeho6zw?_=m*r^7_
z;M~cwQn3ZKr3pp0+WT|uPwmYRq>81!kQ_<Vw#p@MBw0xA06{?}a`ui-6m7<rmgpM^
zi84igXq4egWX*52vpz)YJodTt_-F)6@`}>#ObiD}?xyrvm^PL&$MZS2Y^{u2x~?q@
zlC^}K@9@)+gD?amqNiITwtI0I3!=%Ba_C0p{L>3WIv(`X64HpWbQ>8hp*CszR!C_>
zgyej>M8}n3gK+B`bA^#`wmp8^zae8y#7|OdT*%N(4hLy;SBe00cf};{n)+<pW1q;;
z3=&%e#JX}K2Z|JYQx@X`LF<B|y#r=Dz9Jo7I+rcizmgsD<?IKUagwXfX^b+F8UJ+s
z=PoTUZMsN>v9cFv|ABf3BA*}Gx@Oy{?}FSe@5tDAaTTG+y~Oh9)5-}SG8~lqljSsV
zT_z2SNtIZ4+cW8RBO&EFD`_KL8MdOuOb%8V9Bpyhr<_bZpt12xtlJ~g>oOysY`81)
zPS|2l6{Y9y=?*PX(_27omd*mPcbV>j4B-PGDeqWfEhZgzKyHUu<Xj#Vc4>TL+JH1W
zWJXp7)XBsMC<c*Kzkicc8K88O<n!qr>uVPa7Fq0C^XV-%^W1^r&9BJJ7djx6)-pOn
zGF(F3G8yS3UI6R`ClocyTWm(O?y2Rj7AzJG(Kc)A0dCV}v<}%?Ji~mt9KF#&hIGs$
zdUDE%#6;!V4&o)lnq$Eam8Drn^@jU>Bla#o8ZPm5)aEM(Et@U_lnq!M>X95%(XBz`
z06k6~NFgA@NI7a@!*eN(2hj*}428tz3H6ZtZKRX%&pRY)!5DxM0m?%Wy#bDlHqq`Z
zRdXCn%N#=zzLNZ4={$0y5thc;fMw$&bB{PWkb<{U8Bjo`@sGQii9}*B(}>4G9!kp6
z8A2KPh`m{MH^N1k@Xx{}GL`x;fmAyL#UsaNM&g96YUxV<1z5(vS#uDIHv>_cCk`?a
zN!mEkr}z;A5cMwsBFEuJ(v_ADdp`+rA_=VJRqNOyEYc=97|R{=kfT>(nG<R2<J_v8
zog-F93Ka`qDT{QV)fLkJMt;c8x0%@sm(1&xx)z}<c%IWSd4aH%=Sp06iC#1XiXU-Y
zS8sHnHYp!;N@cH>TI2LWY*%G&PsylVGnk3%RQJNM)ywizcw{7@(l4SED1O9l*2oVz
zQfAa>g>OwE>l@YUl?Xve(Z%l1!@(UH48<a`*)^3P^0t(8nr$w9ujsnU<X$qalOn)O
zwuqPP8%`vINaai?QgY6hbfm^sq+<1n@vSS^>Ld0xQscg-S+@`0EbFi=Zy36YKmp}P
z{m`y~AI&C$Cq0rRx_w)h*xzU2dscO<9ey~q&B4qOV()3^0=|^Bn%@c;mYHQF5~a3L
zh+b_&+(XV0aTCEDvx29C?8%bU$TnOvZvw2P+J_Cp!K{l)qlt1R1~Ypi>Rvx7Cz5kI
z4XzWZ+VNu>`QXA%=1*yI(IJ{B7sMka<@Z@kYL95`sT{L9hVV6`wES-8{g{cwx60m4
zKAQL;LR4HnAcR#$F4}yXYP-hDBnwB$xUA6uvurx`@y*?@z!DwEF%J!5tAW^7R9o?*
z8uB*qL)mjKA4%G~m@HSz*(F!)+flxzw5%H$BEHXJd?5&ij&V2(kj(%k{pLVT?d@-i
z^aHkzb~k%2<}t|Ls*V1xLpkg8dOhh^v~Ns9N#omkFjvlXjqHHPGclhoV@Oy;PC7PV
zvH6kM`h_GvCr#sz2LGy5I*2M9gdb8N2#dNI*?mfM#gr!ECO;%S5c#ZFhEfC<^N8-|
zitL$sL7OEOlhdsfn#Skt`9TC;W^M5h5yk2l=T_HVaR(~3GZHB_nH77NAFrY>Y<VvC
zEuO^)KvVpxemuzBR_HyHAEIwPEkDfI`<x{&Bz8EM#8GQ(I#B{!(q9%o;hE6|<%h_K
zqUKK~X2igOlpHeuQTb0O<Z#5Gm&EEQ*O?suAP%%qP^&e?3)u^?lj>nILXnDZcl-rE
z)`TBY!0G&lbk-wjRg}K+yb}3RWa94lZ}X=4eU^y117+ECSYAaLVg)F35un@#Eml_U
zZ842COPv(Q;AE(Py#tQeDmfob@{gMUGNg`m(c=3oFw@~%ME{EARWbyDMHhU<^sX&P
z2ee)gylI5g)Sc_6mKwYO*|EsfdaU)RXQu|S`FE3(RHh9efyC#!?ZHg!$-B2f?l(>S
zD>>&x^Gl@b8Y6Ei3K>ViGDO7kuXb<47H`&k4TnK6qar+eA(iP)$TKmRVK7@?$i>NY
zF|3@Cp!rvFXcvbPGVPaS1j_ux?e|}3-LATVnbo!Bx2vq>RdGTAL0b!S)klr%aA>+O
zH}9rj;%LfGl%exDm9cC7ZWERVeAcyyExy}ley*FxS_fqe79}GbE4lB~4rphi5}N-d
z+1)aKcTIQJlUV{WA5QMSPV(F3UgO99Fn~!9zJYFNy+|(V8oOhPDc&=q$N|0w*+f0D
zaWNrmqE=VLe9`PuaQHfsMfS}Dbf^ft?U|T}^w^5oVHp&~LgI7XQbS-7F_>wK5h*9N
zJz3--H#5vf<UP5PCFWC$03~ch5&aG+RWXZ>fIjxA+Km<|DL<)VnHl1_1CH4ZA4ww=
z8m!x`8Op>)Z%8^y#4slf>kZU`39`IPdI3)xFexb{dyJzb|K^%j0FK%$9Be7R;+9P)
zmNmBjmATu?7^{&3J34)?*5i;=AUX9zjHMj4aHpj`)_ayz+e9F-<A~Nlx0Y9l&vncA
z1wz^Pd-P;-5W&Hhsj9Zh(KJ<#awP{@uclUbk#*!vAgg+x;Kckkx=^0hIGu-s%>X5x
z)ZV@&ayUpQALVe6c4oO>GTl%{j>3uBm2G7EGi;Cj?r-#s{bWQ4%BD682WQrNI$PAT
zEryv`oV+IAv5}S0>}MI?rJ*gkDF)GVQsw5+T5XH@p5^6g6Q>*a`t(d%J1j$$1PlwM
z!w4k`qMx@$Qts?c=Fio4C8&=sXO^h)l@U_1fKU!V<X42Z#((D*GRs}%-)BiWMvh!T
zwFJzkiz#hn**-R1c35JL<R)qb{RE(#Nr>Sq>@<i~JjjHn=CR0V*qOdtzu38nX*DIT
z;`=O+y`WuM{<-edvgtY53295b<fm~-c9)FPvaJqfE^AyK1&+BG^0N?(AOi1gTOz+-
zaeFU!-ao92M4r811}Il@1NF9;rt&j^#286mh?s#Sk;_x!@EoT6&&&Q6e#r(V(nsLx
zxGma;DR*ilEiPl+2P-jcI(I_M0OgD)2e-yo#x~Z(7Rj*!Rj!$s$>n=n$nTTR<B9_*
z-gJ!F8tX$9lr6;W!@s%K?sMH*sloS!V^CrXbmb77s+LQ!O%F5KVk<YYJp<G(l_1IK
zQWfs5YPV=+O;OXPlj(kZt;O;x8RBqSK@4VUFp#%pE(kH_$`zvSm0Y{O<bediEn<{p
zOiV6Rk_aC6+Wf*DSs#J5%O2#Y9cO#6i0pq@B<J5s!eX0`RDL^}*a*4JIotb1dhdKM
z1-YRCU0^JiVmzZk2l|{yJBXCzd$}jp2c6fP+QXGrS-X5EQhKH|S4x_5_R&(gaTFaY
z>I@~S1tllxnybwn=-?$}a+2%X{0n!fjK{e$d^v>F?O24`+m?7s>$<*+(MdTtWuB1q
z%j4`I)-2~7*Ru##R+(S6#PvwUWdHEQW|f)YU>YET(tIru0)bD4#84oESAQW>AIa88
zYDp0_=c&xnkh3{Le3#L|l7sj4z5(j`*0p+~0!B#56(5D9<`yT6+A`jaP}aPcZbnD$
zj6}Cz7HQTTxZJ8rd~YI=A2=ubDrHxKS5KW2C&{98Hd2y*pCvJuS8)$Y23QfwYD?!)
z1_i-uuCSHQ*eAy1{wi|ou&$6FI@2p<a=-X=h41bsG7f>16yImr^>f|CJ!*lU%2z1J
zOt&;2WS&Yd73c017<3`vG>J(136xhYkUl~Yt80sIqpQuJkY{{8-5ktpWz%K)I*d)L
z)~ZjVFtsALcBYA02tq04c{J$CpXYl`RTv!QBpaNM&Ie+BSvnL!HAie7f=aFVbWUya
z1Jcy$ZfcRLf~YIGU*(!<OPPBl(?nzv>UtH&i)#Bj5;EI_@t)5+XLs|(ayh>jskSlz
ziu{1@v#^MVNp1PLZebb$3jf$-BmV09(=>1?-N1r2K`mAl>!e{&D|%c`rq$%`M#QOW
z#CPw9z3Vb%YQcIJ>Q_xk`Gvclu|8d_N4AoK+uL+$A*gqy(yQqFcp~G4dbdsK{?QSk
zoX&l!?S<*=QXyQ?p0RU&E|?}qPAEi6rWvwxu~ZL>5F^moqvT8!+w-O)H4<C@BVE=x
zch{j>xmE0X9)(|f*-@D_V!Yo&z8_4^KJ@{cX&UqCOTMHdHL1;}c+JmsivVR^E7W`?
zUGuFLIIw8}*_p)0fS^X1rM=FhC!Jmh<?u8LORORgQA4$#7k2GAXIdsFMX?NDGSQXu
zbWoxoX1R_TxW5)cqX&)b$#nXHdK(?Fs(;PnJ+98apgGOdm7|w}<WSTjyyp}7!2`Kn
zjro0+DW6vAT2s87+SXvE%}03kYHYfDgxtD&O=grpwgs)%9BW6oOlne+G^#vaGC#5>
z)oWkZi=C;1g0FRq5R~}l8f*wAn=U=5R1UAO#}^`;WMC=%CoXu(A*XX6Y8WY^J+3yn
zQ~P=qM<B|*Bnb}&s)x8`d@zR_2dJbk)i6*p7k1yW>HKruH5*<>^JzAxC++o`?eD8*
z1*p1G-;T1>jY{IBLNpNGFpdA3=<a({&GP`Mb)P*|L_r6NQL@$Ny2ZRIN(h+-x7w0v
z*`%W~HNGJ6S(w3;_0c?_sy1CJ3W)rw7i`v6y?2b0RIaf{645ReDkb|1VF`B#cQupq
zX;_GnC+Wz^2rMGCBWtF$UmA6w<hrOeQ&&TTPY!7rLsim&oW&@G3a8Nc7Q^%~7b+YL
z*z-@G`+C&Z5wVrzW3O1MML3vk&=UwHrb~FcWRee}N22+uw8gA1soZd48E7>!ld>Q+
zsP9>?qB~4s9Ohh!BhrWs<jQ(v925%{BKEGwZBU3$@yh4~f+4$9l(mK5^i(?uRGaGM
zD$Cfl!4DC8UeE=(v?e)-Uy~Fq^{rwWS*Ab^aV}SYA$8V7T4^0B#0o{p3O-k~#quhn
z!>{RZf>vopGwJ@osY*$uo6D<EVKJi6<9W6eY$qcyHC$XXmPa55I5YQuS=DW@Wx1<7
zd8X!b-OL=N#(a9gqrqj%%oKUHS)o!UYZ}kUu3Z0$e{}FFR3&}&oCHj@MmNTkCCYpK
z+WR9h>QVTX16AD662@!-5`%|>4Tou6%y?3Y18VKy0qTz^Bo%t%-l+PhDTz#RwB>RI
zs<3n=2j29qLPf_Rz$BQ)!@tte4iw#D#}%^7j0gu?8(y!Mw_@a+of$!6?rWrS?i)sz
z#06Kzg)C60Xy8wJ!qBXV!b)U3WrIg3K)1iNGSmzDogW3t_&&=ry6V2TwHts42g?N+
zPNC$}t3ia-J-aO@0HV5qGxk+2mC?Ii(&(+4O{yO{q)K6toF$b2e4MW=c4eX%G`C<=
zor)i7mvk6kL>h+TC(@e-xGOf|x56)2Xm)dP+J`*}PtGpy=5izl1pq&4u66Ds*Pe3S
z;9AGps}`yVGTly8&Pufj@>G!9o@65_qtITme9nZE%2bZ^T$i)DKMx068#p*}FK3hc
zyZh-}1}X3%90mI>km~>ZV`J%1u#`?TNvu_(C0W>+WU7bJrxMg|*Xfx^B*yk`{vNOl
zLGd2xQ8B~8lejh+rW~x%J|eK;-~oJ@C=Jq0tcM<*Hmw)X3X4wOXuHYeeK!v9x8#Ct
zq{NB}DKB1KiE%nhttkt2WKIXb=HcMXnl9PEjCH~DXLU4yrR}QEr1C&~iEH_*5+>;K
z|E`Jxh#l@rC_Ddlb(9YFzi$%>$Y?+{zok90!lpkFssc#OZMyBtHgjY#sw#jJ{bdFo
zEl_dN!p1eg>`QgApm9UFcLt<DQqO_nwbMDBFE5EuOycH&O+b5**g2nYif@_WU=oCY
ztPVM?SE5n-%je^bwGL!$EMTHmlQyX<V6TdF(x|1}83J_40k^RQ{Vk_4feJI)AtGt@
zS?_M)x_`d7C2==i&N2{udDXTI5$woRV0X>G`k<!OX`F>4>#o#-FuEgVqE{0iWQVnY
zhqZ6<W?No0B86NnNY%RKQ|Q%WJTWs8dG^9q3@MgOx?mz!&8c(oP?0$qYGdfag<R9a
z$Cg?^ng-4i_J(V1p1|Hx@!aq}JkEMuHSl0>nV;*PkXQ#UcN0;(T2%$Za_a6tMMfBa
z4yl1(${xf7Q-)}Dq0%i_{-hqPiP@hD&ekWXG5IRKn6@=c{eqRfAo{2oFEp8=;*Bcc
zwC3WGs!#9ozM%0<RJfEaVpoI91MLY3h{)L&q(EK7+rYc+E!94#CLgi4&Ch=t3{iGU
zYpXR+bykxDWc4RQAzr9Op*-xSQY0Z*z{EX5+UhKoiyE-~$H-!lLq|vF6&)4=-exwc
z;K<@!w%hmurO+Nqe)v$*q?qzS$XZ*_t}?_0!{?C+XRDj3N|=Dw%Z$XWAl4Snl+HlT
zi!n}S?L0sklHc^Dr7{8l1r5U+3x5kfOKIY)XE*6iC+e$`fMjcz)U40lRO23O`*yax
z9=LeY6PvX-GD|(4b}x**AY4)Sli!_6;Yh4}Nw$I$N=Sdc&B`X7I>FvDzSAo<&=JjV
zb19cwyLPu4m$!i~%P1`l)#;v^^)But{TyD!{ASqI0RST!DV7N7R`Ny863=k0c4R5o
z;vMxEyUTvVbn^=Z)4B=T8noNrHtlt;v%9k1@akU7cjWWC(ZJw_nVTn;>nibBwVGnp
z-%e&0glC<*9;1>1+tUV1c2v|1pt9u>+risd+O+9QYaH3>4==9oCbRisv6#>9Z?Dcz
zd(v*W>a55cANeQR+_!Wel}pG2{9R)y4Bw@2BSBb!j`ARY9V;=?VsGqyp}QPZIah0x
zTs>*0H#i**&xXUnNiWlS$`vx#Vu`r4YG&K9bVrR)dC<#nv%$$SyG;wqnM-2w>zanQ
z0NAF8`MK_?&5#!GOoht^(w1l1!rAq8tLZkL&6=GX6J<-Se_J#JLLAnb8E&y!!P&Bq
znZ2+pLpnyX&|2<>qDF3oke~V%7;`Et<JZ~~a=kKgW9q9YpV;i6du^5_5BzI=u6w;3
zL%J3_a^bDZ1^%07p-F>vq?PBy%Kb>4RTrDD5^(jWoeMR`g_?X*kgXnI`zKa#e?7B|
z`UaRiJuL)nkS?c={Lu{)H&meogim9o*5>u=;%eJ1);i_{=^+OE8ybj@_2dC|g~qgY
z18UkAJ1Mxn$+D~QEuFHuRWL{{P=hfB3-M%fMWM&ycDpfyJw2M!k7O7WIMglkbKS6f
zM31~1YD}%cB~VMGQ>J?EeygcfHE#kvhj~0YUD0u5dYZCg4J}F16Dz_F0b>zMYJ#!X
zGc!no^YyKpkYw_EfWBX<Z(R@6%)Ll4-qaA4^9WNz3{9OL=TPA(W{tI|;i_*-%Ry2j
z=#~%FK+9vWDcvhVw*?%sR$>u%rq_e4TRT@ClumkF)8!ygNUmb=ZGmi~miY%XAtbzu
zKOzJt8g}4IH9PGQX}e{{&{!@95Q-`5xsa8hL&|c0rHu{K`Rrn5-Y`+FHO2C}HlLuX
z6%4sOD>^@9f<#qa-H8?Z!A2B|7Ne<?Te}U#Oh)tc`U9G&UWXjNueL}AEX5dHd&Q0+
z>wJFMYy!F$Go?@ct8zk`<8=5dGr<8-Sxq)LTK#L4uIZZq>lg%{nf?T|oNp0tSeJ4`
z6GW1vSHmmj#@i05)$Cg2>Bkz<{^iuz+|#|c>mWZu-}cPfFT<fytR@$=hCMyKu`{dT
z)fp!eL?E=bTJI8_Q_I)XlDf1;{{mL4`R&Dt4r!(Rv)fr6Hy}}WD_?V4+MDIAe0s-_
zb+MdYpBXI4PDb~&+<?hBX*~4UL27;zF?Cbt#=%@USB+-0!?y;Tb9;Gq(hVWeH0$<<
zqnoKuS_@_P&vUQ?^LvbFTtF<JPjIn8Cv>bd>kZDX?q;^#z;}w7ib?AERxy@Sgs;1y
zv#nH+Dm%Ab4Bwt&HJ`$q!R6&>ba{1iKbhAz1YT%kL+eo8=YChMvhdi4HZ13pyBlo7
z<>mG5{d7?)-B7-mO6jn^2F_z0TcB>t6Uj+}?5ts$IkYHWt@6CafXAk99jVx&A<acQ
z)|!)u7@p;>4Yo@dOBVOic0l-A&-wCLU^8y)srA9K30dQbh0~$Ape`cW@@)2`jxK8^
zY#wPvHCrMci{)~$AyCH{a^@pm`xaM5P`XfQ1}C@m3OFL$e3r9?F<W4Gn4+)@Xj9*B
z#vh+9Z}hn9M6E=J0rMVCi=kTiiV37g?@G($X7p)^l}hzH44vCU8SE|Pi%ah7VBOY4
z(Y$TKzJ<J=gNJ^gBA_sfu}}9Z=354HEKK*k*S!&$B(%S5KF_V06KimjU+smdwE?Gg
zgdpm?(O%cKDWC4sWA<tteL1ZS8q{JQAFM=bj{|J2N93s?wEmXoYT6f&Frpd|c-T!u
ziY5O_c}uj8QS9VyM?+Yct5nP{S?!(6X?_!#tzrwL>F*>WhR1#kQn!PdHjbvEG>Eg6
za&cUBIx7Ui7Nd5UG?cPdOsvfXtY_O>k;TDR=r**Z#iOn{fh_3HFQG@7fUP~|*Nyv3
zm|*nHp<L60_?QgY)~+u%#DO&~N57Ny&1rSc0&-Q%YU02qI}S3}mKsA$V2IT#(%waT
zM}Bc>r(PbN=FJskC)cgr_hNEx<?=!Wa<f{;!UIk2=zK+l&cEGIwlV9Sx3Y>kM6-4H
zw}kS%zn%W5Rj*p!4(paHTDzry@i<V6jSX~=AvXB5dkPaAu0PcM$!Ax?7t0Oo3y|4f
zJKYo-wVK#@?yf6Ydzq`?_#U0kPHI`!4dXif)4Hv2U@CNSb=I$u@;y*I@T+O}<m`G<
z6OYD42dBN-u!rgB?((s)+BT)uun@ero7#M<PVe;m@)jcOc{wa8^5uMb2MPQAj+n8j
zt@e2zq%dIviwz*cUbdkqR<P9%%<2r9q`PKPNbF?3U)$2583E1jPa9NXr+0EXJcp@|
z>+9>Q%hCDS=}GSc;YCTUw9_A)o?VQt$~Fv7s~NVkjQH)^(R(>jA>P{d(sr`!9R@k<
zG|f7lEUQ~N!3)38t2A?MXp!p&{<7(vEo<E3og190wYuK0Ev{;H*3NZ(xG!d>#tub5
zsDrsyku<3hdq<Y!cf(rC7T^B=<E&c~aLKP4)cUTZN$aLLU|{!QSm<3_-txV)Uqd1J
zz2lbfHWf>4)d(UoIn#47o1p#OJ@1^^`QebEeFW)1^3_TR?9hGkK^yG-J4aSy$f36$
ziygp_`taxKx_0sD{*8U{5Ympd4AOZ#Ir#$j;oD(5*REpVNDGJX@F=|ih%jC*hrNyz
z<j)bM!!`WO*dMp7KEES-IlllhJrN2u(F;eFV=vrJlA+p?u4D(~=jGGO|KElqo%34R
zfS7B;zVip_E$Kj~&qt1|^X25yNTfbc<u46PI=GsZ(JexR@^o?NQMuKA2njSMlN77P
z^ycE^1B+ByE!}Vr6Wtrq!(r*c4y&g()M-Ah37M6>0)F%5Vs>{kIv);TC;D!gA8rEs
zFmI-P*!ySRoKvH-d5_iBY&apruQ@I9)nYN5&8E}I-AJw(Iu>R}hnse~C&P;?48zyC
zRGuEIYmw=EOw`hW@gdS0zQAo<Z1jPLR62tTSaEQ5eS0^Vl3AVFHZMj`JLd*#0Bdov
z9*EC09<#F?1NQ07bcxF*ie{lGTV71mx}0NRMPa6=w`QcjL`nXx)KV1+?PZ^DoBzJN
zc|u)Pk*+(6d)Q0r8`o+Xa0Te4pXiSk7|n~fis>_~gLE_;)GsrQ=v8MQtbp{kQO(8T
zw%v{h$LNLdxv`oYjEW2K<RBX-AEOl;U}opB4I9rkE?nPG*}jiE=aUVNU)2P@clN#&
zKi&K0*ITPru@lHFYu*as39#;5wB!i;?9~$>cBm@UX8;)s$VIWZc@g8R>}=8y#HkSG
zn`a-2TE~aeYv)H6>f@2eN3E`gba1;_YduA9tq#F`?ziK|>REi;`gV0Lrj237_3GI*
zYd!LfPr5CFLoYC=BhC7a1CmyoV>c4!nI2}NO6A%o`Q6#ejAmz@{`pPKUP^~p8uUyI
zX;fH{=>C#3k~7#|`{H`C5GxMaeAMxosJ*$`^sFXoRV?l<26bydHp6|Y62Oy_!TIP4
zwqJ2O(J!Xg#`iLw3Y!DelNp=!uI6`Far>eJRB~hxu)$Kd-#<ASz|sHE)8(?^UDz%F
zXLVrB!PUiwm#lwehCeO%9!x@A!K#T1ST+HZo_~i^o=;29{cD3o2Os#diT!Et3gMLk
TuM~Ktz$*n_Dey{xHWc`O(cS1K
literal 0
HcmV?d00001
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf
new file mode 100644
index 0000000000..1f79332020
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf
@@ -0,0 +1,10 @@
+// /** @file
+// Platform Logo image definition file.
+//
+// Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// 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. <BR>
+#
+# 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.<BR>
+//
+// 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. <BR>
+#
+# 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.<BR>
+//
+// 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.<BR>
+//
+// 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.<BR>
+//
+// 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. <BR>
+#
+# 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ACPI_PLATFORM_H_
+#define _ACPI_PLATFORM_H_
+
+//
+// Statements that include other header files
+//
+
+#include <Base.h>
+#include <Uefi.h>
+#include <IndustryStandard/Pci30.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/HighPrecisionEventTimerTable.h>
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
+#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
+#include <Register/Hpet.h>
+#include <Guid/EventGroup.h>
+#include <Guid/GlobalVariable.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BoardAcpiTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/AslUpdateLib.h>
+#include <Library/PciSegmentInfoLib.h>
+
+#include <Protocol/AcpiTable.h>
+#include <Protocol/MpService.h>
+#include <Protocol/PciIo.h>
+
+#include <Register/Cpuid.h>
+
+#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. <BR>
+#
+# 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// QEMU Video Controller Driver
+//
+
+#ifndef _QEMU_H_
+#define _QEMU_H_
+
+
+#include <Uefi.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/DriverSupportedEfiVersion.h>
+#include <Protocol/DevicePath.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/TimerLib.h>
+#include <Library/FrameBufferBltLib.h>
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/Acpi.h>
+
+#include <Library/S3BootScriptLib.h>
+
+//
+// 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. <BR>
+#
+# 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.<BR>
+;
+; 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.<BR>
+#
+# 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.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _8259_H__
+#define _8259_H__
+
+#include <Protocol/Legacy8259.h>
+#include <Protocol/PciIo.h>
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+
+#include <IndustryStandard/Pci.h>
+
+// 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.<BR>
+# 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.<BR>
+//
+// 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.<BR>
+//
+// 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
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#45306): https://edk2.groups.io/g/devel/message/45306
Mute This Topic: https://groups.io/mt/32816099/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
Hi David,
Here are my comments:
1. All of the copyright years need to be updated to 2019.
2. Please remove " Contributed-under: TianoCore Contribution Agreement 1.0" from your commit message as it is no longer needed.
3. Please rename the directory BoardX58ICH10 to follow Pascal casing: BoardX58Ich10
4. Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat - Is this still needed? Can we just use build_bios.py and delete this file?
5. Please rename Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/GitEdk2X58ICH10.bat to follow Pascal casing: GitEdk2X58Ich10.bat
6. Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiBoardInitPostMemLib.c - Please rename the following functions to follow Pascal casing:
* X58ICH10BoardInitBeforeSiliconInit --> X58Ich10BoardInitBeforeSiliconInit
* X58ICH10BoardInitAfterSiliconInit --> X58Ich10BoardInitAfterSiliconInit
7. Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiBoardInitPreMemLib.c - Please rename the following functions to follow Pascal casing:
* X58ICH10BoardDetect --> X58Ich10BoardDetect
* X58ICH10BoardBootModeDetect --> X58Ich10BoardBootModeDetect
* X58ICH10BoardDebugInit --> X58Ich10BoardDebugInit
* X58ICH10BoardInitBeforeMemoryInit --> X58Ich10BoardInitBeforeMemoryInit
* X58ICH10BoardInitAfterMemoryInit --> X58Ich10BoardInitAfterMemoryInit
8. Please rename Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiX58ICH10Detect.c to follow Pascal casing: PeiX58Ich10Detect.c
9. Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/build_config.cfg - Line 2 - Please rename to follow Pascal casing: BoardX58ICH10 --> BoardX58Ich10
10. Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.fdf - Line 295 - Remove the TAB character.
11. Please remove interspersed trailing white-space from the following files:
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgBuildOption.dsc
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgConfig.dsc
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgPcd.dsc
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.dsc
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat
Other than that, looks good! Please send an updated patch.
Thanks,
Nate
-----Original Message-----
From: Wei, David Y
Sent: Friday, August 9, 2019 3:47 PM
To: devel@edk2.groups.io
Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince <prince.agyeman@intel.com>; Kubacki, Michael A <michael.a.kubacki@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform
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 <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Agyeman Prince <prince.agyeman@intel.com>
Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../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.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiDxe.h>
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/X58Ich10.h>
+
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Protocol/PciRootBridgeIo.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PciHostBridgeLib.h>
+#include <Library/PciLib.h>
+#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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BdsPlatform.h"
+#include <Guid/RootBridgesConnectedEventGroup.h>
+#include <Protocol/FirmwareVolume2.h>
+
+#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"<unavailable>" : 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"<failed to convert>";
+ 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. <BR>
+
+ 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/HiiImageEx.h>
+#include <Protocol/PlatformLogo.h>
+#include <Protocol/HiiPackageList.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+
+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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+
+#include <IndustryStandard/X58Ich10.h>
+
+#include <Library/PciLib.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/PciExpressLib.h>
+#include <Library/PcdLib.h>
+
+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. <BR>
+
+ 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; Index<MAX_CPU_NUM; Index++) {
+ DEBUG ((EFI_D_ERROR, " %02d 0x%02X 0x%02X %d 0x%02X %d\n",
+ Index, mCpuApicIdOrderTable[Index].AcpiProcessorId,
+ mCpuApicIdOrderTable[Index].ApicId,
+ mCpuApicIdOrderTable[Index].Flags,
+ mCpuApicIdOrderTable[Index].SwProcApicId,
+ mCpuApicIdOrderTable[Index].SocketNum));
+ }
+}
+
+EFI_STATUS
+AppendCpuMapTableEntry (
+ IN VOID *ApicPtr,
+ IN UINT32 LocalApicCounter
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE *LocalApicPtr;
+ EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE *LocalX2ApicPtr;
+ UINT8 Type;
+
+ Status = EFI_SUCCESS;
+ Type = ((ACPI_APIC_STRUCTURE_PTR *)ApicPtr)->AcpiApicCommon.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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+
+#include <IndustryStandard/Acpi.h>
+
+//
+// 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include <IndustryStandard/Acpi.h>
+
+//
+// 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/HighPrecisionEventTimerTable.h>
+
+//
+// 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
+#include <Library/PcdLib.h>
+
+//
+// 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. <BR>
+
+ 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "Qemu.h"
+#include <IndustryStandard/Acpi.h>
+
+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. <BR>
+
+ 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. <BR>
+
+ 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. <BR>
+
+ 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:
+ <http://www.cs.cmu.edu/~ralf/files.html>
+ <http://www.ctyme.com/rbrown.htm>
+
+ Copyright (C) 2014, Red Hat, Inc.
+ Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <IndustryStandard/LegacyVgaBios.h>
+#include <Library/DebugLib.h>
+#include <Library/PciLib.h>
+#include <Library/PrintLib.h>
+#include <SimicsPlatforms.h>
+
+#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. <BR>
+
+ 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. <BR>
+
+ 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. <BR>
+#
+# 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
+#define _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
+
+
+#include <PiDxe.h>
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/SmBios.h>
+#include <IndustryStandard/PeImage.h>
+
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/UefiBootManagerLib.h>
+#include <Library/BootLogoLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/NvVarsFileLib.h>
+
+#include <Protocol/Decompress.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/SimpleFileSystem.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/S3SaveState.h>
+#include <Protocol/DxeSmmReadyToLock.h>
+#include <Protocol/LoadedImage.h>
+
+#include <Guid/Acpi.h>
+#include <Guid/SmBios.h>
+#include <Guid/Mps.h>
+#include <Guid/HobList.h>
+#include <Guid/GlobalVariable.h>
+#include <Guid/EventGroup.h>
+
+#include <SimicsPlatforms.h>
+
+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. <BR>
+#
+# 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
zcmeHwJ9Hz-kzh@gFoN)Qu|weq&F~F*XbyPdaEHTfE*dKcjU5ohf-&!%BU8pXGG)q?
zD^tc9GS`(UQ>MIoGG)r#cb?2OW$Gd_vnu0Pg~E?y>sT{Q)F&%4G9u%Xk&#)e|2h0&
zn&2`0PLf>1@BjWNN&Xl7`zYzU`~UYcP5w_masS+n@=v#$bm8A8pL~*ZKm9cM6#l(=
z^C_Iaf!{aDCtrS<d<p+Pc?<u(e4D(*e{bKy^(^^xHcMvkZ-xI>tK`$wx5>BPew+N{
zCqGF({r0EHo1gqN`6>SUDV+cGXUUiF?`J>zS@QFr|2+Bf=f6mP@rz$1Z-4R2<d?tv
zW%A`Oeg)^hN`Cb#`2FRtlefS6b@J<9|2p~dSHDSq^PAr!Z-4zC$qfGe$A7@@Z+@Hn
z_P4)H-u~uyaQ?gGcfW(*-~K-N{qKLDtbX^0<PU%NLo)l_AL0Cu$shj+zrX)e@~1!j
zDf#vfe@_1V=RYT_KmKR(E&Th>|AgN^{U!O!U;dK(*MI$2^6j7hn*8;ze@*`Ox4)It
zdHsE*z$*n_Dey{xR|>pR;FSWe6nLe;D+OLD@JfMK3cOO_l>)C6c%=ZLK$`j}9J%#+
z`g{~f-@JKc$n%k3)||b2c=-M+LnK+A>$>;;@$vEfKfY?L=VAb__wxr}$K&JI&mkaS
zw~kS*1G~9@9j0;vimRVfxy_Y(?c(tf7y|!~-77nSYEzvqlcpIQf^ZIl@W;O*3M7fT
z!9kZ0_+7Z-@1+@3FK$(@q_Qx*CNCLHfLrh%DN_M$JaLeE@0@S|JKldEOG8tTLJSzc
zYJ|Dn!`@e*DIXr+U-e-^H5^DwWD+9bE5=`ek8z`XKS_FDqrkua>L0^f)%(?nEBo=A
z_fYpY?}i^&&`AMu>PnMqa+)M3U!$^re1FlY5cqf;0Cy_D)w70^J`w{D#QyQ|9Rf@{
z8kVb`(W3$AHjlEeUB&Ltb>`mu&NuNEoIQM&cK+Snc~b#~A`kH2n~2dD(13?{J;ulG
z|Id&fV>kskN%9G{)3wsUdQ;W(-n%jm@Z%%a^j$>b;a#Vy<Dc-|$FJd0z%bzRz4!P4
z{sCjp0*YfS>J9)L?rr`_zY37>O@Q{_-78}U2meqcS?f20ZdoD)$&5I7LUsP#5!2mA
zEIv!W^NqXXbtyvT1i?FFELrj6Q@p|h8in*2V;#tu|Ax1|Dk=1pD}m+Uwxe4Bj5U1+
zJNV<fsLOyKaN}*L9!@<z9mh8h<ni$wkx9P7lK%h4Z%*B<7Jsrp4EO5e<5xcS!ohMF
zJ_0O6y=;Bij258V7V**nn0p+qQDwP~>Dq?`cmO&E`M9W{0!H{GGAQ{1E-QX`E<5s}
zixRkn@-arZCEI?0@4(@!dEW!@f%90CZ#9t*CtDBKkZs|re|+@#d>x=TP>&8u37Fif
zP;WRXRfWgu@yZqbfd>-qeS<tg%t&h+Aa47}cR8#P>jS!=`3l7Lc);J!$~z?;OIihj
zxJtjk;$;D^S?~^kMG7IeoW6RCcaSk~q(8<IzH0o9OmK=1x&^#M_~DWL3Z%@l%Bx4@
zQb6AQ0u=1$cz8ZPP&8e|HGe+wWG;a{KAZ!dmCOWS0ZA+r)prfR?Qf3}ZHIRt%l`lv
zzO}JApCzUJ@O1P=5WkZCa0l!MTn7vs`QQIzf_!;+1fA~c0XAemf*X$MP!igY&BDW#
zd-rkbYJv*{4EhQVuCL$*Dm%m{luAOUt{}bp7>!hUi69=~R-0q&3OmUD4Bta0ky`-E
zBMCQ&c4z~>MVXJ@dBmalpL?R*f<qBnTQ#X(J_tX?h<1tLTfD%Bj#$v8##j&Vqk}Yl
z@AY!xHNnH@N%pU<a<nu~HUmE#yNG;vNkH|7S}oL&{>V4s^ECYzID`MbpMsHs!vn@!
z&V+3w2Pj#D`tZXJ_M-sGAqlrXPlBcONaEABVz;s4SiqS=@9#jn@OTgGC#?-dgT$2G
z--!^SMEK$C2MRMB*}oyW&Rm32W4K0r<wWA0cjG*hKmZaaM^HJ~Vp3Cse}#_#BI4uv
z?}PKYf)sz2zQKnMuroQOk$1S&{|Qw)?8fju9MHeU6|8@9k`j?5-ef({?Vfmz{NTul
z6~lkvK)7~A<pUsHuchXjkS)~s1>zt017ZiRi1VxPE@+rB{(^ty{I0;Y<X_;P2a4d3
zzTPsx848;6ue=%x{w`7+O9gX_Fu@+d-G_0CQt1Jgj02h4c>L1?!h9HEL8Lugef_t;
zp{PGRq8g8|BDz@ifQQ!rNT?+7E-FwFyj#SjQa(^$Ab&|ne*?-yfnolYlQqW=01AB<
z`2nRtKFVKgL(mTh)C&}X`>xkSc+-}ThiiC5@cGo?>P&AiC2xWXLl_@<ZAS2fn>B~y
zEP9hpAtG3)%foU#Ho^kTkU&H`)PUUf_74!O_alHGC?AjDQv~}Fsb9)RL?Ea%Qe=$y
zhXSsny77dg7WC*bJj9k_&vlFfOrd>PIjS`$P>+v5YSQ(Be8ll!kPo0&7$ISGu3jg5
zXsxgbZ_sH7fPv9?AP+Yl!AUOpf$xFw@~#>p8DWL)(2C0&tEB~kMLm!50Ugba{s5Us
z{jxvCJA`Zj-WP~}DDcsbfH{urt^(i(j^2?UIN(APg@+Rg<Px4DH&KuPFrJR#rf;?B
zU-?Il{bQ^byA-_PT`lAX@&y408LS4N0a^3MwID!3+5?Pt9q;bCP7`5;K~m|xn9z2*
z>AQp%c031C0MSbO0qqHgqY^dWo@^!kv6Qptfgi3X1$_k|p?4zHpiv*AdsRkDKJvp4
zCm;S4$mS{S0Q*XVe}%Ys?dtt2B$q2SM)p<m;qHcx>;OAaaYNG3l=>gnf&eMdp2>%o
z=g?`O9Y^r5u=@fRaNGm>3J*Lli5*cdsZ`zZu8ix(;hvL#HxLPh>lAxe&{qJ{*>j-T
zxp#cZ&g$A6<iop~AV{7GB|qS0Cm%j|=!XJm&x4gg_WNFq-6+ThAcfEZU}xf;_f_Fu
zcj6*&ffzxTI(}$a&VJDDSqF04`;~k^V}kt%@&V){;uxqD?;wMq2+^Qppxxuh6E6KR
zJo^TR`e2}fJ;%pzH=2)NKVbCl)CxWd_5;oku&)D1;=FPgmV0jy`9Z251JJTdy~Wyq
zmtH6;zz^;0#~4uv^5JwTigFn02i=EN5hSti9rSSO-H;DQIAW}^{cyxP!JbD3d3}ZN
zfu3>%iSkkUSMU%B1_L+W2G?fj#&8u}NoPMCO%bpc0?=+K7Y}~e4JT-u0UxXixi*Gh
zIGlXAVJO)1f5UnLVAmAXaT^aO;V4#6*vZF3u;&2GBU!=<_5-pV%C>9--mZXie*!<6
z><6ePY@xE}kwK;20D^trTk6uDd-;H-I6}j3nY4jg4Jiqz_FYR+BAt^PLs>wQ%xgJd
zuaCaq3@Yg#m6nMlC-M;iZzf34d`@{+@&UT97RiyDq}mL)eTmB7g~n9&qa1%k>X+@0
zcN~L|v{hZf8oJ;_91jwI*R>1&c*9b?=T1I#{CK$doA3Fa^Iix*K76-7`y2AZhl_)F
zV)bLZ7vzHj#VZ61{a}RWn-1Rs@HzmhX9EppR<NKCVs~(WK^wdqVOaV=2iI4w0|Ppt
zIwy`^BB_8n5%nFE+Vim|sk0j(?EnkM=Z?wf@8XTm(ykMU(x6w32r*QA!#fI&(Y}s%
z8JG`j{I%nUleUr|jvrWW&@vUk@+4?~he~;`_IK<^?429bS8y4eJNHTn%Lg#9*7CTH
zvy!#I+dZi4ITWwt!;Q9}E-#LbA)Yjk7k)|_=v=X^s>ew?VhMH}q}|yOjAp>C;O~NF
z#yA9O<?1bWQch96hj1!!U7!wN;=4}JIqyD>^5IJP;pZ5tf&&e%Iy_*QiUz=&53jF0
zKcc=W-=nYsIgn-8;)nM=tM>BEEq+lx0HzyEMf>5ZgNm>&-%{+g{t9lO2Z{q^IHbM`
z*G@jd_yb-H_8bRQuKSk*!hmQg9d48mnp*l-*hR;_(GTAb;}3X^lo~rkeG_=gQvmFd
zRszWjhAU^!12IrO0P{*dI4txuT(wvTk9HN9wX&Oa@)6pBRUs9z{jO#B2apT|0W}|?
zx!x77g?xYoeuJO@k^{u}k%mMkCs-KkcTFw*D-<T2)WzyQ13`fw?_VJ%&Lj7|+IvM2
z8$1hu(W3DOHCG4;tHHjGEr9ci9~@Rts;<04<eNba%q?$69fkVJH8<D~#0F79&0O_I
zk1z(LgTN4fcZ_8NKb(9-`vJYjJq1WXJ|dcFIfWix4m}?oH-Gx>AH4AdLyq#{`yxJq
z3oJFpli(sous~4&?4EeHm_DjGuOLB#-H@`94++clDgch~-QR~%4a_ZXoBkCN&DZ3r
zLx0rWDes|tkT7hh()H88A0i*fC8w_dRwW<NBk4eD2*QPbo|mDisQBFJ<GTTtz+&%C
zTsa&|c>Ceh<rrRt|D9JvT91IkL4=qT(5IEYf=6Co1^EcD5MYHQ!UiP2hn@=@IBR%-
zqp}|WtFj-y6GJ`zKja7YM?Bmeln-~qyQKjQ=Picuh?5VeC7b|K`+<O>zAE9u%|Nwq
zC-4Jme0K&9zj*_#et6@sD97h`1Bft&$8hRQV5CTJh>=)ChU0VV%=M_?sZo7pB8il!
zkfcqrAh*6}+mGPgx`sl}189H}BH)j}54=Q-!r@vIu8DjAsi=Ioj$OGsp%+4tO2xaH
zJa;@A@7_U0@B0`S{^0}GNyq2N54<P+-O@J=MybTH`PcQRAZcOR1MP=bT~Gx>5=r5@
zkjrj)I8fd-%17C`VCV#OVn=gIzUr~qh_csK4RSY_d;ndlYaC7aVc!^Gdi&u#13!OW
z>MQpSV(@jC!L0-jJGHO$Jr0n+c2gVgoL7OqjDO^YKdv80eFcF15dl}I*Pe{sD?k7!
z5mH}}AO1Exi?Bk6b&}`ncg|!j<kk<Ue0bheN}kTnmhurr9|(d?*7D&5#s@4=uv}xH
z6kzQ<12?5q%15B;<2Rp2goEuu#RszFDuKTj<+Lo4#qq;+9<1JRT*wE$iSJUtWfh-5
zYAM*GfBm$)QT>Abz&1HcgflqsAMgWu5ZvXkLWgzQ+0_rCbC5_DlMk%bIV!X|kFBR1
zizm7UGkyU6V~nr?kub~3X?K_*a#G{4K2QCisvHlxU<y$KSeL7*Qq4#o_y?`^u`9gt
z@pgFNCD>bGZqHp3qyX$2@~O)q!gn7Ovs_On_5%t5KYXrA)Kw*tfR=0h7;!`leFgjd
z4HR)*!k?qKx;|PdpMU`Nmq`9nK4SH*HHaGG<}M)F)eo&fP{!^FfI#fO3U8GJ@RyE}
zUJ`v%LnnY2z<Wud!}_DLA6|mT?yegpIXKuI+&!Qy1?<kDTYNMA2RQxi7(~crlK3+C
zx3V8_j+PB71bzT4#G1kKt@qI)Yy=cIkbFR$0PF&pTggh$&V>5<j-wS*X-?W5y?t*+
z^5G@uhAy<#pTa%35!!~+t5C{iV1mYWhxhGD`EcN%2$~F^=K(K7`{Cr(QSkxhx?BhK
zP<#d{2aFVlA<0*jrTY9EAUEDEk1=8w^c8p{NE+aW8;x2>9z#AVn*ohM`2ZaJpbbx>
zG*rE|M7_Kb{9C;3I=gES_)5-k0$}byaR^Uc4Q02CNerd@0I7Y~b9FnOBLvs^$Bub$
z75GtN2>0>8QLFd09>41N&W(cPMa8}2T1dwt;EN-y>hPM+OPY`GqI~=aiQ=5P2+JWE
z2sFmp52df1Jr61~%15vt1a~D4;RazD_EY~K`mVuIz_vJ7wtNbx|ELV^1)YHTxPg*j
zsy!2&D!@~uh4<7#HX8a`rGMqPR#6e5xEH<--mY6}Hg>%NeE`ho0)ZI2=pyjqGw39h
zn~hBQ!dK@w>v4lgFvl2l*)@{h-^Kc&-G{LsOg@mB&YlAy@H~1`Wv`9m;EDu^#kN!u
zfb_#~5i}0L0Xv*_!b?0J-bKF#@)@v%Zz?`RQio6-_JvRfYVq>Qm5&$L9mc*MFCPxz
zS1yiN(y#>V6f)of{DAElzd<7gfqW_;6=$IWudgt4>gB_Cni5t((h&&ihvPu@Japq=
z&mCm1ukbWdpK5hL77pyY(0C$3{(k)XJ($dffm~Qa5%0${udguri&VnWpkW+fU^Ltd
zr!GDWmwr~N8V^EoS89we2CYAKr(bpaoSvg~1sDOKrW`-K?*e3}G{0t%czhdxxdkLn
z;X?2E*tzb=TLVe&?_&Md92>l_^-;+Oyb0$38r3JDi}FE~k-J01A>1G$v~}HRWUwuj
zd^mL;>PEofG}s1^I4{6hK6rpw%2Uy6eV>2zwHuBKz$sSeE!q2C$%h}XeqDA>Y)NPz
z*bgDZ6iG)QtRKjBD1C(#@x~DCxj!%M2lfen0D8!+$f0n9h)`Ly{jblz^77$5BIt#o
zZUpS=fNDdy%g;t3nX5-w%2Uxd!9y9la7_@a3NS)OsT*S>AAjW3rn4dy!oEY|>IkRG
zuo&<jWi7}@1&b2M^#PcXs=(}X0tf|}K<@(&CLhofJx@Y+!5LhiVFef=_acLKz`~D#
z(T6EBrvRL*$#XuOmcxYdGVr66U`Iv&LZID+2^b-Jeth$<Ujy!V4n9KZd*c<hC@kJ_
zaRg*3z{J}%NJ9Vdfr>KZumc(BD?Z-tJC{q9a<Wpg->t1h7Wl3TjjrxM;}CgF>)ict
z76H4z?}d)NW!+_^q!MpHoIH_IL2Q6>kf(*DgVtDpOMZL-_5&9^;iw3BN%#?h_>S~r
z2MJvo3szZumimR!dJ1|+q5wj0c;&0)!=nV_xt`b8uA^XaXfa7>-mz+U?F)qU`1r$*
zLq-o0CrAMbUMUbI$$|k9<Bzh`=V|ss*BEf`#s=Whet3TuEQsR=b$Ek+@%YupKCa-S
z&K9gtXGtKab}vI3DHw#^Ig9Zes-p+UqPT+#Ze0l!`rVJ9Aga2ML<Dd+#k=mPB!QI*
zNz{(BjzCb}O(c41Ip7{d@UM^)Fcd)z^VV^tYCz~8;YIktG7U%~*Re4CZ8sxa)l_#<
z8bf>@&p{lqqVhk)-%a3`Hy~Rt6xoj-*darET&u!J5351Izz;k{r^p@OaY+?UUxi1m
z`p}O`P&kOO0GHZn3=RTjZ^OF)1*@zMH{>i4!e4}M!3x!55npYEV+Cus6Q{32Kq;O>
zb@YH<;se;#O}C&BuN*;ks~X>ORXUd7AE!G)-3U0GMpfWOG;Dm1K>SdFLoom&yayO{
zj9n|<V~Bsu$L9$w*z(+PML;~9WE!v{fw03oKK{52IUqj!94He2&}ry+4%Ol9@;@gZ
z)fL`7kbF3|3flu9;c(0ibq9VxWkeNteS&?Fl=2!SLh)VIhbk#xcnc^?I}luoevKY@
zfCN9KZPBm@fe`T+quhrV_^#*u<B*@DVju_F4}ND@-k{Cf1(%Qh8R|g}!~Y&usLAoe
zRf;-19NvI9et3LB_1{DN6QBeNYrqKOpC2D0?I4AxjBJ(_B=I#EqLelv-V{h8jUL{O
zOZ!$q`H)Y(`vns7@yGkM>XWyQK@^G!7$nTke{{y6lNCFFkl*`fr>tq54T5S1LGnXp
z)3I>>)M+HAlfq^($ExWSZaWHiQL^UG+r9r<>Xibo6nLe;D+OLD@JfMK3cOO_l>)C6
zc%{HA1zsueN`Y4jyi(wm0<RR<mI7I)+w1jD`u*-+87A9S`&wR7Ano=C!?V%l_3iEb
z{r%+rW;FOa;0S&Q;lpc2);k$qT;EL>t9)G@`ShHvqL2)H`PbdS`Diq{I6oVn4o>>r
zxL^EBMm_EHPe-@YWl=GrI>|@X8kd*cf*Rb?!Obi$)<sd|tHpeBcRe~Aym+Q``opV<
z#S6!j;_Snd^^!a3`J(Dr;iOnhZ!S(>u4T-+gUcz=P!j+3dj7#q>8Hb*hUL?nGZ2%K
zZ7=6H>z?1&;2aq<{7?m?tE3|~s#xBh^<J1YN&A-#7+1I-Zbz=C?TFb$)dc%wc{6xP
z9O>UIZ9K)@`wvuMbtj@B#^sEBl<H}Fi>$3JH`eP9l^?w}!e1;d53|}v(s#S--u1$8
zZjBBEw{AYrAxLj!w@2J97FYf4h<EVPozZNg6^~fEJy;Ho!|?&Ok`HWVKEHZa85vGi
zt%YN~UOX$Vd$6sI{Rq8oH61;hk?dW~x8TNl?e^Q)gDlVX>PG)6s(|%+dH+0aeR?+8
zLRGET#fNG=pd0k(l;RuCi~034n33M)HaNoI{OZ}{cz?M{&)Qk^z^VNH?1_i$>EN~v
zh8TQX%xAON{q^vPG2EXC6hb=MPBkyC4z>3&#iI7Sb2i;%Ir8Ofa(8n%g7`E9sQVu@
zH-HZ5@NTxs^Ss#9?jRz?-RaXcxqH#9tBNHE#7mBS)^@ap2i@W5>iXv9_I@&*v8kOJ
zb259X37@oo)ugNP<@EMq@PUr}8u;NK!FB>L^?81IGnp-6KBVbbUiP0Newv=#*85e(
zYJPX|Bxr1;+>r}(PR?&&3bctK#qG)Qbyhm453Uuf+11HY^ob+Wx-Iz5>D81@N-O3}
zj&4NK;Y`&UZWQ_S#l$$<QgrWf+3<GJptt77o)bN*4Rz+TW7oYm@s0za*W?Q?jvJIX
ztDWeWyA9Kh)8dy7H9N2OH&>TO#QwaF9m~tVSBI({H5)jxx;~mktz$=i_XLhaJHk9y
zskD1p*H@3mkUC{Gzlb06eJ*-Df4$kDZXB?>IfjI!L%RdycZ1`5+0Rez78rETXZ8s3
z7!r~WY|jd2jgP_o7R`ToMY6$-JwRMt9hyezi9PPvkd~Xdyz29d3zzr$;u9=Q7DGPr
z>F_+X0g^<UNDIENIXqj9n%*+2ZM>QG@2z@@`}zTB+QTr<-DEnSFP6(C#@!*${qp>@
z_u;5FNPxY#gb3nnzVL0BO?~QaEmN|ydsAmE&kx$_-i=jDep?qE>71NhL58~?xk4EJ
z{_1@20XP6@_w?fWex}ori+nM?y*#UNDIxLN)LDx|PEmC(tq|hs+D=f&`e#>@hAg0B
zIlVqVdD#P&&fwy9Y7*A#iDGeoHMD1SdRM07GlMUv9_Yv}tQwYArU-TiqkF43*LSPQ
z<!P<Z9|-N8!KA(6b&EWv#ofh;CFq@z>H6H)DU)sSOox_{T3%ZG?hdYMoIcJExLRDl
zOpc_zv)j!b$~7mSURtU*y)YSab0AOj#E7sL%aOs>&fwa_MDfDkSlygj{mTISbhm&T
zn-le8dy4s`Wk}4hYjK#MQuiiSU!7U(NNY4_^^!hW-B_)8I_j&MI;VG*snnRqJ9BFU
zc53y@<slL@(@VpwEiY9|((IzahDY?p*^3%arYE*@Bybj&#mw-X1{N`9Zi`k$x~*=U
z8OCFEr9h;8L#qkI?aS%&<nyT(z~^pky>FvU?-qC3G?)@{zjvlwZ%Qln=eZ6cXQOS!
zJc3<azl>D5{x*gqqVLXDS`}FgDQ--k)aV;Ex6&I;XCw2oZ;wg^(sh@`^gtg5uW3ZP
z+h>-BsY6-aFK$(*vW)t2uW!>Ni6y~zau}GMZI`{L8na%E+R^NIrLt?oOlm~y?-Wxx
z;4|Ic>FGXg=o{K<B0Doo#aPjlden_4%Y6lTpH{-Vy*+eQXil+^=^WWek7J6vJpvP{
zF~u^I=C`+tPoh|o-%F|6lfv7)o(?wVzbb@{8%vop-Z6x3p9ytiMo<MRo6_S9oNI3t
zlV{uFB(;3VT0|QjtZsz=)VtN1V<z=W>z>oqy{5Pl;x=d&bVyj7+~3|p-s|0DzCo=i
z1>73Z{R%cDBRJY)O#03>;eI-AUJ$mrJ>j?**@MO1u0Gb4_N}BXZ)C@EayvSQ<n~^-
z+l6hHPR~X+O>y7#^Nd8YrtI*10h!^$)05DK!Rh&BW84>}AQ(fe*xzbLAFHpe(Ol@1
zLA{@gLG^(M;ifn*QoqB=diD&fL^}1!QxH_Y9QH+s4fX}OxTz1tL#_>DNH)@b+iWLO
zncXSfw-U2lClgg9XxGL4s3tO%^)K#f-Q%a1ka}g6&u-52u-g&4Gq|jsQ^@bQ4e4Gh
z8Wnmx&3I^Dq^AmwTtHqo3M>|P=W29BD(Rfv){VU;(upUp9pe;+PPTo9Re<$#(SS+s
zqE629Ti*SRF~f?>P^*S@_0VI^E9%<Hs#r}fnz(_r!!)y2hK?`?o3&}x$aJV%>Cjl*
z3eBv+bw@Q?E5BtvkCiAjVI?$deJ4Fv{U+xlkB;HX!8=8}HSsWsrsWS`7violJLDb1
z{lRAE(^k3R{TsUtIiESru5?Q|DO)tDukw3}J2oMhT_Wb{$nQ6HtWbOZPFp$vS3Kb^
zKs{T+7i|NaAYR%9#WwKhVn++%wtImYOW>DG2^sQ(yjjU1Y7^^6=72=>t|kC`KFf??
zDGIpzc5^$}HNlC3cglelkc;gGA$>K!m2<CoV0P}sc5-;Cgb;aZ%{{iG&X%RDnYMMY
z-5f<`Cz&sqsZF)U+HUiZY=nei$CNd;XHs&?T|M@Od0{Jz`Cc(lvm)!JnE{(`t1i=l
zNeXVUQ`NoKqisz3iSh!MEb3y;sju&tMzctu?sZL-G251}3T}%Vh64$*dAXe)!FueO
zQ65;*8!#@m@OeARR_C|Wm}euc5Z7xxBh!W|*5c{iLp&{N3`J5aabdZoTKBN}cTAJ`
zi=4$8Qtdfxk!_-rr{}E4+EbC+2w<dJ$6`o+9Sa=k%&JxeuUppLvludG0&t=<R(k=-
zE@k)U3G>#tytvt3S^3s>tz^`F=QTGH(wItE@5&CG&XN=ZKkbIv^z>SJ#;pb9MET3i
zP+Qr&`A*8pQ>|yjk=F}muQrl*+X9v?U&;BsEr41KSuy3;Q+b<hCqi_t2v4^%LOywu
zlbCgTCvep78*FCJPita%TM((fXwOJa$}e}7aIEJ<&lRmX!IgJiwDcYHT8{~pyq=Ex
z7E`7x2_3p8XP4J^um{Uza({Pyc_t(9zNoGdY$A^W5t#d*n(pDw3fJRfjHL=T&hM#U
zc+0dJmCeouXqn>k8s;rb8g&NeFabsMCaj!*FHeXG1$fo;;oEi}v+Bm1S^)t2XZvou
zqPKVlgG9YjmEF+p69e5_>Af*!WDI|n<|YJgcMk~)V|CX<F--*wv2vAGMj9ri^RD0G
z$V^+lU1Wjc5zaGX-3OzbwlVCn0n*)4=3zA=MU9w`Iizh$bzj^JrK(OZh!~YjoHtB{
zz=ti)&QHzt7X(}DG&MBKIyYBOSg+UL>*^6r&P;?-JS(#!^BOX>H0_=m2gNNjLcVE3
z_r<kbTa>D5fh)C>Apn26DvH(gs%93Fw~1Yy7=wj^4R=}bEiR1d(isi?^wc8E7G9}x
zc5}Kmw4)tu!+3OthW}FbdjC5+6T`<$nL8+0vm%ac`efynH<GY>%@M(?Vk(engi!xb
zn-HF`t1L*1P_i=DEFV#c+}c>m+pFC>f{=ncAJE30F}YLNAJw7pgDtl-%B;~RA4=EL
zd()FlkEG_*)lq)r=9%=4k}0YJjhPiT3Uvru3V|@9I-LrS=G2(N<sM3)2lqI*m%oW*
zx(ma~xh*C<n&B&ggEprDO0^20cA!w!Gn8=_7W`HMx1OtU^gxa7D-MX01)sG^jMSJl
zQ@|d{bjX7f+k7^`vgO8VmXaD<|7t&xF<Z?KZ_FN5@oze&$yBJnU@-wizkUNb!40@v
z3MbP@7Y3UyiPE{^khU<!R%o1uu4QFgUS|R~uub=543etI;C-{@Qp;~vRR3M5NkN&f
zn4Bq=apLi-CC?k^7&cumtWZi}V<#(#YNlYY;6qt*=U=TIn1Gzhi6v%VbggRkk*0fO
zDkQcN9egY4K-MfcLzHs|MR;r(P}ZG%(Qb3P)QYjU3|eSX*>}=&Igl#uNlE41ZJ1e5
zLmH}&^e*O9nPIJ`MpTVUguLR*7tBm^No^$`5bRJ&jnJSvwH6mGSV*HPy8DTq3t7-H
zh>8tN<<OW`-BaR3&9x%-QfxWUS0yC*)io?Lpa@t?Sfou?eGHWJq^VV*f>R?+b!j`)
z6s0ZC)1g%A#VrA$I@7XAw$<>03V=>2;d8`EM@g3=zrIo2vZ=?ev4o|Vup;R>_pcCU
zaYL*oX+Ama8^$T8?IUIPIn}}A1wlW%5Xk40Te4mmN~bA_sfshwdH_<YM?;?cun1%}
zt6lve!e4!f1Hcd&nA(6q5gJ91&BANbmQ(9!y|l}{^i&E+ensF6qzanVi*{F)B@-V#
zS<RZKMJD!!e#H_tSb|R+3}FW*V+0P=UhvGWQzO>GZMqo^mcBC~0iLGTxcoRPfI4bJ
zi#Zt+D)DJhSju1%g_Nq4tQBDvwAfC`THc+Pp+nrL#pH-kM>=E)BNaA;HiI5BVazx~
zRMW5{YzXLc2(7PDrPvFCeR|ejVaf3rO?&L9fdya1kf~mQie`GjnAS1Bs>-K>la3zd
z!1r~S2c^3pRAy|FP|`5f=^fxmZ<Uf(f@<-bsR;5t5fGIbJ+B)QW=dT})t0Ip)D^K(
zpbw1YBI}jT+CQ;AtRtd0U7d@uUh`p_8n*&Jiu&AP%i<g_aa+?WC%v*G1I%p5P1$`S
zhcd)Ks2*9|(N`0TK;}jmR`Nn2G8^?w8jzcR56nss$;I-m3PGi_0o?kC3#>C0!XwjN
zs^``Y2~}`~#QS<O_?nAx12&N#xt(BiqNh;S`85$}AfwJ#1<-V8nk1${kl_N)k<4(A
z*9#F{u9$a#6J;aTGoq8U*Hq)H%hB8-0!hy}tzim>;jQ!G*ZEaVH7bS!pmRQRnVw2f
z#WH;Q*7B~Wqz6U(tk2a6V6pH)&N8)<f;bzQR9HFF{1pNnNdvNn1)p+o1gzeJ6B%-a
z0`*Z>^XqY9NnI+3O#o5Y^u${EuHu`3oa#%69p^u7%R$c7B2J?E(^G5=ISTIZmk11n
zBeo{euhu>j*@5>@q&8cxx%`xMxL=*F4ajkTNouWz<0@Z!d_ZTR_^>{+voM4Xf6<eD
zn=Xjz3Tm;4V}(m9d74M>Dmy3a#8W=XH(K1d-o&)86K+CM6-<U|d3eLJ>BjW2l5J47
zysnA{hdWWh8KOxu8R=MB=%~r2N!0(UNlQ8{l4!!L$Oy=2r0IVWk;Yf7uPTcSGHdcx
zrwC~7^K5+szx{8iusa=ED`U(CSE2H*5V3+pgp|L-I+)f!o95ii-T9@vYQ<mpd`V_a
zXz+kBG)|$nA+)kTGXO$Y&U;VE5Tqw9196AT+S8#>NkwFu^50h1<!kt>Qx-Qaa8eMl
z@+Ehm%$+p(eqPq{D%i}BBBzI{hDzfv9OO#Iy6N~psUkXl54EfH%L}5eq=&|)SoCVC
z7A;oQAw$GCy`v`c!C>?KLDX~tK*@<;=o-iK&_q1>AjCI-sF_wW)1uaQuHwj|1l18?
zRciFrj>v4aqM}LBCgY=H#MKM2)r2)p&siS2nf$pVniiXv(o7<`zew5sL;tF&Ju0>;
zxI~600TJnh<(CmdsmZyzQd5xa7B^XwiMa?t>FfZx<kH-ub-}z1*q$RA{#@s)#C9I^
zOe!q8KCL6?E_mz#@K7-@qVLq|XV%`1^pj;Ys;-r%M(};f*C?ftkf_i6!9T6nQ3;ix
z)P&*#hTJ;}<n!xj73=Ui(0w`ATF}%D846L0UDSRHWPH|>{xX}bR(-ggctEQq#z=0S
z-;iWh>M2hNF$0uJWA;Zk_xE>KL#?O}M1BQE`J}|-O=JXH#oT2SxR}HWB*k+!S*@}P
z`6xPqQD>RN3K=rt9k^%NbY8=WN^v#E>9A~0uLM#!9qxu&;!Ib2$o1$dgw+-1oCbkq
zD3u9-3dFBQt=nX*n1Hw!cUP^&yg7@#r)o+X*ebSkX^qkW3(CO}U81VO<s>%cP>`eH
zRZK%sNsdfkNa0zl@mNC>tyPdKD%bF?m2%6o7qW9{9)TfC5};_n;E0c8Dl|19DjGzy
z))6N;{kM!UU==K3Tlz{PU`6!m8$GmgqIm2zRsI`Ldqs21z{<!0FBI80CauTnFi+GX
zUfR)QxRlWp+$$L{BnCz%WwZ1ZHEqt)RW~<GXUs!fox7`gyb09i@yd>xv4$el;opqN
z;Y+9xHAP6SJP=twGR8wkgHrBT{-){#)M~Y8qiNH{2AoDhB8=r(Otd4X{(&EBdw#M7
zQU@v`J#o5Hg$_{>SDuZKNS&15M4aSOOJ+V)a*h!ii=d1%Su-NXa`fRH#dIvhqau9~
z4Rv4+ottZ*-*iiUcZ&warM+JB*quyAAba+z=|z@&Ao~EVvkBMuOsYeqB=zpFq%j@5
zUi0h)nbw40SePx=_*7?dR)I#$l|kntblG6i5}B~g*1V-M3bjKxLUtphB<T-GJ##*N
z#k!Q4t-6h`cX%!-t48-ali?I<?7_Vf;!b94WH6DDO3KxmgKgEu8h4ewt3o!&G``Bf
z*uNPDGto_C@Sf&Erd&{iE=MO!>!>MzvH)0iU*`SDhdB+>v~6_9bXWPXup?tOzz;Fg
z(UU<TD3b5cKiZ<bxttseP|GXh@oWnv+5M<{C4sVlhICi;^3KgzgS|G0y%rvMSItNx
zwc`{&)MF(Q$=G`vbPiTVuBD`LSUJZ{!@nv8gV<B0msvbRMwfO=;7_e}YH~lBfiZOC
zDY&WZI;hl`I3JAC?Ep!GPJ$kZoF5_ablpM83Q0BKqiF}J4CU>p9#U%uK)HLrlyFCF
zmZEO${U;V+wIk$#N=aY7AcFywQ%W_xoZ=&E61sxq`G_Ffl}Ycrdi;7BBzA4)K*4$+
zBTU6TsGiKw2PiqUq6GIRI8`ZB%)t^d9x|Vs&<!YDw~OH+DRXQkhK#JPSW@pcEzabu
z7NQ~clj$1N7W=&q3@fvuRM-Zm{maUz2z8?5WCK+#(zp;$QifOAeho6zw?_=m*r^7_
z;M~cwQn3ZKr3pp0+WT|uPwmYRq>81!kQ_<Vw#p@MBw0xA06{?}a`ui-6m7<rmgpM^
zi84igXq4egWX*52vpz)YJodTt_-F)6@`}>#ObiD}?xyrvm^PL&$MZS2Y^{u2x~?q@
zlC^}K@9@)+gD?amqNiITwtI0I3!=%Ba_C0p{L>3WIv(`X64HpWbQ>8hp*CszR!C_>
zgyej>M8}n3gK+B`bA^#`wmp8^zae8y#7|OdT*%N(4hLy;SBe00cf};{n)+<pW1q;;
z3=&%e#JX}K2Z|JYQx@X`LF<B|y#r=Dz9Jo7I+rcizmgsD<?IKUagwXfX^b+F8UJ+s
z=PoTUZMsN>v9cFv|ABf3BA*}Gx@Oy{?}FSe@5tDAaTTG+y~Oh9)5-}SG8~lqljSsV
zT_z2SNtIZ4+cW8RBO&EFD`_KL8MdOuOb%8V9Bpyhr<_bZpt12xtlJ~g>oOysY`81)
zPS|2l6{Y9y=?*PX(_27omd*mPcbV>j4B-PGDeqWfEhZgzKyHUu<Xj#Vc4>TL+JH1W
zWJXp7)XBsMC<c*Kzkicc8K88O<n!qr>uVPa7Fq0C^XV-%^W1^r&9BJJ7djx6)-pOn
zGF(F3G8yS3UI6R`ClocyTWm(O?y2Rj7AzJG(Kc)A0dCV}v<}%?Ji~mt9KF#&hIGs$
zdUDE%#6;!V4&o)lnq$Eam8Drn^@jU>Bla#o8ZPm5)aEM(Et@U_lnq!M>X95%(XBz`
z06k6~NFgA@NI7a@!*eN(2hj*}428tz3H6ZtZKRX%&pRY)!5DxM0m?%Wy#bDlHqq`Z
zRdXCn%N#=zzLNZ4={$0y5thc;fMw$&bB{PWkb<{U8Bjo`@sGQii9}*B(}>4G9!kp6
z8A2KPh`m{MH^N1k@Xx{}GL`x;fmAyL#UsaNM&g96YUxV<1z5(vS#uDIHv>_cCk`?a
zN!mEkr}z;A5cMwsBFEuJ(v_ADdp`+rA_=VJRqNOyEYc=97|R{=kfT>(nG<R2<J_v8
zog-F93Ka`qDT{QV)fLkJMt;c8x0%@sm(1&xx)z}<c%IWSd4aH%=Sp06iC#1XiXU-Y
zS8sHnHYp!;N@cH>TI2LWY*%G&PsylVGnk3%RQJNM)ywizcw{7@(l4SED1O9l*2oVz
zQfAa>g>OwE>l@YUl?Xve(Z%l1!@(UH48<a`*)^3P^0t(8nr$w9ujsnU<X$qalOn)O
zwuqPP8%`vINaai?QgY6hbfm^sq+<1n@vSS^>Ld0xQscg-S+@`0EbFi=Zy36YKmp}P
z{m`y~AI&C$Cq0rRx_w)h*xzU2dscO<9ey~q&B4qOV()3^0=|^Bn%@c;mYHQF5~a3L
zh+b_&+(XV0aTCEDvx29C?8%bU$TnOvZvw2P+J_Cp!K{l)qlt1R1~Ypi>Rvx7Cz5kI
z4XzWZ+VNu>`QXA%=1*yI(IJ{B7sMka<@Z@kYL95`sT{L9hVV6`wES-8{g{cwx60m4
zKAQL;LR4HnAcR#$F4}yXYP-hDBnwB$xUA6uvurx`@y*?@z!DwEF%J!5tAW^7R9o?*
z8uB*qL)mjKA4%G~m@HSz*(F!)+flxzw5%H$BEHXJd?5&ij&V2(kj(%k{pLVT?d@-i
z^aHkzb~k%2<}t|Ls*V1xLpkg8dOhh^v~Ns9N#omkFjvlXjqHHPGclhoV@Oy;PC7PV
zvH6kM`h_GvCr#sz2LGy5I*2M9gdb8N2#dNI*?mfM#gr!ECO;%S5c#ZFhEfC<^N8-|
zitL$sL7OEOlhdsfn#Skt`9TC;W^M5h5yk2l=T_HVaR(~3GZHB_nH77NAFrY>Y<VvC
zEuO^)KvVpxemuzBR_HyHAEIwPEkDfI`<x{&Bz8EM#8GQ(I#B{!(q9%o;hE6|<%h_K
zqUKK~X2igOlpHeuQTb0O<Z#5Gm&EEQ*O?suAP%%qP^&e?3)u^?lj>nILXnDZcl-rE
z)`TBY!0G&lbk-wjRg}K+yb}3RWa94lZ}X=4eU^y117+ECSYAaLVg)F35un@#Eml_U
zZ842COPv(Q;AE(Py#tQeDmfob@{gMUGNg`m(c=3oFw@~%ME{EARWbyDMHhU<^sX&P
z2ee)gylI5g)Sc_6mKwYO*|EsfdaU)RXQu|S`FE3(RHh9efyC#!?ZHg!$-B2f?l(>S
zD>>&x^Gl@b8Y6Ei3K>ViGDO7kuXb<47H`&k4TnK6qar+eA(iP)$TKmRVK7@?$i>NY
zF|3@Cp!rvFXcvbPGVPaS1j_ux?e|}3-LATVnbo!Bx2vq>RdGTAL0b!S)klr%aA>+O
zH}9rj;%LfGl%exDm9cC7ZWERVeAcyyExy}ley*FxS_fqe79}GbE4lB~4rphi5}N-d
z+1)aKcTIQJlUV{WA5QMSPV(F3UgO99Fn~!9zJYFNy+|(V8oOhPDc&=q$N|0w*+f0D
zaWNrmqE=VLe9`PuaQHfsMfS}Dbf^ft?U|T}^w^5oVHp&~LgI7XQbS-7F_>wK5h*9N
zJz3--H#5vf<UP5PCFWC$03~ch5&aG+RWXZ>fIjxA+Km<|DL<)VnHl1_1CH4ZA4ww=
z8m!x`8Op>)Z%8^y#4slf>kZU`39`IPdI3)xFexb{dyJzb|K^%j0FK%$9Be7R;+9P)
zmNmBjmATu?7^{&3J34)?*5i;=AUX9zjHMj4aHpj`)_ayz+e9F-<A~Nlx0Y9l&vncA
z1wz^Pd-P;-5W&Hhsj9Zh(KJ<#awP{@uclUbk#*!vAgg+x;Kckkx=^0hIGu-s%>X5x
z)ZV@&ayUpQALVe6c4oO>GTl%{j>3uBm2G7EGi;Cj?r-#s{bWQ4%BD682WQrNI$PAT
zEryv`oV+IAv5}S0>}MI?rJ*gkDF)GVQsw5+T5XH@p5^6g6Q>*a`t(d%J1j$$1PlwM
z!w4k`qMx@$Qts?c=Fio4C8&=sXO^h)l@U_1fKU!V<X42Z#((D*GRs}%-)BiWMvh!T
zwFJzkiz#hn**-R1c35JL<R)qb{RE(#Nr>Sq>@<i~JjjHn=CR0V*qOdtzu38nX*DIT
z;`=O+y`WuM{<-edvgtY53295b<fm~-c9)FPvaJqfE^AyK1&+BG^0N?(AOi1gTOz+-
zaeFU!-ao92M4r811}Il@1NF9;rt&j^#286mh?s#Sk;_x!@EoT6&&&Q6e#r(V(nsLx
zxGma;DR*ilEiPl+2P-jcI(I_M0OgD)2e-yo#x~Z(7Rj*!Rj!$s$>n=n$nTTR<B9_*
z-gJ!F8tX$9lr6;W!@s%K?sMH*sloS!V^CrXbmb77s+LQ!O%F5KVk<YYJp<G(l_1IK
zQWfs5YPV=+O;OXPlj(kZt;O;x8RBqSK@4VUFp#%pE(kH_$`zvSm0Y{O<bediEn<{p
zOiV6Rk_aC6+Wf*DSs#J5%O2#Y9cO#6i0pq@B<J5s!eX0`RDL^}*a*4JIotb1dhdKM
z1-YRCU0^JiVmzZk2l|{yJBXCzd$}jp2c6fP+QXGrS-X5EQhKH|S4x_5_R&(gaTFaY
z>I@~S1tllxnybwn=-?$}a+2%X{0n!fjK{e$d^v>F?O24`+m?7s>$<*+(MdTtWuB1q
z%j4`I)-2~7*Ru##R+(S6#PvwUWdHEQW|f)YU>YET(tIru0)bD4#84oESAQW>AIa88
zYDp0_=c&xnkh3{Le3#L|l7sj4z5(j`*0p+~0!B#56(5D9<`yT6+A`jaP}aPcZbnD$
zj6}Cz7HQTTxZJ8rd~YI=A2=ubDrHxKS5KW2C&{98Hd2y*pCvJuS8)$Y23QfwYD?!)
z1_i-uuCSHQ*eAy1{wi|ou&$6FI@2p<a=-X=h41bsG7f>16yImr^>f|CJ!*lU%2z1J
zOt&;2WS&Yd73c017<3`vG>J(136xhYkUl~Yt80sIqpQuJkY{{8-5ktpWz%K)I*d)L
z)~ZjVFtsALcBYA02tq04c{J$CpXYl`RTv!QBpaNM&Ie+BSvnL!HAie7f=aFVbWUya
z1Jcy$ZfcRLf~YIGU*(!<OPPBl(?nzv>UtH&i)#Bj5;EI_@t)5+XLs|(ayh>jskSlz
ziu{1@v#^MVNp1PLZebb$3jf$-BmV09(=>1?-N1r2K`mAl>!e{&D|%c`rq$%`M#QOW
z#CPw9z3Vb%YQcIJ>Q_xk`Gvclu|8d_N4AoK+uL+$A*gqy(yQqFcp~G4dbdsK{?QSk
zoX&l!?S<*=QXyQ?p0RU&E|?}qPAEi6rWvwxu~ZL>5F^moqvT8!+w-O)H4<C@BVE=x
zch{j>xmE0X9)(|f*-@D_V!Yo&z8_4^KJ@{cX&UqCOTMHdHL1;}c+JmsivVR^E7W`?
zUGuFLIIw8}*_p)0fS^X1rM=FhC!Jmh<?u8LORORgQA4$#7k2GAXIdsFMX?NDGSQXu
zbWoxoX1R_TxW5)cqX&)b$#nXHdK(?Fs(;PnJ+98apgGOdm7|w}<WSTjyyp}7!2`Kn
zjro0+DW6vAT2s87+SXvE%}03kYHYfDgxtD&O=grpwgs)%9BW6oOlne+G^#vaGC#5>
z)oWkZi=C;1g0FRq5R~}l8f*wAn=U=5R1UAO#}^`;WMC=%CoXu(A*XX6Y8WY^J+3yn
zQ~P=qM<B|*Bnb}&s)x8`d@zR_2dJbk)i6*p7k1yW>HKruH5*<>^JzAxC++o`?eD8*
z1*p1G-;T1>jY{IBLNpNGFpdA3=<a({&GP`Mb)P*|L_r6NQL@$Ny2ZRIN(h+-x7w0v
z*`%W~HNGJ6S(w3;_0c?_sy1CJ3W)rw7i`v6y?2b0RIaf{645ReDkb|1VF`B#cQupq
zX;_GnC+Wz^2rMGCBWtF$UmA6w<hrOeQ&&TTPY!7rLsim&oW&@G3a8Nc7Q^%~7b+YL
z*z-@G`+C&Z5wVrzW3O1MML3vk&=UwHrb~FcWRee}N22+uw8gA1soZd48E7>!ld>Q+
zsP9>?qB~4s9Ohh!BhrWs<jQ(v925%{BKEGwZBU3$@yh4~f+4$9l(mK5^i(?uRGaGM
zD$Cfl!4DC8UeE=(v?e)-Uy~Fq^{rwWS*Ab^aV}SYA$8V7T4^0B#0o{p3O-k~#quhn
z!>{RZf>vopGwJ@osY*$uo6D<EVKJi6<9W6eY$qcyHC$XXmPa55I5YQuS=DW@Wx1<7
zd8X!b-OL=N#(a9gqrqj%%oKUHS)o!UYZ}kUu3Z0$e{}FFR3&}&oCHj@MmNTkCCYpK
z+WR9h>QVTX16AD662@!-5`%|>4Tou6%y?3Y18VKy0qTz^Bo%t%-l+PhDTz#RwB>RI
zs<3n=2j29qLPf_Rz$BQ)!@tte4iw#D#}%^7j0gu?8(y!Mw_@a+of$!6?rWrS?i)sz
z#06Kzg)C60Xy8wJ!qBXV!b)U3WrIg3K)1iNGSmzDogW3t_&&=ry6V2TwHts42g?N+
zPNC$}t3ia-J-aO@0HV5qGxk+2mC?Ii(&(+4O{yO{q)K6toF$b2e4MW=c4eX%G`C<=
zor)i7mvk6kL>h+TC(@e-xGOf|x56)2Xm)dP+J`*}PtGpy=5izl1pq&4u66Ds*Pe3S
z;9AGps}`yVGTly8&Pufj@>G!9o@65_qtITme9nZE%2bZ^T$i)DKMx068#p*}FK3hc
zyZh-}1}X3%90mI>km~>ZV`J%1u#`?TNvu_(C0W>+WU7bJrxMg|*Xfx^B*yk`{vNOl
zLGd2xQ8B~8lejh+rW~x%J|eK;-~oJ@C=Jq0tcM<*Hmw)X3X4wOXuHYeeK!v9x8#Ct
zq{NB}DKB1KiE%nhttkt2WKIXb=HcMXnl9PEjCH~DXLU4yrR}QEr1C&~iEH_*5+>;K
z|E`Jxh#l@rC_Ddlb(9YFzi$%>$Y?+{zok90!lpkFssc#OZMyBtHgjY#sw#jJ{bdFo
zEl_dN!p1eg>`QgApm9UFcLt<DQqO_nwbMDBFE5EuOycH&O+b5**g2nYif@_WU=oCY
ztPVM?SE5n-%je^bwGL!$EMTHmlQyX<V6TdF(x|1}83J_40k^RQ{Vk_4feJI)AtGt@
zS?_M)x_`d7C2==i&N2{udDXTI5$woRV0X>G`k<!OX`F>4>#o#-FuEgVqE{0iWQVnY
zhqZ6<W?No0B86NnNY%RKQ|Q%WJTWs8dG^9q3@MgOx?mz!&8c(oP?0$qYGdfag<R9a
z$Cg?^ng-4i_J(V1p1|Hx@!aq}JkEMuHSl0>nV;*PkXQ#UcN0;(T2%$Za_a6tMMfBa
z4yl1(${xf7Q-)}Dq0%i_{-hqPiP@hD&ekWXG5IRKn6@=c{eqRfAo{2oFEp8=;*Bcc
zwC3WGs!#9ozM%0<RJfEaVpoI91MLY3h{)L&q(EK7+rYc+E!94#CLgi4&Ch=t3{iGU
zYpXR+bykxDWc4RQAzr9Op*-xSQY0Z*z{EX5+UhKoiyE-~$H-!lLq|vF6&)4=-exwc
z;K<@!w%hmurO+Nqe)v$*q?qzS$XZ*_t}?_0!{?C+XRDj3N|=Dw%Z$XWAl4Snl+HlT
zi!n}S?L0sklHc^Dr7{8l1r5U+3x5kfOKIY)XE*6iC+e$`fMjcz)U40lRO23O`*yax
z9=LeY6PvX-GD|(4b}x**AY4)Sli!_6;Yh4}Nw$I$N=Sdc&B`X7I>FvDzSAo<&=JjV
zb19cwyLPu4m$!i~%P1`l)#;v^^)But{TyD!{ASqI0RST!DV7N7R`Ny863=k0c4R5o
z;vMxEyUTvVbn^=Z)4B=T8noNrHtlt;v%9k1@akU7cjWWC(ZJw_nVTn;>nibBwVGnp
z-%e&0glC<*9;1>1+tUV1c2v|1pt9u>+risd+O+9QYaH3>4==9oCbRisv6#>9Z?Dcz
zd(v*W>a55cANeQR+_!Wel}pG2{9R)y4Bw@2BSBb!j`ARY9V;=?VsGqyp}QPZIah0x
zTs>*0H#i**&xXUnNiWlS$`vx#Vu`r4YG&K9bVrR)dC<#nv%$$SyG;wqnM-2w>zanQ
z0NAF8`MK_?&5#!GOoht^(w1l1!rAq8tLZkL&6=GX6J<-Se_J#JLLAnb8E&y!!P&Bq
znZ2+pLpnyX&|2<>qDF3oke~V%7;`Et<JZ~~a=kKgW9q9YpV;i6du^5_5BzI=u6w;3
zL%J3_a^bDZ1^%07p-F>vq?PBy%Kb>4RTrDD5^(jWoeMR`g_?X*kgXnI`zKa#e?7B|
z`UaRiJuL)nkS?c={Lu{)H&meogim9o*5>u=;%eJ1);i_{=^+OE8ybj@_2dC|g~qgY
z18UkAJ1Mxn$+D~QEuFHuRWL{{P=hfB3-M%fMWM&ycDpfyJw2M!k7O7WIMglkbKS6f
zM31~1YD}%cB~VMGQ>J?EeygcfHE#kvhj~0YUD0u5dYZCg4J}F16Dz_F0b>zMYJ#!X
zGc!no^YyKpkYw_EfWBX<Z(R@6%)Ll4-qaA4^9WNz3{9OL=TPA(W{tI|;i_*-%Ry2j
z=#~%FK+9vWDcvhVw*?%sR$>u%rq_e4TRT@ClumkF)8!ygNUmb=ZGmi~miY%XAtbzu
zKOzJt8g}4IH9PGQX}e{{&{!@95Q-`5xsa8hL&|c0rHu{K`Rrn5-Y`+FHO2C}HlLuX
z6%4sOD>^@9f<#qa-H8?Z!A2B|7Ne<?Te}U#Oh)tc`U9G&UWXjNueL}AEX5dHd&Q0+
z>wJFMYy!F$Go?@ct8zk`<8=5dGr<8-Sxq)LTK#L4uIZZq>lg%{nf?T|oNp0tSeJ4`
z6GW1vSHmmj#@i05)$Cg2>Bkz<{^iuz+|#|c>mWZu-}cPfFT<fytR@$=hCMyKu`{dT
z)fp!eL?E=bTJI8_Q_I)XlDf1;{{mL4`R&Dt4r!(Rv)fr6Hy}}WD_?V4+MDIAe0s-_
zb+MdYpBXI4PDb~&+<?hBX*~4UL27;zF?Cbt#=%@USB+-0!?y;Tb9;Gq(hVWeH0$<<
zqnoKuS_@_P&vUQ?^LvbFTtF<JPjIn8Cv>bd>kZDX?q;^#z;}w7ib?AERxy@Sgs;1y
zv#nH+Dm%Ab4Bwt&HJ`$q!R6&>ba{1iKbhAz1YT%kL+eo8=YChMvhdi4HZ13pyBlo7
z<>mG5{d7?)-B7-mO6jn^2F_z0TcB>t6Uj+}?5ts$IkYHWt@6CafXAk99jVx&A<acQ
z)|!)u7@p;>4Yo@dOBVOic0l-A&-wCLU^8y)srA9K30dQbh0~$Ape`cW@@)2`jxK8^
zY#wPvHCrMci{)~$AyCH{a^@pm`xaM5P`XfQ1}C@m3OFL$e3r9?F<W4Gn4+)@Xj9*B
z#vh+9Z}hn9M6E=J0rMVCi=kTiiV37g?@G($X7p)^l}hzH44vCU8SE|Pi%ah7VBOY4
z(Y$TKzJ<J=gNJ^gBA_sfu}}9Z=354HEKK*k*S!&$B(%S5KF_V06KimjU+smdwE?Gg
zgdpm?(O%cKDWC4sWA<tteL1ZS8q{JQAFM=bj{|J2N93s?wEmXoYT6f&Frpd|c-T!u
ziY5O_c}uj8QS9VyM?+Yct5nP{S?!(6X?_!#tzrwL>F*>WhR1#kQn!PdHjbvEG>Eg6
za&cUBIx7Ui7Nd5UG?cPdOsvfXtY_O>k;TDR=r**Z#iOn{fh_3HFQG@7fUP~|*Nyv3
zm|*nHp<L60_?QgY)~+u%#DO&~N57Ny&1rSc0&-Q%YU02qI}S3}mKsA$V2IT#(%waT
zM}Bc>r(PbN=FJskC)cgr_hNEx<?=!Wa<f{;!UIk2=zK+l&cEGIwlV9Sx3Y>kM6-4H
zw}kS%zn%W5Rj*p!4(paHTDzry@i<V6jSX~=AvXB5dkPaAu0PcM$!Ax?7t0Oo3y|4f
zJKYo-wVK#@?yf6Ydzq`?_#U0kPHI`!4dXif)4Hv2U@CNSb=I$u@;y*I@T+O}<m`G<
z6OYD42dBN-u!rgB?((s)+BT)uun@ero7#M<PVe;m@)jcOc{wa8^5uMb2MPQAj+n8j
zt@e2zq%dIviwz*cUbdkqR<P9%%<2r9q`PKPNbF?3U)$2583E1jPa9NXr+0EXJcp@|
z>+9>Q%hCDS=}GSc;YCTUw9_A)o?VQt$~Fv7s~NVkjQH)^(R(>jA>P{d(sr`!9R@k<
zG|f7lEUQ~N!3)38t2A?MXp!p&{<7(vEo<E3og190wYuK0Ev{;H*3NZ(xG!d>#tub5
zsDrsyku<3hdq<Y!cf(rC7T^B=<E&c~aLKP4)cUTZN$aLLU|{!QSm<3_-txV)Uqd1J
zz2lbfHWf>4)d(UoIn#47o1p#OJ@1^^`QebEeFW)1^3_TR?9hGkK^yG-J4aSy$f36$
ziygp_`taxKx_0sD{*8U{5Ympd4AOZ#Ir#$j;oD(5*REpVNDGJX@F=|ih%jC*hrNyz
z<j)bM!!`WO*dMp7KEES-IlllhJrN2u(F;eFV=vrJlA+p?u4D(~=jGGO|KElqo%34R
zfS7B;zVip_E$Kj~&qt1|^X25yNTfbc<u46PI=GsZ(JexR@^o?NQMuKA2njSMlN77P
z^ycE^1B+ByE!}Vr6Wtrq!(r*c4y&g()M-Ah37M6>0)F%5Vs>{kIv);TC;D!gA8rEs
zFmI-P*!ySRoKvH-d5_iBY&apruQ@I9)nYN5&8E}I-AJw(Iu>R}hnse~C&P;?48zyC
zRGuEIYmw=EOw`hW@gdS0zQAo<Z1jPLR62tTSaEQ5eS0^Vl3AVFHZMj`JLd*#0Bdov
z9*EC09<#F?1NQ07bcxF*ie{lGTV71mx}0NRMPa6=w`QcjL`nXx)KV1+?PZ^DoBzJN
zc|u)Pk*+(6d)Q0r8`o+Xa0Te4pXiSk7|n~fis>_~gLE_;)GsrQ=v8MQtbp{kQO(8T
zw%v{h$LNLdxv`oYjEW2K<RBX-AEOl;U}opB4I9rkE?nPG*}jiE=aUVNU)2P@clN#&
zKi&K0*ITPru@lHFYu*as39#;5wB!i;?9~$>cBm@UX8;)s$VIWZc@g8R>}=8y#HkSG
zn`a-2TE~aeYv)H6>f@2eN3E`gba1;_YduA9tq#F`?ziK|>REi;`gV0Lrj237_3GI*
zYd!LfPr5CFLoYC=BhC7a1CmyoV>c4!nI2}NO6A%o`Q6#ejAmz@{`pPKUP^~p8uUyI
zX;fH{=>C#3k~7#|`{H`C5GxMaeAMxosJ*$`^sFXoRV?l<26bydHp6|Y62Oy_!TIP4
zwqJ2O(J!Xg#`iLw3Y!DelNp=!uI6`Far>eJRB~hxu)$Kd-#<ASz|sHE)8(?^UDz%F
zXLVrB!PUiwm#lwehCeO%9!x@A!K#T1ST+HZo_~i^o=;29{cD3o2Os#diT!Et3gMLk
TuM~Ktz$*n_Dey{xHWc`O(cS1K
literal 0
HcmV?d00001
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf
new file mode 100644
index 0000000000..1f79332020
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf
@@ -0,0 +1,10 @@
+// /** @file
+// Platform Logo image definition file.
+//
+// Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// 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. <BR>
+#
+# 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.<BR>
+//
+// 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. <BR>
+#
+# 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.<BR>
+//
+// 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.<BR>
+//
+// 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.<BR>
+//
+// 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. <BR>
+#
+# 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ACPI_PLATFORM_H_
+#define _ACPI_PLATFORM_H_
+
+//
+// Statements that include other header files
+//
+
+#include <Base.h>
+#include <Uefi.h>
+#include <IndustryStandard/Pci30.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/HighPrecisionEventTimerTable.h>
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
+#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
+#include <Register/Hpet.h>
+#include <Guid/EventGroup.h>
+#include <Guid/GlobalVariable.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BoardAcpiTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/AslUpdateLib.h>
+#include <Library/PciSegmentInfoLib.h>
+
+#include <Protocol/AcpiTable.h>
+#include <Protocol/MpService.h>
+#include <Protocol/PciIo.h>
+
+#include <Register/Cpuid.h>
+
+#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. <BR>
+#
+# 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// QEMU Video Controller Driver
+//
+
+#ifndef _QEMU_H_
+#define _QEMU_H_
+
+
+#include <Uefi.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/DriverSupportedEfiVersion.h>
+#include <Protocol/DevicePath.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/TimerLib.h>
+#include <Library/FrameBufferBltLib.h>
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/Acpi.h>
+
+#include <Library/S3BootScriptLib.h>
+
+//
+// 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. <BR>
+#
+# 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.<BR>
+;
+; 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.<BR>
+#
+# 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.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _8259_H__
+#define _8259_H__
+
+#include <Protocol/Legacy8259.h>
+#include <Protocol/PciIo.h>
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+
+#include <IndustryStandard/Pci.h>
+
+// 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.<BR>
+# 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.<BR>
+//
+// 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.<BR>
+//
+// 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
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#45749): https://edk2.groups.io/g/devel/message/45749
Mute This Topic: https://groups.io/mt/32816099/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
Sorry this one was intended for patch 6 not patch 5.
-----Original Message-----
From: Desimone, Nathaniel L
Sent: Thursday, August 15, 2019 12:38 PM
To: Wei, David Y <david.y.wei@intel.com>; devel@edk2.groups.io
Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince <prince.agyeman@intel.com>; Kubacki, Michael A <michael.a.kubacki@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: RE: [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform
Hi David,
Here are my comments:
1. All of the copyright years need to be updated to 2019.
2. Please remove " Contributed-under: TianoCore Contribution Agreement 1.0" from your commit message as it is no longer needed.
3. Please rename the directory BoardX58ICH10 to follow Pascal casing: BoardX58Ich10
4. Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat - Is this still needed? Can we just use build_bios.py and delete this file?
5. Please rename Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/GitEdk2X58ICH10.bat to follow Pascal casing: GitEdk2X58Ich10.bat
6. Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiBoardInitPostMemLib.c - Please rename the following functions to follow Pascal casing:
* X58ICH10BoardInitBeforeSiliconInit --> X58Ich10BoardInitBeforeSiliconInit
* X58ICH10BoardInitAfterSiliconInit --> X58Ich10BoardInitAfterSiliconInit
7. Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiBoardInitPreMemLib.c - Please rename the following functions to follow Pascal casing:
* X58ICH10BoardDetect --> X58Ich10BoardDetect
* X58ICH10BoardBootModeDetect --> X58Ich10BoardBootModeDetect
* X58ICH10BoardDebugInit --> X58Ich10BoardDebugInit
* X58ICH10BoardInitBeforeMemoryInit --> X58Ich10BoardInitBeforeMemoryInit
* X58ICH10BoardInitAfterMemoryInit --> X58Ich10BoardInitAfterMemoryInit
8. Please rename Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiX58ICH10Detect.c to follow Pascal casing: PeiX58Ich10Detect.c
9. Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/build_config.cfg - Line 2 - Please rename to follow Pascal casing: BoardX58ICH10 --> BoardX58Ich10
10. Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.fdf - Line 295 - Remove the TAB character.
11. Please remove interspersed trailing white-space from the following files:
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgBuildOption.dsc
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgConfig.dsc
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgPcd.dsc
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.dsc
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat
Other than that, looks good! Please send an updated patch.
Thanks,
Nate
-----Original Message-----
From: Wei, David Y
Sent: Friday, August 9, 2019 3:47 PM
To: devel@edk2.groups.io
Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince <prince.agyeman@intel.com>; Kubacki, Michael A <michael.a.kubacki@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform
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 <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Agyeman Prince <prince.agyeman@intel.com>
Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../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.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiDxe.h>
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/X58Ich10.h>
+
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Protocol/PciRootBridgeIo.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PciHostBridgeLib.h>
+#include <Library/PciLib.h>
+#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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BdsPlatform.h"
+#include <Guid/RootBridgesConnectedEventGroup.h>
+#include <Protocol/FirmwareVolume2.h>
+
+#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"<unavailable>" : 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"<failed to convert>";
+ 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. <BR>
+
+ 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/HiiImageEx.h>
+#include <Protocol/PlatformLogo.h>
+#include <Protocol/HiiPackageList.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+
+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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+
+#include <IndustryStandard/X58Ich10.h>
+
+#include <Library/PciLib.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/PciExpressLib.h>
+#include <Library/PcdLib.h>
+
+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. <BR>
+
+ 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; Index<MAX_CPU_NUM; Index++) {
+ DEBUG ((EFI_D_ERROR, " %02d 0x%02X 0x%02X %d 0x%02X %d\n",
+ Index, mCpuApicIdOrderTable[Index].AcpiProcessorId,
+ mCpuApicIdOrderTable[Index].ApicId,
+ mCpuApicIdOrderTable[Index].Flags,
+ mCpuApicIdOrderTable[Index].SwProcApicId,
+ mCpuApicIdOrderTable[Index].SocketNum));
+ }
+}
+
+EFI_STATUS
+AppendCpuMapTableEntry (
+ IN VOID *ApicPtr,
+ IN UINT32 LocalApicCounter
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE *LocalApicPtr;
+ EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE *LocalX2ApicPtr;
+ UINT8 Type;
+
+ Status = EFI_SUCCESS;
+ Type = ((ACPI_APIC_STRUCTURE_PTR *)ApicPtr)->AcpiApicCommon.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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+
+#include <IndustryStandard/Acpi.h>
+
+//
+// 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include <IndustryStandard/Acpi.h>
+
+//
+// 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/HighPrecisionEventTimerTable.h>
+
+//
+// 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
+#include <Library/PcdLib.h>
+
+//
+// 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. <BR>
+
+ 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "Qemu.h"
+#include <IndustryStandard/Acpi.h>
+
+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. <BR>
+
+ 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. <BR>
+
+ 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. <BR>
+
+ 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:
+ <http://www.cs.cmu.edu/~ralf/files.html>
+ <http://www.ctyme.com/rbrown.htm>
+
+ Copyright (C) 2014, Red Hat, Inc.
+ Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <IndustryStandard/LegacyVgaBios.h>
+#include <Library/DebugLib.h>
+#include <Library/PciLib.h>
+#include <Library/PrintLib.h>
+#include <SimicsPlatforms.h>
+
+#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. <BR>
+
+ 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. <BR>
+
+ 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. <BR>
+#
+# 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
+#define _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
+
+
+#include <PiDxe.h>
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/SmBios.h>
+#include <IndustryStandard/PeImage.h>
+
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/UefiBootManagerLib.h>
+#include <Library/BootLogoLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/NvVarsFileLib.h>
+
+#include <Protocol/Decompress.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/SimpleFileSystem.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/S3SaveState.h>
+#include <Protocol/DxeSmmReadyToLock.h>
+#include <Protocol/LoadedImage.h>
+
+#include <Guid/Acpi.h>
+#include <Guid/SmBios.h>
+#include <Guid/Mps.h>
+#include <Guid/HobList.h>
+#include <Guid/GlobalVariable.h>
+#include <Guid/EventGroup.h>
+
+#include <SimicsPlatforms.h>
+
+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. <BR>
+#
+# 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
zcmeHwJ9Hz-kzh@gFoN)Qu|weq&F~F*XbyPdaEHTfE*dKcjU5ohf-&!%BU8pXGG)q?
zD^tc9GS`(UQ>MIoGG)r#cb?2OW$Gd_vnu0Pg~E?y>sT{Q)F&%4G9u%Xk&#)e|2h0&
zn&2`0PLf>1@BjWNN&Xl7`zYzU`~UYcP5w_masS+n@=v#$bm8A8pL~*ZKm9cM6#l(=
z^C_Iaf!{aDCtrS<d<p+Pc?<u(e4D(*e{bKy^(^^xHcMvkZ-xI>tK`$wx5>BPew+N{
zCqGF({r0EHo1gqN`6>SUDV+cGXUUiF?`J>zS@QFr|2+Bf=f6mP@rz$1Z-4R2<d?tv
zW%A`Oeg)^hN`Cb#`2FRtlefS6b@J<9|2p~dSHDSq^PAr!Z-4zC$qfGe$A7@@Z+@Hn
z_P4)H-u~uyaQ?gGcfW(*-~K-N{qKLDtbX^0<PU%NLo)l_AL0Cu$shj+zrX)e@~1!j
zDf#vfe@_1V=RYT_KmKR(E&Th>|AgN^{U!O!U;dK(*MI$2^6j7hn*8;ze@*`Ox4)It
zdHsE*z$*n_Dey{xR|>pR;FSWe6nLe;D+OLD@JfMK3cOO_l>)C6c%=ZLK$`j}9J%#+
z`g{~f-@JKc$n%k3)||b2c=-M+LnK+A>$>;;@$vEfKfY?L=VAb__wxr}$K&JI&mkaS
zw~kS*1G~9@9j0;vimRVfxy_Y(?c(tf7y|!~-77nSYEzvqlcpIQf^ZIl@W;O*3M7fT
z!9kZ0_+7Z-@1+@3FK$(@q_Qx*CNCLHfLrh%DN_M$JaLeE@0@S|JKldEOG8tTLJSzc
zYJ|Dn!`@e*DIXr+U-e-^H5^DwWD+9bE5=`ek8z`XKS_FDqrkua>L0^f)%(?nEBo=A
z_fYpY?}i^&&`AMu>PnMqa+)M3U!$^re1FlY5cqf;0Cy_D)w70^J`w{D#QyQ|9Rf@{
z8kVb`(W3$AHjlEeUB&Ltb>`mu&NuNEoIQM&cK+Snc~b#~A`kH2n~2dD(13?{J;ulG
z|Id&fV>kskN%9G{)3wsUdQ;W(-n%jm@Z%%a^j$>b;a#Vy<Dc-|$FJd0z%bzRz4!P4
z{sCjp0*YfS>J9)L?rr`_zY37>O@Q{_-78}U2meqcS?f20ZdoD)$&5I7LUsP#5!2mA
zEIv!W^NqXXbtyvT1i?FFELrj6Q@p|h8in*2V;#tu|Ax1|Dk=1pD}m+Uwxe4Bj5U1+
zJNV<fsLOyKaN}*L9!@<z9mh8h<ni$wkx9P7lK%h4Z%*B<7Jsrp4EO5e<5xcS!ohMF
zJ_0O6y=;Bij258V7V**nn0p+qQDwP~>Dq?`cmO&E`M9W{0!H{GGAQ{1E-QX`E<5s}
zixRkn@-arZCEI?0@4(@!dEW!@f%90CZ#9t*CtDBKkZs|re|+@#d>x=TP>&8u37Fif
zP;WRXRfWgu@yZqbfd>-qeS<tg%t&h+Aa47}cR8#P>jS!=`3l7Lc);J!$~z?;OIihj
zxJtjk;$;D^S?~^kMG7IeoW6RCcaSk~q(8<IzH0o9OmK=1x&^#M_~DWL3Z%@l%Bx4@
zQb6AQ0u=1$cz8ZPP&8e|HGe+wWG;a{KAZ!dmCOWS0ZA+r)prfR?Qf3}ZHIRt%l`lv
zzO}JApCzUJ@O1P=5WkZCa0l!MTn7vs`QQIzf_!;+1fA~c0XAemf*X$MP!igY&BDW#
zd-rkbYJv*{4EhQVuCL$*Dm%m{luAOUt{}bp7>!hUi69=~R-0q&3OmUD4Bta0ky`-E
zBMCQ&c4z~>MVXJ@dBmalpL?R*f<qBnTQ#X(J_tX?h<1tLTfD%Bj#$v8##j&Vqk}Yl
z@AY!xHNnH@N%pU<a<nu~HUmE#yNG;vNkH|7S}oL&{>V4s^ECYzID`MbpMsHs!vn@!
z&V+3w2Pj#D`tZXJ_M-sGAqlrXPlBcONaEABVz;s4SiqS=@9#jn@OTgGC#?-dgT$2G
z--!^SMEK$C2MRMB*}oyW&Rm32W4K0r<wWA0cjG*hKmZaaM^HJ~Vp3Cse}#_#BI4uv
z?}PKYf)sz2zQKnMuroQOk$1S&{|Qw)?8fju9MHeU6|8@9k`j?5-ef({?Vfmz{NTul
z6~lkvK)7~A<pUsHuchXjkS)~s1>zt017ZiRi1VxPE@+rB{(^ty{I0;Y<X_;P2a4d3
zzTPsx848;6ue=%x{w`7+O9gX_Fu@+d-G_0CQt1Jgj02h4c>L1?!h9HEL8Lugef_t;
zp{PGRq8g8|BDz@ifQQ!rNT?+7E-FwFyj#SjQa(^$Ab&|ne*?-yfnolYlQqW=01AB<
z`2nRtKFVKgL(mTh)C&}X`>xkSc+-}ThiiC5@cGo?>P&AiC2xWXLl_@<ZAS2fn>B~y
zEP9hpAtG3)%foU#Ho^kTkU&H`)PUUf_74!O_alHGC?AjDQv~}Fsb9)RL?Ea%Qe=$y
zhXSsny77dg7WC*bJj9k_&vlFfOrd>PIjS`$P>+v5YSQ(Be8ll!kPo0&7$ISGu3jg5
zXsxgbZ_sH7fPv9?AP+Yl!AUOpf$xFw@~#>p8DWL)(2C0&tEB~kMLm!50Ugba{s5Us
z{jxvCJA`Zj-WP~}DDcsbfH{urt^(i(j^2?UIN(APg@+Rg<Px4DH&KuPFrJR#rf;?B
zU-?Il{bQ^byA-_PT`lAX@&y408LS4N0a^3MwID!3+5?Pt9q;bCP7`5;K~m|xn9z2*
z>AQp%c031C0MSbO0qqHgqY^dWo@^!kv6Qptfgi3X1$_k|p?4zHpiv*AdsRkDKJvp4
zCm;S4$mS{S0Q*XVe}%Ys?dtt2B$q2SM)p<m;qHcx>;OAaaYNG3l=>gnf&eMdp2>%o
z=g?`O9Y^r5u=@fRaNGm>3J*Lli5*cdsZ`zZu8ix(;hvL#HxLPh>lAxe&{qJ{*>j-T
zxp#cZ&g$A6<iop~AV{7GB|qS0Cm%j|=!XJm&x4gg_WNFq-6+ThAcfEZU}xf;_f_Fu
zcj6*&ffzxTI(}$a&VJDDSqF04`;~k^V}kt%@&V){;uxqD?;wMq2+^Qppxxuh6E6KR
zJo^TR`e2}fJ;%pzH=2)NKVbCl)CxWd_5;oku&)D1;=FPgmV0jy`9Z251JJTdy~Wyq
zmtH6;zz^;0#~4uv^5JwTigFn02i=EN5hSti9rSSO-H;DQIAW}^{cyxP!JbD3d3}ZN
zfu3>%iSkkUSMU%B1_L+W2G?fj#&8u}NoPMCO%bpc0?=+K7Y}~e4JT-u0UxXixi*Gh
zIGlXAVJO)1f5UnLVAmAXaT^aO;V4#6*vZF3u;&2GBU!=<_5-pV%C>9--mZXie*!<6
z><6ePY@xE}kwK;20D^trTk6uDd-;H-I6}j3nY4jg4Jiqz_FYR+BAt^PLs>wQ%xgJd
zuaCaq3@Yg#m6nMlC-M;iZzf34d`@{+@&UT97RiyDq}mL)eTmB7g~n9&qa1%k>X+@0
zcN~L|v{hZf8oJ;_91jwI*R>1&c*9b?=T1I#{CK$doA3Fa^Iix*K76-7`y2AZhl_)F
zV)bLZ7vzHj#VZ61{a}RWn-1Rs@HzmhX9EppR<NKCVs~(WK^wdqVOaV=2iI4w0|Ppt
zIwy`^BB_8n5%nFE+Vim|sk0j(?EnkM=Z?wf@8XTm(ykMU(x6w32r*QA!#fI&(Y}s%
z8JG`j{I%nUleUr|jvrWW&@vUk@+4?~he~;`_IK<^?429bS8y4eJNHTn%Lg#9*7CTH
zvy!#I+dZi4ITWwt!;Q9}E-#LbA)Yjk7k)|_=v=X^s>ew?VhMH}q}|yOjAp>C;O~NF
z#yA9O<?1bWQch96hj1!!U7!wN;=4}JIqyD>^5IJP;pZ5tf&&e%Iy_*QiUz=&53jF0
zKcc=W-=nYsIgn-8;)nM=tM>BEEq+lx0HzyEMf>5ZgNm>&-%{+g{t9lO2Z{q^IHbM`
z*G@jd_yb-H_8bRQuKSk*!hmQg9d48mnp*l-*hR;_(GTAb;}3X^lo~rkeG_=gQvmFd
zRszWjhAU^!12IrO0P{*dI4txuT(wvTk9HN9wX&Oa@)6pBRUs9z{jO#B2apT|0W}|?
zx!x77g?xYoeuJO@k^{u}k%mMkCs-KkcTFw*D-<T2)WzyQ13`fw?_VJ%&Lj7|+IvM2
z8$1hu(W3DOHCG4;tHHjGEr9ci9~@Rts;<04<eNba%q?$69fkVJH8<D~#0F79&0O_I
zk1z(LgTN4fcZ_8NKb(9-`vJYjJq1WXJ|dcFIfWix4m}?oH-Gx>AH4AdLyq#{`yxJq
z3oJFpli(sous~4&?4EeHm_DjGuOLB#-H@`94++clDgch~-QR~%4a_ZXoBkCN&DZ3r
zLx0rWDes|tkT7hh()H88A0i*fC8w_dRwW<NBk4eD2*QPbo|mDisQBFJ<GTTtz+&%C
zTsa&|c>Ceh<rrRt|D9JvT91IkL4=qT(5IEYf=6Co1^EcD5MYHQ!UiP2hn@=@IBR%-
zqp}|WtFj-y6GJ`zKja7YM?Bmeln-~qyQKjQ=Picuh?5VeC7b|K`+<O>zAE9u%|Nwq
zC-4Jme0K&9zj*_#et6@sD97h`1Bft&$8hRQV5CTJh>=)ChU0VV%=M_?sZo7pB8il!
zkfcqrAh*6}+mGPgx`sl}189H}BH)j}54=Q-!r@vIu8DjAsi=Ioj$OGsp%+4tO2xaH
zJa;@A@7_U0@B0`S{^0}GNyq2N54<P+-O@J=MybTH`PcQRAZcOR1MP=bT~Gx>5=r5@
zkjrj)I8fd-%17C`VCV#OVn=gIzUr~qh_csK4RSY_d;ndlYaC7aVc!^Gdi&u#13!OW
z>MQpSV(@jC!L0-jJGHO$Jr0n+c2gVgoL7OqjDO^YKdv80eFcF15dl}I*Pe{sD?k7!
z5mH}}AO1Exi?Bk6b&}`ncg|!j<kk<Ue0bheN}kTnmhurr9|(d?*7D&5#s@4=uv}xH
z6kzQ<12?5q%15B;<2Rp2goEuu#RszFDuKTj<+Lo4#qq;+9<1JRT*wE$iSJUtWfh-5
zYAM*GfBm$)QT>Abz&1HcgflqsAMgWu5ZvXkLWgzQ+0_rCbC5_DlMk%bIV!X|kFBR1
zizm7UGkyU6V~nr?kub~3X?K_*a#G{4K2QCisvHlxU<y$KSeL7*Qq4#o_y?`^u`9gt
z@pgFNCD>bGZqHp3qyX$2@~O)q!gn7Ovs_On_5%t5KYXrA)Kw*tfR=0h7;!`leFgjd
z4HR)*!k?qKx;|PdpMU`Nmq`9nK4SH*HHaGG<}M)F)eo&fP{!^FfI#fO3U8GJ@RyE}
zUJ`v%LnnY2z<Wud!}_DLA6|mT?yegpIXKuI+&!Qy1?<kDTYNMA2RQxi7(~crlK3+C
zx3V8_j+PB71bzT4#G1kKt@qI)Yy=cIkbFR$0PF&pTggh$&V>5<j-wS*X-?W5y?t*+
z^5G@uhAy<#pTa%35!!~+t5C{iV1mYWhxhGD`EcN%2$~F^=K(K7`{Cr(QSkxhx?BhK
zP<#d{2aFVlA<0*jrTY9EAUEDEk1=8w^c8p{NE+aW8;x2>9z#AVn*ohM`2ZaJpbbx>
zG*rE|M7_Kb{9C;3I=gES_)5-k0$}byaR^Uc4Q02CNerd@0I7Y~b9FnOBLvs^$Bub$
z75GtN2>0>8QLFd09>41N&W(cPMa8}2T1dwt;EN-y>hPM+OPY`GqI~=aiQ=5P2+JWE
z2sFmp52df1Jr61~%15vt1a~D4;RazD_EY~K`mVuIz_vJ7wtNbx|ELV^1)YHTxPg*j
zsy!2&D!@~uh4<7#HX8a`rGMqPR#6e5xEH<--mY6}Hg>%NeE`ho0)ZI2=pyjqGw39h
zn~hBQ!dK@w>v4lgFvl2l*)@{h-^Kc&-G{LsOg@mB&YlAy@H~1`Wv`9m;EDu^#kN!u
zfb_#~5i}0L0Xv*_!b?0J-bKF#@)@v%Zz?`RQio6-_JvRfYVq>Qm5&$L9mc*MFCPxz
zS1yiN(y#>V6f)of{DAElzd<7gfqW_;6=$IWudgt4>gB_Cni5t((h&&ihvPu@Japq=
z&mCm1ukbWdpK5hL77pyY(0C$3{(k)XJ($dffm~Qa5%0${udguri&VnWpkW+fU^Ltd
zr!GDWmwr~N8V^EoS89we2CYAKr(bpaoSvg~1sDOKrW`-K?*e3}G{0t%czhdxxdkLn
z;X?2E*tzb=TLVe&?_&Md92>l_^-;+Oyb0$38r3JDi}FE~k-J01A>1G$v~}HRWUwuj
zd^mL;>PEofG}s1^I4{6hK6rpw%2Uy6eV>2zwHuBKz$sSeE!q2C$%h}XeqDA>Y)NPz
z*bgDZ6iG)QtRKjBD1C(#@x~DCxj!%M2lfen0D8!+$f0n9h)`Ly{jblz^77$5BIt#o
zZUpS=fNDdy%g;t3nX5-w%2Uxd!9y9la7_@a3NS)OsT*S>AAjW3rn4dy!oEY|>IkRG
zuo&<jWi7}@1&b2M^#PcXs=(}X0tf|}K<@(&CLhofJx@Y+!5LhiVFef=_acLKz`~D#
z(T6EBrvRL*$#XuOmcxYdGVr66U`Iv&LZID+2^b-Jeth$<Ujy!V4n9KZd*c<hC@kJ_
zaRg*3z{J}%NJ9Vdfr>KZumc(BD?Z-tJC{q9a<Wpg->t1h7Wl3TjjrxM;}CgF>)ict
z76H4z?}d)NW!+_^q!MpHoIH_IL2Q6>kf(*DgVtDpOMZL-_5&9^;iw3BN%#?h_>S~r
z2MJvo3szZumimR!dJ1|+q5wj0c;&0)!=nV_xt`b8uA^XaXfa7>-mz+U?F)qU`1r$*
zLq-o0CrAMbUMUbI$$|k9<Bzh`=V|ss*BEf`#s=Whet3TuEQsR=b$Ek+@%YupKCa-S
z&K9gtXGtKab}vI3DHw#^Ig9Zes-p+UqPT+#Ze0l!`rVJ9Aga2ML<Dd+#k=mPB!QI*
zNz{(BjzCb}O(c41Ip7{d@UM^)Fcd)z^VV^tYCz~8;YIktG7U%~*Re4CZ8sxa)l_#<
z8bf>@&p{lqqVhk)-%a3`Hy~Rt6xoj-*darET&u!J5351Izz;k{r^p@OaY+?UUxi1m
z`p}O`P&kOO0GHZn3=RTjZ^OF)1*@zMH{>i4!e4}M!3x!55npYEV+Cus6Q{32Kq;O>
zb@YH<;se;#O}C&BuN*;ks~X>ORXUd7AE!G)-3U0GMpfWOG;Dm1K>SdFLoom&yayO{
zj9n|<V~Bsu$L9$w*z(+PML;~9WE!v{fw03oKK{52IUqj!94He2&}ry+4%Ol9@;@gZ
z)fL`7kbF3|3flu9;c(0ibq9VxWkeNteS&?Fl=2!SLh)VIhbk#xcnc^?I}luoevKY@
zfCN9KZPBm@fe`T+quhrV_^#*u<B*@DVju_F4}ND@-k{Cf1(%Qh8R|g}!~Y&usLAoe
zRf;-19NvI9et3LB_1{DN6QBeNYrqKOpC2D0?I4AxjBJ(_B=I#EqLelv-V{h8jUL{O
zOZ!$q`H)Y(`vns7@yGkM>XWyQK@^G!7$nTke{{y6lNCFFkl*`fr>tq54T5S1LGnXp
z)3I>>)M+HAlfq^($ExWSZaWHiQL^UG+r9r<>Xibo6nLe;D+OLD@JfMK3cOO_l>)C6
zc%{HA1zsueN`Y4jyi(wm0<RR<mI7I)+w1jD`u*-+87A9S`&wR7Ano=C!?V%l_3iEb
z{r%+rW;FOa;0S&Q;lpc2);k$qT;EL>t9)G@`ShHvqL2)H`PbdS`Diq{I6oVn4o>>r
zxL^EBMm_EHPe-@YWl=GrI>|@X8kd*cf*Rb?!Obi$)<sd|tHpeBcRe~Aym+Q``opV<
z#S6!j;_Snd^^!a3`J(Dr;iOnhZ!S(>u4T-+gUcz=P!j+3dj7#q>8Hb*hUL?nGZ2%K
zZ7=6H>z?1&;2aq<{7?m?tE3|~s#xBh^<J1YN&A-#7+1I-Zbz=C?TFb$)dc%wc{6xP
z9O>UIZ9K)@`wvuMbtj@B#^sEBl<H}Fi>$3JH`eP9l^?w}!e1;d53|}v(s#S--u1$8
zZjBBEw{AYrAxLj!w@2J97FYf4h<EVPozZNg6^~fEJy;Ho!|?&Ok`HWVKEHZa85vGi
zt%YN~UOX$Vd$6sI{Rq8oH61;hk?dW~x8TNl?e^Q)gDlVX>PG)6s(|%+dH+0aeR?+8
zLRGET#fNG=pd0k(l;RuCi~034n33M)HaNoI{OZ}{cz?M{&)Qk^z^VNH?1_i$>EN~v
zh8TQX%xAON{q^vPG2EXC6hb=MPBkyC4z>3&#iI7Sb2i;%Ir8Ofa(8n%g7`E9sQVu@
zH-HZ5@NTxs^Ss#9?jRz?-RaXcxqH#9tBNHE#7mBS)^@ap2i@W5>iXv9_I@&*v8kOJ
zb259X37@oo)ugNP<@EMq@PUr}8u;NK!FB>L^?81IGnp-6KBVbbUiP0Newv=#*85e(
zYJPX|Bxr1;+>r}(PR?&&3bctK#qG)Qbyhm453Uuf+11HY^ob+Wx-Iz5>D81@N-O3}
zj&4NK;Y`&UZWQ_S#l$$<QgrWf+3<GJptt77o)bN*4Rz+TW7oYm@s0za*W?Q?jvJIX
ztDWeWyA9Kh)8dy7H9N2OH&>TO#QwaF9m~tVSBI({H5)jxx;~mktz$=i_XLhaJHk9y
zskD1p*H@3mkUC{Gzlb06eJ*-Df4$kDZXB?>IfjI!L%RdycZ1`5+0Rez78rETXZ8s3
z7!r~WY|jd2jgP_o7R`ToMY6$-JwRMt9hyezi9PPvkd~Xdyz29d3zzr$;u9=Q7DGPr
z>F_+X0g^<UNDIENIXqj9n%*+2ZM>QG@2z@@`}zTB+QTr<-DEnSFP6(C#@!*${qp>@
z_u;5FNPxY#gb3nnzVL0BO?~QaEmN|ydsAmE&kx$_-i=jDep?qE>71NhL58~?xk4EJ
z{_1@20XP6@_w?fWex}ori+nM?y*#UNDIxLN)LDx|PEmC(tq|hs+D=f&`e#>@hAg0B
zIlVqVdD#P&&fwy9Y7*A#iDGeoHMD1SdRM07GlMUv9_Yv}tQwYArU-TiqkF43*LSPQ
z<!P<Z9|-N8!KA(6b&EWv#ofh;CFq@z>H6H)DU)sSOox_{T3%ZG?hdYMoIcJExLRDl
zOpc_zv)j!b$~7mSURtU*y)YSab0AOj#E7sL%aOs>&fwa_MDfDkSlygj{mTISbhm&T
zn-le8dy4s`Wk}4hYjK#MQuiiSU!7U(NNY4_^^!hW-B_)8I_j&MI;VG*snnRqJ9BFU
zc53y@<slL@(@VpwEiY9|((IzahDY?p*^3%arYE*@Bybj&#mw-X1{N`9Zi`k$x~*=U
z8OCFEr9h;8L#qkI?aS%&<nyT(z~^pky>FvU?-qC3G?)@{zjvlwZ%Qln=eZ6cXQOS!
zJc3<azl>D5{x*gqqVLXDS`}FgDQ--k)aV;Ex6&I;XCw2oZ;wg^(sh@`^gtg5uW3ZP
z+h>-BsY6-aFK$(*vW)t2uW!>Ni6y~zau}GMZI`{L8na%E+R^NIrLt?oOlm~y?-Wxx
z;4|Ic>FGXg=o{K<B0Doo#aPjlden_4%Y6lTpH{-Vy*+eQXil+^=^WWek7J6vJpvP{
zF~u^I=C`+tPoh|o-%F|6lfv7)o(?wVzbb@{8%vop-Z6x3p9ytiMo<MRo6_S9oNI3t
zlV{uFB(;3VT0|QjtZsz=)VtN1V<z=W>z>oqy{5Pl;x=d&bVyj7+~3|p-s|0DzCo=i
z1>73Z{R%cDBRJY)O#03>;eI-AUJ$mrJ>j?**@MO1u0Gb4_N}BXZ)C@EayvSQ<n~^-
z+l6hHPR~X+O>y7#^Nd8YrtI*10h!^$)05DK!Rh&BW84>}AQ(fe*xzbLAFHpe(Ol@1
zLA{@gLG^(M;ifn*QoqB=diD&fL^}1!QxH_Y9QH+s4fX}OxTz1tL#_>DNH)@b+iWLO
zncXSfw-U2lClgg9XxGL4s3tO%^)K#f-Q%a1ka}g6&u-52u-g&4Gq|jsQ^@bQ4e4Gh
z8Wnmx&3I^Dq^AmwTtHqo3M>|P=W29BD(Rfv){VU;(upUp9pe;+PPTo9Re<$#(SS+s
zqE629Ti*SRF~f?>P^*S@_0VI^E9%<Hs#r}fnz(_r!!)y2hK?`?o3&}x$aJV%>Cjl*
z3eBv+bw@Q?E5BtvkCiAjVI?$deJ4Fv{U+xlkB;HX!8=8}HSsWsrsWS`7violJLDb1
z{lRAE(^k3R{TsUtIiESru5?Q|DO)tDukw3}J2oMhT_Wb{$nQ6HtWbOZPFp$vS3Kb^
zKs{T+7i|NaAYR%9#WwKhVn++%wtImYOW>DG2^sQ(yjjU1Y7^^6=72=>t|kC`KFf??
zDGIpzc5^$}HNlC3cglelkc;gGA$>K!m2<CoV0P}sc5-;Cgb;aZ%{{iG&X%RDnYMMY
z-5f<`Cz&sqsZF)U+HUiZY=nei$CNd;XHs&?T|M@Od0{Jz`Cc(lvm)!JnE{(`t1i=l
zNeXVUQ`NoKqisz3iSh!MEb3y;sju&tMzctu?sZL-G251}3T}%Vh64$*dAXe)!FueO
zQ65;*8!#@m@OeARR_C|Wm}euc5Z7xxBh!W|*5c{iLp&{N3`J5aabdZoTKBN}cTAJ`
zi=4$8Qtdfxk!_-rr{}E4+EbC+2w<dJ$6`o+9Sa=k%&JxeuUppLvludG0&t=<R(k=-
zE@k)U3G>#tytvt3S^3s>tz^`F=QTGH(wItE@5&CG&XN=ZKkbIv^z>SJ#;pb9MET3i
zP+Qr&`A*8pQ>|yjk=F}muQrl*+X9v?U&;BsEr41KSuy3;Q+b<hCqi_t2v4^%LOywu
zlbCgTCvep78*FCJPita%TM((fXwOJa$}e}7aIEJ<&lRmX!IgJiwDcYHT8{~pyq=Ex
z7E`7x2_3p8XP4J^um{Uza({Pyc_t(9zNoGdY$A^W5t#d*n(pDw3fJRfjHL=T&hM#U
zc+0dJmCeouXqn>k8s;rb8g&NeFabsMCaj!*FHeXG1$fo;;oEi}v+Bm1S^)t2XZvou
zqPKVlgG9YjmEF+p69e5_>Af*!WDI|n<|YJgcMk~)V|CX<F--*wv2vAGMj9ri^RD0G
z$V^+lU1Wjc5zaGX-3OzbwlVCn0n*)4=3zA=MU9w`Iizh$bzj^JrK(OZh!~YjoHtB{
zz=ti)&QHzt7X(}DG&MBKIyYBOSg+UL>*^6r&P;?-JS(#!^BOX>H0_=m2gNNjLcVE3
z_r<kbTa>D5fh)C>Apn26DvH(gs%93Fw~1Yy7=wj^4R=}bEiR1d(isi?^wc8E7G9}x
zc5}Kmw4)tu!+3OthW}FbdjC5+6T`<$nL8+0vm%ac`efynH<GY>%@M(?Vk(engi!xb
zn-HF`t1L*1P_i=DEFV#c+}c>m+pFC>f{=ncAJE30F}YLNAJw7pgDtl-%B;~RA4=EL
zd()FlkEG_*)lq)r=9%=4k}0YJjhPiT3Uvru3V|@9I-LrS=G2(N<sM3)2lqI*m%oW*
zx(ma~xh*C<n&B&ggEprDO0^20cA!w!Gn8=_7W`HMx1OtU^gxa7D-MX01)sG^jMSJl
zQ@|d{bjX7f+k7^`vgO8VmXaD<|7t&xF<Z?KZ_FN5@oze&$yBJnU@-wizkUNb!40@v
z3MbP@7Y3UyiPE{^khU<!R%o1uu4QFgUS|R~uub=543etI;C-{@Qp;~vRR3M5NkN&f
zn4Bq=apLi-CC?k^7&cumtWZi}V<#(#YNlYY;6qt*=U=TIn1Gzhi6v%VbggRkk*0fO
zDkQcN9egY4K-MfcLzHs|MR;r(P}ZG%(Qb3P)QYjU3|eSX*>}=&Igl#uNlE41ZJ1e5
zLmH}&^e*O9nPIJ`MpTVUguLR*7tBm^No^$`5bRJ&jnJSvwH6mGSV*HPy8DTq3t7-H
zh>8tN<<OW`-BaR3&9x%-QfxWUS0yC*)io?Lpa@t?Sfou?eGHWJq^VV*f>R?+b!j`)
z6s0ZC)1g%A#VrA$I@7XAw$<>03V=>2;d8`EM@g3=zrIo2vZ=?ev4o|Vup;R>_pcCU
zaYL*oX+Ama8^$T8?IUIPIn}}A1wlW%5Xk40Te4mmN~bA_sfshwdH_<YM?;?cun1%}
zt6lve!e4!f1Hcd&nA(6q5gJ91&BANbmQ(9!y|l}{^i&E+ensF6qzanVi*{F)B@-V#
zS<RZKMJD!!e#H_tSb|R+3}FW*V+0P=UhvGWQzO>GZMqo^mcBC~0iLGTxcoRPfI4bJ
zi#Zt+D)DJhSju1%g_Nq4tQBDvwAfC`THc+Pp+nrL#pH-kM>=E)BNaA;HiI5BVazx~
zRMW5{YzXLc2(7PDrPvFCeR|ejVaf3rO?&L9fdya1kf~mQie`GjnAS1Bs>-K>la3zd
z!1r~S2c^3pRAy|FP|`5f=^fxmZ<Uf(f@<-bsR;5t5fGIbJ+B)QW=dT})t0Ip)D^K(
zpbw1YBI}jT+CQ;AtRtd0U7d@uUh`p_8n*&Jiu&AP%i<g_aa+?WC%v*G1I%p5P1$`S
zhcd)Ks2*9|(N`0TK;}jmR`Nn2G8^?w8jzcR56nss$;I-m3PGi_0o?kC3#>C0!XwjN
zs^``Y2~}`~#QS<O_?nAx12&N#xt(BiqNh;S`85$}AfwJ#1<-V8nk1${kl_N)k<4(A
z*9#F{u9$a#6J;aTGoq8U*Hq)H%hB8-0!hy}tzim>;jQ!G*ZEaVH7bS!pmRQRnVw2f
z#WH;Q*7B~Wqz6U(tk2a6V6pH)&N8)<f;bzQR9HFF{1pNnNdvNn1)p+o1gzeJ6B%-a
z0`*Z>^XqY9NnI+3O#o5Y^u${EuHu`3oa#%69p^u7%R$c7B2J?E(^G5=ISTIZmk11n
zBeo{euhu>j*@5>@q&8cxx%`xMxL=*F4ajkTNouWz<0@Z!d_ZTR_^>{+voM4Xf6<eD
zn=Xjz3Tm;4V}(m9d74M>Dmy3a#8W=XH(K1d-o&)86K+CM6-<U|d3eLJ>BjW2l5J47
zysnA{hdWWh8KOxu8R=MB=%~r2N!0(UNlQ8{l4!!L$Oy=2r0IVWk;Yf7uPTcSGHdcx
zrwC~7^K5+szx{8iusa=ED`U(CSE2H*5V3+pgp|L-I+)f!o95ii-T9@vYQ<mpd`V_a
zXz+kBG)|$nA+)kTGXO$Y&U;VE5Tqw9196AT+S8#>NkwFu^50h1<!kt>Qx-Qaa8eMl
z@+Ehm%$+p(eqPq{D%i}BBBzI{hDzfv9OO#Iy6N~psUkXl54EfH%L}5eq=&|)SoCVC
z7A;oQAw$GCy`v`c!C>?KLDX~tK*@<;=o-iK&_q1>AjCI-sF_wW)1uaQuHwj|1l18?
zRciFrj>v4aqM}LBCgY=H#MKM2)r2)p&siS2nf$pVniiXv(o7<`zew5sL;tF&Ju0>;
zxI~600TJnh<(CmdsmZyzQd5xa7B^XwiMa?t>FfZx<kH-ub-}z1*q$RA{#@s)#C9I^
zOe!q8KCL6?E_mz#@K7-@qVLq|XV%`1^pj;Ys;-r%M(};f*C?ftkf_i6!9T6nQ3;ix
z)P&*#hTJ;}<n!xj73=Ui(0w`ATF}%D846L0UDSRHWPH|>{xX}bR(-ggctEQq#z=0S
z-;iWh>M2hNF$0uJWA;Zk_xE>KL#?O}M1BQE`J}|-O=JXH#oT2SxR}HWB*k+!S*@}P
z`6xPqQD>RN3K=rt9k^%NbY8=WN^v#E>9A~0uLM#!9qxu&;!Ib2$o1$dgw+-1oCbkq
zD3u9-3dFBQt=nX*n1Hw!cUP^&yg7@#r)o+X*ebSkX^qkW3(CO}U81VO<s>%cP>`eH
zRZK%sNsdfkNa0zl@mNC>tyPdKD%bF?m2%6o7qW9{9)TfC5};_n;E0c8Dl|19DjGzy
z))6N;{kM!UU==K3Tlz{PU`6!m8$GmgqIm2zRsI`Ldqs21z{<!0FBI80CauTnFi+GX
zUfR)QxRlWp+$$L{BnCz%WwZ1ZHEqt)RW~<GXUs!fox7`gyb09i@yd>xv4$el;opqN
z;Y+9xHAP6SJP=twGR8wkgHrBT{-){#)M~Y8qiNH{2AoDhB8=r(Otd4X{(&EBdw#M7
zQU@v`J#o5Hg$_{>SDuZKNS&15M4aSOOJ+V)a*h!ii=d1%Su-NXa`fRH#dIvhqau9~
z4Rv4+ottZ*-*iiUcZ&warM+JB*quyAAba+z=|z@&Ao~EVvkBMuOsYeqB=zpFq%j@5
zUi0h)nbw40SePx=_*7?dR)I#$l|kntblG6i5}B~g*1V-M3bjKxLUtphB<T-GJ##*N
z#k!Q4t-6h`cX%!-t48-ali?I<?7_Vf;!b94WH6DDO3KxmgKgEu8h4ewt3o!&G``Bf
z*uNPDGto_C@Sf&Erd&{iE=MO!>!>MzvH)0iU*`SDhdB+>v~6_9bXWPXup?tOzz;Fg
z(UU<TD3b5cKiZ<bxttseP|GXh@oWnv+5M<{C4sVlhICi;^3KgzgS|G0y%rvMSItNx
zwc`{&)MF(Q$=G`vbPiTVuBD`LSUJZ{!@nv8gV<B0msvbRMwfO=;7_e}YH~lBfiZOC
zDY&WZI;hl`I3JAC?Ep!GPJ$kZoF5_ablpM83Q0BKqiF}J4CU>p9#U%uK)HLrlyFCF
zmZEO${U;V+wIk$#N=aY7AcFywQ%W_xoZ=&E61sxq`G_Ffl}Ycrdi;7BBzA4)K*4$+
zBTU6TsGiKw2PiqUq6GIRI8`ZB%)t^d9x|Vs&<!YDw~OH+DRXQkhK#JPSW@pcEzabu
z7NQ~clj$1N7W=&q3@fvuRM-Zm{maUz2z8?5WCK+#(zp;$QifOAeho6zw?_=m*r^7_
z;M~cwQn3ZKr3pp0+WT|uPwmYRq>81!kQ_<Vw#p@MBw0xA06{?}a`ui-6m7<rmgpM^
zi84igXq4egWX*52vpz)YJodTt_-F)6@`}>#ObiD}?xyrvm^PL&$MZS2Y^{u2x~?q@
zlC^}K@9@)+gD?amqNiITwtI0I3!=%Ba_C0p{L>3WIv(`X64HpWbQ>8hp*CszR!C_>
zgyej>M8}n3gK+B`bA^#`wmp8^zae8y#7|OdT*%N(4hLy;SBe00cf};{n)+<pW1q;;
z3=&%e#JX}K2Z|JYQx@X`LF<B|y#r=Dz9Jo7I+rcizmgsD<?IKUagwXfX^b+F8UJ+s
z=PoTUZMsN>v9cFv|ABf3BA*}Gx@Oy{?}FSe@5tDAaTTG+y~Oh9)5-}SG8~lqljSsV
zT_z2SNtIZ4+cW8RBO&EFD`_KL8MdOuOb%8V9Bpyhr<_bZpt12xtlJ~g>oOysY`81)
zPS|2l6{Y9y=?*PX(_27omd*mPcbV>j4B-PGDeqWfEhZgzKyHUu<Xj#Vc4>TL+JH1W
zWJXp7)XBsMC<c*Kzkicc8K88O<n!qr>uVPa7Fq0C^XV-%^W1^r&9BJJ7djx6)-pOn
zGF(F3G8yS3UI6R`ClocyTWm(O?y2Rj7AzJG(Kc)A0dCV}v<}%?Ji~mt9KF#&hIGs$
zdUDE%#6;!V4&o)lnq$Eam8Drn^@jU>Bla#o8ZPm5)aEM(Et@U_lnq!M>X95%(XBz`
z06k6~NFgA@NI7a@!*eN(2hj*}428tz3H6ZtZKRX%&pRY)!5DxM0m?%Wy#bDlHqq`Z
zRdXCn%N#=zzLNZ4={$0y5thc;fMw$&bB{PWkb<{U8Bjo`@sGQii9}*B(}>4G9!kp6
z8A2KPh`m{MH^N1k@Xx{}GL`x;fmAyL#UsaNM&g96YUxV<1z5(vS#uDIHv>_cCk`?a
zN!mEkr}z;A5cMwsBFEuJ(v_ADdp`+rA_=VJRqNOyEYc=97|R{=kfT>(nG<R2<J_v8
zog-F93Ka`qDT{QV)fLkJMt;c8x0%@sm(1&xx)z}<c%IWSd4aH%=Sp06iC#1XiXU-Y
zS8sHnHYp!;N@cH>TI2LWY*%G&PsylVGnk3%RQJNM)ywizcw{7@(l4SED1O9l*2oVz
zQfAa>g>OwE>l@YUl?Xve(Z%l1!@(UH48<a`*)^3P^0t(8nr$w9ujsnU<X$qalOn)O
zwuqPP8%`vINaai?QgY6hbfm^sq+<1n@vSS^>Ld0xQscg-S+@`0EbFi=Zy36YKmp}P
z{m`y~AI&C$Cq0rRx_w)h*xzU2dscO<9ey~q&B4qOV()3^0=|^Bn%@c;mYHQF5~a3L
zh+b_&+(XV0aTCEDvx29C?8%bU$TnOvZvw2P+J_Cp!K{l)qlt1R1~Ypi>Rvx7Cz5kI
z4XzWZ+VNu>`QXA%=1*yI(IJ{B7sMka<@Z@kYL95`sT{L9hVV6`wES-8{g{cwx60m4
zKAQL;LR4HnAcR#$F4}yXYP-hDBnwB$xUA6uvurx`@y*?@z!DwEF%J!5tAW^7R9o?*
z8uB*qL)mjKA4%G~m@HSz*(F!)+flxzw5%H$BEHXJd?5&ij&V2(kj(%k{pLVT?d@-i
z^aHkzb~k%2<}t|Ls*V1xLpkg8dOhh^v~Ns9N#omkFjvlXjqHHPGclhoV@Oy;PC7PV
zvH6kM`h_GvCr#sz2LGy5I*2M9gdb8N2#dNI*?mfM#gr!ECO;%S5c#ZFhEfC<^N8-|
zitL$sL7OEOlhdsfn#Skt`9TC;W^M5h5yk2l=T_HVaR(~3GZHB_nH77NAFrY>Y<VvC
zEuO^)KvVpxemuzBR_HyHAEIwPEkDfI`<x{&Bz8EM#8GQ(I#B{!(q9%o;hE6|<%h_K
zqUKK~X2igOlpHeuQTb0O<Z#5Gm&EEQ*O?suAP%%qP^&e?3)u^?lj>nILXnDZcl-rE
z)`TBY!0G&lbk-wjRg}K+yb}3RWa94lZ}X=4eU^y117+ECSYAaLVg)F35un@#Eml_U
zZ842COPv(Q;AE(Py#tQeDmfob@{gMUGNg`m(c=3oFw@~%ME{EARWbyDMHhU<^sX&P
z2ee)gylI5g)Sc_6mKwYO*|EsfdaU)RXQu|S`FE3(RHh9efyC#!?ZHg!$-B2f?l(>S
zD>>&x^Gl@b8Y6Ei3K>ViGDO7kuXb<47H`&k4TnK6qar+eA(iP)$TKmRVK7@?$i>NY
zF|3@Cp!rvFXcvbPGVPaS1j_ux?e|}3-LATVnbo!Bx2vq>RdGTAL0b!S)klr%aA>+O
zH}9rj;%LfGl%exDm9cC7ZWERVeAcyyExy}ley*FxS_fqe79}GbE4lB~4rphi5}N-d
z+1)aKcTIQJlUV{WA5QMSPV(F3UgO99Fn~!9zJYFNy+|(V8oOhPDc&=q$N|0w*+f0D
zaWNrmqE=VLe9`PuaQHfsMfS}Dbf^ft?U|T}^w^5oVHp&~LgI7XQbS-7F_>wK5h*9N
zJz3--H#5vf<UP5PCFWC$03~ch5&aG+RWXZ>fIjxA+Km<|DL<)VnHl1_1CH4ZA4ww=
z8m!x`8Op>)Z%8^y#4slf>kZU`39`IPdI3)xFexb{dyJzb|K^%j0FK%$9Be7R;+9P)
zmNmBjmATu?7^{&3J34)?*5i;=AUX9zjHMj4aHpj`)_ayz+e9F-<A~Nlx0Y9l&vncA
z1wz^Pd-P;-5W&Hhsj9Zh(KJ<#awP{@uclUbk#*!vAgg+x;Kckkx=^0hIGu-s%>X5x
z)ZV@&ayUpQALVe6c4oO>GTl%{j>3uBm2G7EGi;Cj?r-#s{bWQ4%BD682WQrNI$PAT
zEryv`oV+IAv5}S0>}MI?rJ*gkDF)GVQsw5+T5XH@p5^6g6Q>*a`t(d%J1j$$1PlwM
z!w4k`qMx@$Qts?c=Fio4C8&=sXO^h)l@U_1fKU!V<X42Z#((D*GRs}%-)BiWMvh!T
zwFJzkiz#hn**-R1c35JL<R)qb{RE(#Nr>Sq>@<i~JjjHn=CR0V*qOdtzu38nX*DIT
z;`=O+y`WuM{<-edvgtY53295b<fm~-c9)FPvaJqfE^AyK1&+BG^0N?(AOi1gTOz+-
zaeFU!-ao92M4r811}Il@1NF9;rt&j^#286mh?s#Sk;_x!@EoT6&&&Q6e#r(V(nsLx
zxGma;DR*ilEiPl+2P-jcI(I_M0OgD)2e-yo#x~Z(7Rj*!Rj!$s$>n=n$nTTR<B9_*
z-gJ!F8tX$9lr6;W!@s%K?sMH*sloS!V^CrXbmb77s+LQ!O%F5KVk<YYJp<G(l_1IK
zQWfs5YPV=+O;OXPlj(kZt;O;x8RBqSK@4VUFp#%pE(kH_$`zvSm0Y{O<bediEn<{p
zOiV6Rk_aC6+Wf*DSs#J5%O2#Y9cO#6i0pq@B<J5s!eX0`RDL^}*a*4JIotb1dhdKM
z1-YRCU0^JiVmzZk2l|{yJBXCzd$}jp2c6fP+QXGrS-X5EQhKH|S4x_5_R&(gaTFaY
z>I@~S1tllxnybwn=-?$}a+2%X{0n!fjK{e$d^v>F?O24`+m?7s>$<*+(MdTtWuB1q
z%j4`I)-2~7*Ru##R+(S6#PvwUWdHEQW|f)YU>YET(tIru0)bD4#84oESAQW>AIa88
zYDp0_=c&xnkh3{Le3#L|l7sj4z5(j`*0p+~0!B#56(5D9<`yT6+A`jaP}aPcZbnD$
zj6}Cz7HQTTxZJ8rd~YI=A2=ubDrHxKS5KW2C&{98Hd2y*pCvJuS8)$Y23QfwYD?!)
z1_i-uuCSHQ*eAy1{wi|ou&$6FI@2p<a=-X=h41bsG7f>16yImr^>f|CJ!*lU%2z1J
zOt&;2WS&Yd73c017<3`vG>J(136xhYkUl~Yt80sIqpQuJkY{{8-5ktpWz%K)I*d)L
z)~ZjVFtsALcBYA02tq04c{J$CpXYl`RTv!QBpaNM&Ie+BSvnL!HAie7f=aFVbWUya
z1Jcy$ZfcRLf~YIGU*(!<OPPBl(?nzv>UtH&i)#Bj5;EI_@t)5+XLs|(ayh>jskSlz
ziu{1@v#^MVNp1PLZebb$3jf$-BmV09(=>1?-N1r2K`mAl>!e{&D|%c`rq$%`M#QOW
z#CPw9z3Vb%YQcIJ>Q_xk`Gvclu|8d_N4AoK+uL+$A*gqy(yQqFcp~G4dbdsK{?QSk
zoX&l!?S<*=QXyQ?p0RU&E|?}qPAEi6rWvwxu~ZL>5F^moqvT8!+w-O)H4<C@BVE=x
zch{j>xmE0X9)(|f*-@D_V!Yo&z8_4^KJ@{cX&UqCOTMHdHL1;}c+JmsivVR^E7W`?
zUGuFLIIw8}*_p)0fS^X1rM=FhC!Jmh<?u8LORORgQA4$#7k2GAXIdsFMX?NDGSQXu
zbWoxoX1R_TxW5)cqX&)b$#nXHdK(?Fs(;PnJ+98apgGOdm7|w}<WSTjyyp}7!2`Kn
zjro0+DW6vAT2s87+SXvE%}03kYHYfDgxtD&O=grpwgs)%9BW6oOlne+G^#vaGC#5>
z)oWkZi=C;1g0FRq5R~}l8f*wAn=U=5R1UAO#}^`;WMC=%CoXu(A*XX6Y8WY^J+3yn
zQ~P=qM<B|*Bnb}&s)x8`d@zR_2dJbk)i6*p7k1yW>HKruH5*<>^JzAxC++o`?eD8*
z1*p1G-;T1>jY{IBLNpNGFpdA3=<a({&GP`Mb)P*|L_r6NQL@$Ny2ZRIN(h+-x7w0v
z*`%W~HNGJ6S(w3;_0c?_sy1CJ3W)rw7i`v6y?2b0RIaf{645ReDkb|1VF`B#cQupq
zX;_GnC+Wz^2rMGCBWtF$UmA6w<hrOeQ&&TTPY!7rLsim&oW&@G3a8Nc7Q^%~7b+YL
z*z-@G`+C&Z5wVrzW3O1MML3vk&=UwHrb~FcWRee}N22+uw8gA1soZd48E7>!ld>Q+
zsP9>?qB~4s9Ohh!BhrWs<jQ(v925%{BKEGwZBU3$@yh4~f+4$9l(mK5^i(?uRGaGM
zD$Cfl!4DC8UeE=(v?e)-Uy~Fq^{rwWS*Ab^aV}SYA$8V7T4^0B#0o{p3O-k~#quhn
z!>{RZf>vopGwJ@osY*$uo6D<EVKJi6<9W6eY$qcyHC$XXmPa55I5YQuS=DW@Wx1<7
zd8X!b-OL=N#(a9gqrqj%%oKUHS)o!UYZ}kUu3Z0$e{}FFR3&}&oCHj@MmNTkCCYpK
z+WR9h>QVTX16AD662@!-5`%|>4Tou6%y?3Y18VKy0qTz^Bo%t%-l+PhDTz#RwB>RI
zs<3n=2j29qLPf_Rz$BQ)!@tte4iw#D#}%^7j0gu?8(y!Mw_@a+of$!6?rWrS?i)sz
z#06Kzg)C60Xy8wJ!qBXV!b)U3WrIg3K)1iNGSmzDogW3t_&&=ry6V2TwHts42g?N+
zPNC$}t3ia-J-aO@0HV5qGxk+2mC?Ii(&(+4O{yO{q)K6toF$b2e4MW=c4eX%G`C<=
zor)i7mvk6kL>h+TC(@e-xGOf|x56)2Xm)dP+J`*}PtGpy=5izl1pq&4u66Ds*Pe3S
z;9AGps}`yVGTly8&Pufj@>G!9o@65_qtITme9nZE%2bZ^T$i)DKMx068#p*}FK3hc
zyZh-}1}X3%90mI>km~>ZV`J%1u#`?TNvu_(C0W>+WU7bJrxMg|*Xfx^B*yk`{vNOl
zLGd2xQ8B~8lejh+rW~x%J|eK;-~oJ@C=Jq0tcM<*Hmw)X3X4wOXuHYeeK!v9x8#Ct
zq{NB}DKB1KiE%nhttkt2WKIXb=HcMXnl9PEjCH~DXLU4yrR}QEr1C&~iEH_*5+>;K
z|E`Jxh#l@rC_Ddlb(9YFzi$%>$Y?+{zok90!lpkFssc#OZMyBtHgjY#sw#jJ{bdFo
zEl_dN!p1eg>`QgApm9UFcLt<DQqO_nwbMDBFE5EuOycH&O+b5**g2nYif@_WU=oCY
ztPVM?SE5n-%je^bwGL!$EMTHmlQyX<V6TdF(x|1}83J_40k^RQ{Vk_4feJI)AtGt@
zS?_M)x_`d7C2==i&N2{udDXTI5$woRV0X>G`k<!OX`F>4>#o#-FuEgVqE{0iWQVnY
zhqZ6<W?No0B86NnNY%RKQ|Q%WJTWs8dG^9q3@MgOx?mz!&8c(oP?0$qYGdfag<R9a
z$Cg?^ng-4i_J(V1p1|Hx@!aq}JkEMuHSl0>nV;*PkXQ#UcN0;(T2%$Za_a6tMMfBa
z4yl1(${xf7Q-)}Dq0%i_{-hqPiP@hD&ekWXG5IRKn6@=c{eqRfAo{2oFEp8=;*Bcc
zwC3WGs!#9ozM%0<RJfEaVpoI91MLY3h{)L&q(EK7+rYc+E!94#CLgi4&Ch=t3{iGU
zYpXR+bykxDWc4RQAzr9Op*-xSQY0Z*z{EX5+UhKoiyE-~$H-!lLq|vF6&)4=-exwc
z;K<@!w%hmurO+Nqe)v$*q?qzS$XZ*_t}?_0!{?C+XRDj3N|=Dw%Z$XWAl4Snl+HlT
zi!n}S?L0sklHc^Dr7{8l1r5U+3x5kfOKIY)XE*6iC+e$`fMjcz)U40lRO23O`*yax
z9=LeY6PvX-GD|(4b}x**AY4)Sli!_6;Yh4}Nw$I$N=Sdc&B`X7I>FvDzSAo<&=JjV
zb19cwyLPu4m$!i~%P1`l)#;v^^)But{TyD!{ASqI0RST!DV7N7R`Ny863=k0c4R5o
z;vMxEyUTvVbn^=Z)4B=T8noNrHtlt;v%9k1@akU7cjWWC(ZJw_nVTn;>nibBwVGnp
z-%e&0glC<*9;1>1+tUV1c2v|1pt9u>+risd+O+9QYaH3>4==9oCbRisv6#>9Z?Dcz
zd(v*W>a55cANeQR+_!Wel}pG2{9R)y4Bw@2BSBb!j`ARY9V;=?VsGqyp}QPZIah0x
zTs>*0H#i**&xXUnNiWlS$`vx#Vu`r4YG&K9bVrR)dC<#nv%$$SyG;wqnM-2w>zanQ
z0NAF8`MK_?&5#!GOoht^(w1l1!rAq8tLZkL&6=GX6J<-Se_J#JLLAnb8E&y!!P&Bq
znZ2+pLpnyX&|2<>qDF3oke~V%7;`Et<JZ~~a=kKgW9q9YpV;i6du^5_5BzI=u6w;3
zL%J3_a^bDZ1^%07p-F>vq?PBy%Kb>4RTrDD5^(jWoeMR`g_?X*kgXnI`zKa#e?7B|
z`UaRiJuL)nkS?c={Lu{)H&meogim9o*5>u=;%eJ1);i_{=^+OE8ybj@_2dC|g~qgY
z18UkAJ1Mxn$+D~QEuFHuRWL{{P=hfB3-M%fMWM&ycDpfyJw2M!k7O7WIMglkbKS6f
zM31~1YD}%cB~VMGQ>J?EeygcfHE#kvhj~0YUD0u5dYZCg4J}F16Dz_F0b>zMYJ#!X
zGc!no^YyKpkYw_EfWBX<Z(R@6%)Ll4-qaA4^9WNz3{9OL=TPA(W{tI|;i_*-%Ry2j
z=#~%FK+9vWDcvhVw*?%sR$>u%rq_e4TRT@ClumkF)8!ygNUmb=ZGmi~miY%XAtbzu
zKOzJt8g}4IH9PGQX}e{{&{!@95Q-`5xsa8hL&|c0rHu{K`Rrn5-Y`+FHO2C}HlLuX
z6%4sOD>^@9f<#qa-H8?Z!A2B|7Ne<?Te}U#Oh)tc`U9G&UWXjNueL}AEX5dHd&Q0+
z>wJFMYy!F$Go?@ct8zk`<8=5dGr<8-Sxq)LTK#L4uIZZq>lg%{nf?T|oNp0tSeJ4`
z6GW1vSHmmj#@i05)$Cg2>Bkz<{^iuz+|#|c>mWZu-}cPfFT<fytR@$=hCMyKu`{dT
z)fp!eL?E=bTJI8_Q_I)XlDf1;{{mL4`R&Dt4r!(Rv)fr6Hy}}WD_?V4+MDIAe0s-_
zb+MdYpBXI4PDb~&+<?hBX*~4UL27;zF?Cbt#=%@USB+-0!?y;Tb9;Gq(hVWeH0$<<
zqnoKuS_@_P&vUQ?^LvbFTtF<JPjIn8Cv>bd>kZDX?q;^#z;}w7ib?AERxy@Sgs;1y
zv#nH+Dm%Ab4Bwt&HJ`$q!R6&>ba{1iKbhAz1YT%kL+eo8=YChMvhdi4HZ13pyBlo7
z<>mG5{d7?)-B7-mO6jn^2F_z0TcB>t6Uj+}?5ts$IkYHWt@6CafXAk99jVx&A<acQ
z)|!)u7@p;>4Yo@dOBVOic0l-A&-wCLU^8y)srA9K30dQbh0~$Ape`cW@@)2`jxK8^
zY#wPvHCrMci{)~$AyCH{a^@pm`xaM5P`XfQ1}C@m3OFL$e3r9?F<W4Gn4+)@Xj9*B
z#vh+9Z}hn9M6E=J0rMVCi=kTiiV37g?@G($X7p)^l}hzH44vCU8SE|Pi%ah7VBOY4
z(Y$TKzJ<J=gNJ^gBA_sfu}}9Z=354HEKK*k*S!&$B(%S5KF_V06KimjU+smdwE?Gg
zgdpm?(O%cKDWC4sWA<tteL1ZS8q{JQAFM=bj{|J2N93s?wEmXoYT6f&Frpd|c-T!u
ziY5O_c}uj8QS9VyM?+Yct5nP{S?!(6X?_!#tzrwL>F*>WhR1#kQn!PdHjbvEG>Eg6
za&cUBIx7Ui7Nd5UG?cPdOsvfXtY_O>k;TDR=r**Z#iOn{fh_3HFQG@7fUP~|*Nyv3
zm|*nHp<L60_?QgY)~+u%#DO&~N57Ny&1rSc0&-Q%YU02qI}S3}mKsA$V2IT#(%waT
zM}Bc>r(PbN=FJskC)cgr_hNEx<?=!Wa<f{;!UIk2=zK+l&cEGIwlV9Sx3Y>kM6-4H
zw}kS%zn%W5Rj*p!4(paHTDzry@i<V6jSX~=AvXB5dkPaAu0PcM$!Ax?7t0Oo3y|4f
zJKYo-wVK#@?yf6Ydzq`?_#U0kPHI`!4dXif)4Hv2U@CNSb=I$u@;y*I@T+O}<m`G<
z6OYD42dBN-u!rgB?((s)+BT)uun@ero7#M<PVe;m@)jcOc{wa8^5uMb2MPQAj+n8j
zt@e2zq%dIviwz*cUbdkqR<P9%%<2r9q`PKPNbF?3U)$2583E1jPa9NXr+0EXJcp@|
z>+9>Q%hCDS=}GSc;YCTUw9_A)o?VQt$~Fv7s~NVkjQH)^(R(>jA>P{d(sr`!9R@k<
zG|f7lEUQ~N!3)38t2A?MXp!p&{<7(vEo<E3og190wYuK0Ev{;H*3NZ(xG!d>#tub5
zsDrsyku<3hdq<Y!cf(rC7T^B=<E&c~aLKP4)cUTZN$aLLU|{!QSm<3_-txV)Uqd1J
zz2lbfHWf>4)d(UoIn#47o1p#OJ@1^^`QebEeFW)1^3_TR?9hGkK^yG-J4aSy$f36$
ziygp_`taxKx_0sD{*8U{5Ympd4AOZ#Ir#$j;oD(5*REpVNDGJX@F=|ih%jC*hrNyz
z<j)bM!!`WO*dMp7KEES-IlllhJrN2u(F;eFV=vrJlA+p?u4D(~=jGGO|KElqo%34R
zfS7B;zVip_E$Kj~&qt1|^X25yNTfbc<u46PI=GsZ(JexR@^o?NQMuKA2njSMlN77P
z^ycE^1B+ByE!}Vr6Wtrq!(r*c4y&g()M-Ah37M6>0)F%5Vs>{kIv);TC;D!gA8rEs
zFmI-P*!ySRoKvH-d5_iBY&apruQ@I9)nYN5&8E}I-AJw(Iu>R}hnse~C&P;?48zyC
zRGuEIYmw=EOw`hW@gdS0zQAo<Z1jPLR62tTSaEQ5eS0^Vl3AVFHZMj`JLd*#0Bdov
z9*EC09<#F?1NQ07bcxF*ie{lGTV71mx}0NRMPa6=w`QcjL`nXx)KV1+?PZ^DoBzJN
zc|u)Pk*+(6d)Q0r8`o+Xa0Te4pXiSk7|n~fis>_~gLE_;)GsrQ=v8MQtbp{kQO(8T
zw%v{h$LNLdxv`oYjEW2K<RBX-AEOl;U}opB4I9rkE?nPG*}jiE=aUVNU)2P@clN#&
zKi&K0*ITPru@lHFYu*as39#;5wB!i;?9~$>cBm@UX8;)s$VIWZc@g8R>}=8y#HkSG
zn`a-2TE~aeYv)H6>f@2eN3E`gba1;_YduA9tq#F`?ziK|>REi;`gV0Lrj237_3GI*
zYd!LfPr5CFLoYC=BhC7a1CmyoV>c4!nI2}NO6A%o`Q6#ejAmz@{`pPKUP^~p8uUyI
zX;fH{=>C#3k~7#|`{H`C5GxMaeAMxosJ*$`^sFXoRV?l<26bydHp6|Y62Oy_!TIP4
zwqJ2O(J!Xg#`iLw3Y!DelNp=!uI6`Far>eJRB~hxu)$Kd-#<ASz|sHE)8(?^UDz%F
zXLVrB!PUiwm#lwehCeO%9!x@A!K#T1ST+HZo_~i^o=;29{cD3o2Os#diT!Et3gMLk
TuM~Ktz$*n_Dey{xHWc`O(cS1K
literal 0
HcmV?d00001
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf
new file mode 100644
index 0000000000..1f79332020
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf
@@ -0,0 +1,10 @@
+// /** @file
+// Platform Logo image definition file.
+//
+// Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// 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. <BR>
+#
+# 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.<BR>
+//
+// 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. <BR>
+#
+# 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.<BR>
+//
+// 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.<BR>
+//
+// 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.<BR>
+//
+// 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. <BR>
+#
+# 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ACPI_PLATFORM_H_
+#define _ACPI_PLATFORM_H_
+
+//
+// Statements that include other header files
+//
+
+#include <Base.h>
+#include <Uefi.h>
+#include <IndustryStandard/Pci30.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/HighPrecisionEventTimerTable.h>
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
+#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
+#include <Register/Hpet.h>
+#include <Guid/EventGroup.h>
+#include <Guid/GlobalVariable.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BoardAcpiTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/AslUpdateLib.h>
+#include <Library/PciSegmentInfoLib.h>
+
+#include <Protocol/AcpiTable.h>
+#include <Protocol/MpService.h>
+#include <Protocol/PciIo.h>
+
+#include <Register/Cpuid.h>
+
+#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. <BR>
+#
+# 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// QEMU Video Controller Driver
+//
+
+#ifndef _QEMU_H_
+#define _QEMU_H_
+
+
+#include <Uefi.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/DriverSupportedEfiVersion.h>
+#include <Protocol/DevicePath.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/TimerLib.h>
+#include <Library/FrameBufferBltLib.h>
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/Acpi.h>
+
+#include <Library/S3BootScriptLib.h>
+
+//
+// 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. <BR>
+#
+# 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.<BR>
+;
+; 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.<BR>
+#
+# 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.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _8259_H__
+#define _8259_H__
+
+#include <Protocol/Legacy8259.h>
+#include <Protocol/PciIo.h>
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+
+#include <IndustryStandard/Pci.h>
+
+// 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.<BR>
+# 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.<BR>
+//
+// 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.<BR>
+//
+// 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
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#45751): https://edk2.groups.io/g/devel/message/45751
Mute This Topic: https://groups.io/mt/32816099/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
Agree with Nate's feedback on moving the noted items out of the "Overrides" directory.
Please do submit a patch for style fixes in MinPlatformPkg/Acpi/AcpiTables directly.
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 9, 2019 3:47 PM
> To: devel@edk2.groups.io
> Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince
> <prince.agyeman@intel.com>; Kubacki, Michael A
> <michael.a.kubacki@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides
> modules for SIMICS QSP Platform
>
> 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 <hao.a.wu@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Cc: Agyeman Prince <prince.agyeman@intel.com>
> Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
>
> Signed-off-by: David Wei <david.y.wei@intel.com>
> ---
> .../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/PciHos
> tBridgeLib/PciHostBridgeLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platfor
> mBootManagerLib/BdsPlatform.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platfor
> mBootManagerLib/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/AcpiTabl
> es/AcpiPlatform.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/Facs/Facs.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/Fadt/Fadt.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/Hpet/Hpet.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/Wsmt/Wsmt.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Com
> ponentName.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Driv
> er.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Driv
> erSupportedEfiVersion.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Gop.
> c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Initia
> lize.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeS
> him.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interrupt
> ControllerDxe/8259.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHos
> tBridgeLib/PciHostBridge.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHos
> tBridgeLib/PciHostBridgeLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platfor
> mBootManagerLib/BdsPlatform.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platfor
> mBootManagerLib/PlatformBootManagerLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.bm
> p
> 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/LogoDxe
> Extra.uni
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtr
> a.uni
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/
> DxePciLibX58Ich10.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/AcpiPlatform.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/AcpiPlatform.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qem
> u.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qem
> uVideoDxe.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeS
> him.asm
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeS
> him.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeS
> him.sh
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interrupt
> ControllerDxe/8259.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interrupt
> ControllerDxe/8259.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interrupt
> ControllerDxe/Legacy8259.uni
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interrupt
> ControllerDxe/Legacy8259Extra.uni
>
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridgeLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridgeLib.c
> new file mode 100644
> index 0000000000..2aaa4b3e90
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/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.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiDxe.h>
> +
> +#include <IndustryStandard/Pci.h>
> +#include <IndustryStandard/X58Ich10.h>
> +
> +#include <Protocol/PciHostBridgeResourceAllocation.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PciHostBridgeLib.h>
> +#include <Library/PciLib.h>
> +#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/Platf
> ormBootManagerLib/BdsPlatform.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/BdsPlatform.c
> new file mode 100644
> index 0000000000..0b66862e46
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/BdsPlatform.c
> @@ -0,0 +1,1553 @@
> +/** @file
> + Platform BDS customizations.
> +
> + Copyright (c) 2004 - 2018 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "BdsPlatform.h"
> +#include <Guid/RootBridgesConnectedEventGroup.h>
> +#include <Protocol/FirmwareVolume2.h>
> +
> +#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"<unavailable>" : 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"<failed to convert>";
> + 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/Platf
> ormBootManagerLib/PlatformData.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/PlatformData.c
> new file mode 100644
> index 0000000000..5f1b16dd56
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/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. <BR>
> +
> + 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. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Uefi.h>
> +#include <Protocol/HiiDatabase.h>
> +#include <Protocol/GraphicsOutput.h>
> +#include <Protocol/HiiImageEx.h>
> +#include <Protocol/PlatformLogo.h>
> +#include <Protocol/HiiPackageList.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +
> +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/BasePciLibCf
> 8/PciLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf
> 8/PciLib.c
> new file mode 100644
> index 0000000000..7544117a03
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf
> 8/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. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Base.h>
> +
> +#include <IndustryStandard/X58Ich10.h>
> +
> +#include <Library/PciLib.h>
> +#include <Library/PciCf8Lib.h>
> +#include <Library/PciExpressLib.h>
> +#include <Library/PcdLib.h>
> +
> +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/AcpiTa
> bles/AcpiPlatform.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.c
> new file mode 100644
> index 0000000000..b1d7552792
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.c
> @@ -0,0 +1,1579 @@
> +/** @file
> + ACPI Platform Driver
> +
> + Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +
> + 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; Index<MAX_CPU_NUM; Index++) {
> + DEBUG ((EFI_D_ERROR, " %02d 0x%02X 0x%02X %d 0x%02X
> %d\n",
> + Index, mCpuApicIdOrderTable[Index].AcpiProcessorId,
> + mCpuApicIdOrderTable[Index].ApicId,
> + mCpuApicIdOrderTable[Index].Flags,
> + mCpuApicIdOrderTable[Index].SwProcApicId,
> + mCpuApicIdOrderTable[Index].SocketNum));
> + }
> +}
> +
> +EFI_STATUS
> +AppendCpuMapTableEntry (
> + IN VOID *ApicPtr,
> + IN UINT32 LocalApicCounter
> + )
> +{
> + EFI_STATUS Status;
> + EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE *LocalApicPtr;
> + EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE *LocalX2ApicPtr;
> + UINT8 Type;
> +
> + Status = EFI_SUCCESS;
> + Type = ((ACPI_APIC_STRUCTURE_PTR *)ApicPtr)->AcpiApicCommon.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_HEA
> DER *McfgTable;
> +
> EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_AD
> DRESS_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_BA
> SE_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_B
> ASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
> +
> EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVIS
> ION,
> + 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_HEA
> DER) +
> + sizeof
> (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_A
> DDRESS_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_B
> ASE_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/AcpiTa
> bles/Facs/Facs.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/Facs/Facs.c
> new file mode 100644
> index 0000000000..a16c13466a
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/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. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// Statements that include other files
> +//
> +
> +#include <IndustryStandard/Acpi.h>
> +
> +//
> +// 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/AcpiTa
> bles/Fadt/Fadt.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/Fadt/Fadt.c
> new file mode 100644
> index 0000000000..8aa10a4a5b
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/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. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// Statements that include other files
> +//
> +#include <IndustryStandard/Acpi.h>
> +
> +//
> +// 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/AcpiTa
> bles/Hpet/Hpet.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/Hpet/Hpet.c
> new file mode 100644
> index 0000000000..aa386ba149
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/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. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// Statements that include other files
> +//
> +
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/HighPrecisionEventTimerTable.h>
> +
> +//
> +// 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/AcpiTa
> bles/Wsmt/Wsmt.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/Wsmt/Wsmt.c
> new file mode 100644
> index 0000000000..12e2feacb4
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/Wsmt/Wsmt.c
> @@ -0,0 +1,46 @@
> +/** @file
> + ACPI WSMT table
> +
> + Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// Statements that include other files
> +//
> +
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
> +#include <Library/PcdLib.h>
> +
> +//
> +// 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/Co
> mponentName.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Co
> mponentName.c
> new file mode 100644
> index 0000000000..dd9cc80e42
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Co
> mponentName.c
> @@ -0,0 +1,205 @@
> +/** @file
> + Component name for the QEMU video controller.
> +
> + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved. <BR>
> +
> + 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/Dri
> ver.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dri
> ver.c
> new file mode 100644
> index 0000000000..e49e7a465c
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dri
> ver.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. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "Qemu.h"
> +#include <IndustryStandard/Acpi.h>
> +
> +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/Dri
> verSupportedEfiVersion.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dri
> verSupportedEfiVersion.c
> new file mode 100644
> index 0000000000..c2d82e7324
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dri
> verSupportedEfiVersion.c
> @@ -0,0 +1,15 @@
> +/** @file
> + Driver supported version protocol for the QEMU video driver.
> +
> + Copyright (c) 2007 - 2010 Intel Corporation. All rights reserved. <BR>
> +
> + 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/Go
> p.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Go
> p.c
> new file mode 100644
> index 0000000000..19ff5209d2
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Go
> p.c
> @@ -0,0 +1,417 @@
> +/** @file
> + Graphics Output Protocol functions for the QEMU video controller.
> +
> + Copyright (c) 2007 - 2018 Intel Corporation. All rights reserved. <BR>
> +
> + 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/Ini
> tialize.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Ini
> tialize.c
> new file mode 100644
> index 0000000000..fbf40e9eaf
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Ini
> tialize.c
> @@ -0,0 +1,341 @@
> +/** @file
> + Graphics Output Protocol functions for the QEMU video controller.
> +
> + Copyright (c) 2007 - 2010 Intel Corporation. All rights reserved. <BR>
> +
> + 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/Vb
> eShim.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.c
> new file mode 100644
> index 0000000000..aa4648f813
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.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:
> + <http://www.cs.cmu.edu/~ralf/files.html>
> + <http://www.ctyme.com/rbrown.htm>
> +
> + Copyright (C) 2014, Red Hat, Inc.
> + Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <IndustryStandard/LegacyVgaBios.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/PrintLib.h>
> +#include <SimicsPlatforms.h>
> +
> +#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/8259Interru
> ptControllerDxe/8259.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.c
> new file mode 100644
> index 0000000000..b57bacdda4
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.c
> @@ -0,0 +1,622 @@
> +/** @file
> + This contains the installation function for the driver.
> +
> + Copyright (c) 2005 - 2018 Intel Corporation. All rights reserved. <BR>
> +
> + 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/PciH
> ostBridgeLib/PciHostBridge.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridge.h
> new file mode 100644
> index 0000000000..3bf31067fa
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridge.h
> @@ -0,0 +1,68 @@
> +/** @file
> + Header file of OVMF instance of PciHostBridgeLib.
> +
> + Copyright (c) 2016 Intel Corporation. All rights reserved. <BR>
> +
> + 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/PciH
> ostBridgeLib/PciHostBridgeLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridgeLib.inf
> new file mode 100644
> index 0000000000..8c6de3dca6
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/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. <BR>
> +#
> +# 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/Platf
> ormBootManagerLib/BdsPlatform.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/BdsPlatform.h
> new file mode 100644
> index 0000000000..1fb031b752
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/BdsPlatform.h
> @@ -0,0 +1,156 @@
> +/** @file
> + Platform BDS customizations include file.
> +
> + Copyright (c) 2006 - 2017 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
> +#define _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
> +
> +
> +#include <PiDxe.h>
> +
> +#include <IndustryStandard/Pci.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/SmBios.h>
> +#include <IndustryStandard/PeImage.h>
> +
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/UefiBootManagerLib.h>
> +#include <Library/BootLogoLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/DxeServicesTableLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/NvVarsFileLib.h>
> +
> +#include <Protocol/Decompress.h>
> +#include <Protocol/PciIo.h>
> +#include <Protocol/FirmwareVolume2.h>
> +#include <Protocol/SimpleFileSystem.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +#include <Protocol/S3SaveState.h>
> +#include <Protocol/DxeSmmReadyToLock.h>
> +#include <Protocol/LoadedImage.h>
> +
> +#include <Guid/Acpi.h>
> +#include <Guid/SmBios.h>
> +#include <Guid/Mps.h>
> +#include <Guid/HobList.h>
> +#include <Guid/GlobalVariable.h>
> +#include <Guid/EventGroup.h>
> +
> +#include <SimicsPlatforms.h>
> +
> +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/Platf
> ormBootManagerLib/PlatformBootManagerLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/PlatformBootManagerLib.inf
> new file mode 100644
> index 0000000000..55da35e87d
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/PlatformBootManagerLib.inf
> @@ -0,0 +1,69 @@
> +## @file
> +# Platform BDS customizations library.
> +#
> +# Copyright (c) 2007 - 2018 Intel Corporation. All rights reserved. <BR>
> +#
> +# 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.b
> mp
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.b
> mp
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..86d7030833a096f54539
> 3735d931d9f4f2fbf8c0
> GIT binary patch
> literal 141078
> zcmeHwJ9Hz-kzh@gFoN)Qu|weq&F~F*XbyPdaEHTfE*dKcjU5ohf-
> &!%BU8pXGG)q?
> zD^tc9GS`(UQ>MIoGG)r#cb?2OW$Gd_vnu0Pg~E?y>sT{Q)F&%4G9u%Xk&#)e
> |2h0&
> zn&2`0PLf>1@BjWNN&Xl7`zYzU`~UYcP5w_masS+n@=v#$bm8A8pL~*ZKm9c
> M6#l(=
> z^C_Iaf!{aDCtrS<d<p+Pc?<u(e4D(*e{bKy^(^^xHcMvkZ-xI>tK`$wx5>BPew+N{
> zCqGF({r0EHo1gqN`6>SUDV+cGXUUiF?`J>zS@QFr|2+Bf=f6mP@rz$1Z-
> 4R2<d?tv
> zW%A`Oeg)^hN`Cb#`2FRtlefS6b@J<9|2p~dSHDSq^PAr!Z-
> 4zC$qfGe$A7@@Z+@Hn
> z_P4)H-u~uyaQ?gGcfW(*-~K-N{qKLDtbX^0<PU%NLo)l_AL0Cu$shj+zrX)e@~1!j
> zDf#vfe@_1V=RYT_KmKR(E&Th>|AgN^{U!O!U;dK(*MI$2^6j7hn*8;ze@*`Ox4
> )It
> zdHsE*z$*n_Dey{xR|>pR;FSWe6nLe;D+OLD@JfMK3cOO_l>)C6c%=ZLK$`j}9J%
> #+
> z`g{~f-@JKc$n%k3)||b2c=-
> M+LnK+A>$>;;@$vEfKfY?L=VAb__wxr}$K&JI&mkaS
> zw~kS*1G~9@9j0;vimRVfxy_Y(?c(tf7y|!~-77nSYEzvqlcpIQf^ZIl@W;O*3M7fT
> z!9kZ0_+7Z-
> @1+@3FK$(@q_Qx*CNCLHfLrh%DN_M$JaLeE@0@S|JKldEOG8tTLJSzc
> zYJ|Dn!`@e*DIXr+U-e-
> ^H5^DwWD+9bE5=`ek8z`XKS_FDqrkua>L0^f)%(?nEBo=A
> z_fYpY?}i^&&`AMu>PnMqa+)M3U!$^re1FlY5cqf;0Cy_D)w70^J`w{D#QyQ|9Rf
> @{
> z8kVb`(W3$AHjlEeUB&Ltb>`mu&NuNEoIQM&cK+Snc~b#~A`kH2n~2dD(13?{J;
> ulG
> z|Id&fV>kskN%9G{)3wsUdQ;W(-n%jm@Z%%a^j$>b;a#Vy<Dc-
> |$FJd0z%bzRz4!P4
> z{sCjp0*YfS>J9)L?rr`_zY37>O@Q{_-78}U2meqcS?f20ZdoD)$&5I7LUsP#5!2mA
> zEIv!W^NqXXbtyvT1i?FFELrj6Q@p|h8in*2V;#tu|Ax1|Dk=1pD}m+Uwxe4Bj5U
> 1+
> zJNV<fsLOyKaN}*L9!@<z9mh8h<ni$wkx9P7lK%h4Z%*B<7Jsrp4EO5e<5xcS!oh
> MF
> zJ_0O6y=;Bij258V7V**nn0p+qQDwP~>Dq?`cmO&E`M9W{0!H{GGAQ{1E-
> QX`E<5s}
> zixRkn@-
> arZCEI?0@4(@!dEW!@f%90CZ#9t*CtDBKkZs|re|+@#d>x=TP>&8u37Fif
> zP;WRXRfWgu@yZqbfd>-qeS<tg%t&h+Aa47}cR8#P>jS!=`3l7Lc);J!$~z?;OIihj
> zxJtjk;$;D^S?~^kMG7IeoW6RCcaSk~q(8<IzH0o9OmK=1x&^#M_~DWL3Z%@l
> %Bx4@
> zQb6AQ0u=1$cz8ZPP&8e|HGe+wWG;a{KAZ!dmCOWS0ZA+r)prfR?Qf3}ZHIRt
> %l`lv
> zzO}JApCzUJ@O1P=5WkZCa0l!MTn7vs`QQIzf_!;+1fA~c0XAemf*X$MP!igY&BD
> W#
> zd-rkbYJv*{4EhQVuCL$*Dm%m{luAOUt{}bp7>!hUi69=~R-
> 0q&3OmUD4Bta0ky`-E
> zBMCQ&c4z~>MVXJ@dBmalpL?R*f<qBnTQ#X(J_tX?h<1tLTfD%Bj#$v8##j&Vq
> k}Yl
> z@AY!xHNnH@N%pU<a<nu~HUmE#yNG;vNkH|7S}oL&{>V4s^ECYzID`MbpMs
> Hs!vn@!
> z&V+3w2Pj#D`tZXJ_M-sGAqlrXPlBcONaEABVz;s4SiqS=@9#jn@OTgGC#?-
> dgT$2G
> z--
> !^SMEK$C2MRMB*}oyW&Rm32W4K0r<wWA0cjG*hKmZaaM^HJ~Vp3Cse}#_#
> BI4uv
> z?}PKYf)sz2zQKnMuroQOk$1S&{|Qw)?8fju9MHeU6|8@9k`j?5-
> ef({?Vfmz{NTul
> z6~lkvK)7~A<pUsHuchXjkS)~s1>zt017ZiRi1VxPE@+rB{(^ty{I0;Y<X_;P2a4d3
> zzTPsx848;6ue=%x{w`7+O9gX_Fu@+d-G_0CQt1Jgj02h4c>L1?!h9HEL8Lugef_t;
> zp{PGRq8g8|BDz@ifQQ!rNT?+7E-FwFyj#SjQa(^$Ab&|ne*?-
> yfnolYlQqW=01AB<
> z`2nRtKFVKgL(mTh)C&}X`>xkSc+-
> }ThiiC5@cGo?>P&AiC2xWXLl_@<ZAS2fn>B~y
> zEP9hpAtG3)%foU#Ho^kTkU&H`)PUUf_74!O_alHGC?AjDQv~}Fsb9)RL?Ea%Qe
> =$y
> zhXSsny77dg7WC*bJj9k_&vlFfOrd>PIjS`$P>+v5YSQ(Be8ll!kPo0&7$ISGu3jg5
> zXsxgbZ_sH7fPv9?AP+Yl!AUOpf$xFw@~#>p8DWL)(2C0&tEB~kMLm!50Ugba{s
> 5Us
> z{jxvCJA`Zj-WP~}DDcsbfH{urt^(i(j^2?UIN(APg@+Rg<Px4DH&KuPFrJR#rf;?B
> zU-?Il{bQ^byA-
> _PT`lAX@&y408LS4N0a^3MwID!3+5?Pt9q;bCP7`5;K~m|xn9z2*
> z>AQp%c031C0MSbO0qqHgqY^dWo@^!kv6Qptfgi3X1$_k|p?4zHpiv*AdsRkD
> KJvp4
> zCm;S4$mS{S0Q*XVe}%Ys?dtt2B$q2SM)p<m;qHcx>;OAaaYNG3l=>gnf&eMdp2
> >%o
> z=g?`O9Y^r5u=@fRaNGm>3J*Lli5*cdsZ`zZu8ix(;hvL#HxLPh>lAxe&{qJ{*>j-T
> zxp#cZ&g$A6<iop~AV{7GB|qS0Cm%j|=!XJm&x4gg_WNFq-
> 6+ThAcfEZU}xf;_f_Fu
> zcj6*&ffzxTI(}$a&VJDDSqF04`;~k^V}kt%@&V){;uxqD?;wMq2+^Qppxxuh6E6K
> R
> zJo^TR`e2}fJ;%pzH=2)NKVbCl)CxWd_5;oku&)D1;=FPgmV0jy`9Z251JJTdy~Wyq
> zmtH6;zz^;0#~4uv^5JwTigFn02i=EN5hSti9rSSO-H;DQIAW}^{cyxP!JbD3d3}ZN
> zfu3>%iSkkUSMU%B1_L+W2G?fj#&8u}NoPMCO%bpc0?=+K7Y}~e4JT-
> u0UxXixi*Gh
> zIGlXAVJO)1f5UnLVAmAXaT^aO;V4#6*vZF3u;&2GBU!=<_5-pV%C>9--
> mZXie*!<6
> z><6ePY@xE}kwK;20D^trTk6uDd-;H-I6}j3nY4jg4Jiqz_FYR+BAt^PLs>wQ%xgJd
> zuaCaq3@Yg#m6nMlC-
> M;iZzf34d`@{+@&UT97RiyDq}mL)eTmB7g~n9&qa1%k>X+@0
> zcN~L|v{hZf8oJ;_91jwI*R>1&c*9b?=T1I#{CK$doA3Fa^Iix*K76-7`y2AZhl_)F
> zV)bLZ7vzHj#VZ61{a}RWn-
> 1Rs@HzmhX9EppR<NKCVs~(WK^wdqVOaV=2iI4w0|Ppt
> zIwy`^BB_8n5%nFE+Vim|sk0j(?EnkM=Z?wf@8XTm(ykMU(x6w32r*QA!#fI&(Y
> }s%
> z8JG`j{I%nUleUr|jvrWW&@vUk@+4?~he~;`_IK<^?429bS8y4eJNHTn%Lg#9*7
> CTH
> zvy!#I+dZi4ITWwt!;Q9}E-#LbA)Yjk7k)|_=v=X^s>ew?VhMH}q}|yOjAp>C;O~NF
> z#yA9O<?1bWQch96hj1!!U7!wN;=4}JIqyD>^5IJP;pZ5tf&&e%Iy_*QiUz=&53jF
> 0
> zKcc=W-=nYsIgn-8;)nM=tM>BEEq+lx0HzyEMf>5ZgNm>&-
> %{+g{t9lO2Z{q^IHbM`
> z*G@jd_yb-H_8bRQuKSk*!hmQg9d48mnp*l-
> *hR;_(GTAb;}3X^lo~rkeG_=gQvmFd
> zRszWjhAU^!12IrO0P{*dI4txuT(wvTk9HN9wX&Oa@)6pBRUs9z{jO#B2apT|0W
> }|?
> zx!x77g?xYoeuJO@k^{u}k%mMkCs-KkcTFw*D-
> <T2)WzyQ13`fw?_VJ%&Lj7|+IvM2
> z8$1hu(W3DOHCG4;tHHjGEr9ci9~@Rts;<04<eNba%q?$69fkVJH8<D~#0F79&
> 0O_I
> zk1z(LgTN4fcZ_8NKb(9-`vJYjJq1WXJ|dcFIfWix4m}?oH-Gx>AH4AdLyq#{`yxJq
> z3oJFpli(sous~4&?4EeHm_DjGuOLB#-H@`94++clDgch~-
> QR~%4a_ZXoBkCN&DZ3r
> zLx0rWDes|tkT7hh()H88A0i*fC8w_dRwW<NBk4eD2*QPbo|mDisQBFJ<GTTtz
> +&%C
> zTsa&|c>Ceh<rrRt|D9JvT91IkL4=qT(5IEYf=6Co1^EcD5MYHQ!UiP2hn@=@IBR
> %-
> zqp}|WtFj-y6GJ`zKja7YM?Bmeln-
> ~qyQKjQ=Picuh?5VeC7b|K`+<O>zAE9u%|Nwq
> zC-
> 4Jme0K&9zj*_#et6@sD97h`1Bft&$8hRQV5CTJh>=)ChU0VV%=M_?sZo7pB8il!
> zkfcqrAh*6}+mGPgx`sl}189H}BH)j}54=Q-!r@vIu8DjAsi=Ioj$OGsp%+4tO2xaH
> zJa;@A@7_U0@B0`S{^0}GNyq2N54<P+-
> O@J=MybTH`PcQRAZcOR1MP=bT~Gx>5=r5@
> zkjrj)I8fd-%17C`VCV#OVn=gIzUr~qh_csK4RSY_d;ndlYaC7aVc!^Gdi&u#13!OW
> z>MQpSV(@jC!L0-jJGHO$Jr0n+c2gVgoL7OqjDO^YKdv80eFcF15dl}I*Pe{sD?k7!
> z5mH}}AO1Exi?Bk6b&}`ncg|!j<kk<Ue0bheN}kTnmhurr9|(d?*7D&5#s@4=uv}x
> H
> z6kzQ<12?5q%15B;<2Rp2goEuu#RszFDuKTj<+Lo4#qq;+9<1JRT*wE$iSJUtWfh-
> 5
> zYAM*GfBm$)QT>Abz&1HcgflqsAMgWu5ZvXkLWgzQ+0_rCbC5_DlMk%bIV!X|
> kFBR1
> zizm7UGkyU6V~nr?kub~3X?K_*a#G{4K2QCisvHlxU<y$KSeL7*Qq4#o_y?`^u`9
> gt
> z@pgFNCD>bGZqHp3qyX$2@~O)q!gn7Ovs_On_5%t5KYXrA)Kw*tfR=0h7;!`leF
> gjd
> z4HR)*!k?qKx;|PdpMU`Nmq`9nK4SH*HHaGG<}M)F)eo&fP{!^FfI#fO3U8GJ@R
> yE}
> zUJ`v%LnnY2z<Wud!}_DLA6|mT?yegpIXKuI+&!Qy1?<kDTYNMA2RQxi7(~crlK3
> +C
> zx3V8_j+PB71bzT4#G1kKt@qI)Yy=cIkbFR$0PF&pTggh$&V>5<j-wS*X-
> ?W5y?t*+
> z^5G@uhAy<#pTa%35!!~+t5C{iV1mYWhxhGD`EcN%2$~F^=K(K7`{Cr(QSkxhx?
> BhK
> zP<#d{2aFVlA<0*jrTY9EAUEDEk1=8w^c8p{NE+aW8;x2>9z#AVn*ohM`2ZaJpb
> bx>
> zG*rE|M7_Kb{9C;3I=gES_)5-
> k0$}byaR^Uc4Q02CNerd@0I7Y~b9FnOBLvs^$Bub$
> z75GtN2>0>8QLFd09>41N&W(cPMa8}2T1dwt;EN-
> y>hPM+OPY`GqI~=aiQ=5P2+JWE
> z2sFmp52df1Jr61~%15vt1a~D4;RazD_EY~K`mVuIz_vJ7wtNbx|ELV^1)YHTxPg*
> j
> zsy!2&D!@~uh4<7#HX8a`rGMqPR#6e5xEH<--
> mY6}Hg>%NeE`ho0)ZI2=pyjqGw39h
> zn~hBQ!dK@w>v4lgFvl2l*)@{h-^Kc&-
> G{LsOg@mB&YlAy@H~1`Wv`9m;EDu^#kN!u
> zfb_#~5i}0L0Xv*_!b?0J-bKF#@)@v%Zz?`RQio6-
> _JvRfYVq>Qm5&$L9mc*MFCPxz
> zS1yiN(y#>V6f)of{DAElzd<7gfqW_;6=$IWudgt4>gB_Cni5t((h&&ihvPu@Japq=
> z&mCm1ukbWdpK5hL77pyY(0C$3{(k)XJ($dffm~Qa5%0${udguri&VnWpkW+fU
> ^Ltd
> zr!GDWmwr~N8V^EoS89we2CYAKr(bpaoSvg~1sDOKrW`-
> K?*e3}G{0t%czhdxxdkLn
> z;X?2E*tzb=TLVe&?_&Md92>l_^-;+Oyb0$38r3JDi}FE~k-
> J01A>1G$v~}HRWUwuj
> zd^mL;>PEofG}s1^I4{6hK6rpw%2Uy6eV>2zwHuBKz$sSeE!q2C$%h}XeqDA>Y)
> NPz
> z*bgDZ6iG)QtRKjBD1C(#@x~DCxj!%M2lfen0D8!+$f0n9h)`Ly{jblz^77$5BIt#o
> zZUpS=fNDdy%g;t3nX5-
> w%2Uxd!9y9la7_@a3NS)OsT*S>AAjW3rn4dy!oEY|>IkRG
> zuo&<jWi7}@1&b2M^#PcXs=(}X0tf|}K<@(&CLhofJx@Y+!5LhiVFef=_acLKz`~D
> #
> z(T6EBrvRL*$#XuOmcxYdGVr66U`Iv&LZID+2^b-
> Jeth$<Ujy!V4n9KZd*c<hC@kJ_
> zaRg*3z{J}%NJ9Vdfr>KZumc(BD?Z-tJC{q9a<Wpg->t1h7Wl3TjjrxM;}CgF>)ict
> z76H4z?}d)NW!+_^q!MpHoIH_IL2Q6>kf(*DgVtDpOMZL-
> _5&9^;iw3BN%#?h_>S~r
> z2MJvo3szZumimR!dJ1|+q5wj0c;&0)!=nV_xt`b8uA^XaXfa7>-mz+U?F)qU`1r$*
> zLq-
> o0CrAMbUMUbI$$|k9<Bzh`=V|ss*BEf`#s=Whet3TuEQsR=b$Ek+@%YupKCa-S
> z&K9gtXGtKab}vI3DHw#^Ig9Zes-
> p+UqPT+#Ze0l!`rVJ9Aga2ML<Dd+#k=mPB!QI*
> zNz{(BjzCb}O(c41Ip7{d@UM^)Fcd)z^VV^tYCz~8;YIktG7U%~*Re4CZ8sxa)l_#<
> z8bf>@&p{lqqVhk)-%a3`Hy~Rt6xoj-*darET&u!J5351Izz;k{r^p@OaY+?UUxi1m
> z`p}O`P&kOO0GHZn3=RTjZ^OF)1*@zMH{>i4!e4}M!3x!55npYEV+Cus6Q{32Kq;
> O>
> zb@YH<;se;#O}C&BuN*;ks~X>ORXUd7AE!G)-
> 3U0GMpfWOG;Dm1K>SdFLoom&yayO{
> zj9n|<V~Bsu$L9$w*z(+PML;~9WE!v{fw03oKK{52IUqj!94He2&}ry+4%Ol9@;@
> gZ
> z)fL`7kbF3|3flu9;c(0ibq9VxWkeNteS&?Fl=2!SLh)VIhbk#xcnc^?I}luoevKY@
> zfCN9KZPBm@fe`T+quhrV_^#*u<B*@DVju_F4}ND@-
> k{Cf1(%Qh8R|g}!~Y&usLAoe
> zRf;-19NvI9et3LB_1{DN6QBeNYrqKOpC2D0?I4AxjBJ(_B=I#EqLelv-V{h8jUL{O
> zOZ!$q`H)Y(`vns7@yGkM>XWyQK@^G!7$nTke{{y6lNCFFkl*`fr>tq54T5S1LGnX
> p
> z)3I>>)M+HAlfq^($ExWSZaWHiQL^UG+r9r<>Xibo6nLe;D+OLD@JfMK3cOO_l>
> )C6
> zc%{HA1zsueN`Y4jyi(wm0<RR<mI7I)+w1jD`u*-
> +87A9S`&wR7Ano=C!?V%l_3iEb
> z{r%+rW;FOa;0S&Q;lpc2);k$qT;EL>t9)G@`ShHvqL2)H`PbdS`Diq{I6oVn4o>>r
> zxL^EBMm_EHPe-
> @YWl=GrI>|@X8kd*cf*Rb?!Obi$)<sd|tHpeBcRe~Aym+Q``opV<
> z#S6!j;_Snd^^!a3`J(Dr;iOnhZ!S(>u4T-+gUcz=P!j+3dj7#q>8Hb*hUL?nGZ2%K
> zZ7=6H>z?1&;2aq<{7?m?tE3|~s#xBh^<J1YN&A-#7+1I-
> Zbz=C?TFb$)dc%wc{6xP
> z9O>UIZ9K)@`wvuMbtj@B#^sEBl<H}Fi>$3JH`eP9l^?w}!e1;d53|}v(s#S--u1$8
> zZjBBEw{AYrAxLj!w@2J97FYf4h<EVPozZNg6^~fEJy;Ho!|?&Ok`HWVKEHZa85v
> Gi
> zt%YN~UOX$Vd$6sI{Rq8oH61;hk?dW~x8TNl?e^Q)gDlVX>PG)6s(|%+dH+0aeR
> ?+8
> zLRGET#fNG=pd0k(l;RuCi~034n33M)HaNoI{OZ}{cz?M{&)Qk^z^VNH?1_i$>EN~
> v
> zh8TQX%xAON{q^vPG2EXC6hb=MPBkyC4z>3&#iI7Sb2i;%Ir8Ofa(8n%g7`E9sQ
> Vu@
> zH-HZ5@NTxs^Ss#9?jRz?-
> RaXcxqH#9tBNHE#7mBS)^@ap2i@W5>iXv9_I@&*v8kOJ
> zb259X37@oo)ugNP<@EMq@PUr}8u;NK!FB>L^?81IGnp-
> 6KBVbbUiP0Newv=#*85e(
> zYJPX|Bxr1;+>r}(PR?&&3bctK#qG)Qbyhm453Uuf+11HY^ob+Wx-Iz5>D81@N-
> O3}
> zj&4NK;Y`&UZWQ_S#l$$<QgrWf+3<GJptt77o)bN*4Rz+TW7oYm@s0za*W?Q?
> jvJIX
> ztDWeWyA9Kh)8dy7H9N2OH&>TO#QwaF9m~tVSBI({H5)jxx;~mktz$=i_XLhaJH
> k9y
> zskD1p*H@3mkUC{Gzlb06eJ*-Df4$kDZXB?>IfjI!L%RdycZ1`5+0Rez78rETXZ8s3
> z7!r~WY|jd2jgP_o7R`ToMY6$-
> JwRMt9hyezi9PPvkd~Xdyz29d3zzr$;u9=Q7DGPr
> z>F_+X0g^<UNDIENIXqj9n%*+2ZM>QG@2z@@`}zTB+QTr<-
> DEnSFP6(C#@!*${qp>@
> z_u;5FNPxY#gb3nnzVL0BO?~QaEmN|ydsAmE&kx$_-
> i=jDep?qE>71NhL58~?xk4EJ
> z{_1@20XP6@_w?fWex}ori+nM?y*#UNDIxLN)LDx|PEmC(tq|hs+D=f&`e#>@h
> Ag0B
> zIlVqVdD#P&&fwy9Y7*A#iDGeoHMD1SdRM07GlMUv9_Yv}tQwYArU-
> TiqkF43*LSPQ
> z<!P<Z9|-
> N8!KA(6b&EWv#ofh;CFq@z>H6H)DU)sSOox_{T3%ZG?hdYMoIcJExLRDl
> zOpc_zv)j!b$~7mSURtU*y)YSab0AOj#E7sL%aOs>&fwa_MDfDkSlygj{mTISbhm
> &T
> zn-le8dy4s`Wk}4hYjK#MQuiiSU!7U(NNY4_^^!hW-B_)8I_j&MI;VG*snnRqJ9BFU
> zc53y@<slL@(@VpwEiY9|((IzahDY?p*^3%arYE*@Bybj&#mw-
> X1{N`9Zi`k$x~*=U
> z8OCFEr9h;8L#qkI?aS%&<nyT(z~^pky>FvU?-
> qC3G?)@{zjvlwZ%Qln=eZ6cXQOS!
> zJc3<azl>D5{x*gqqVLXDS`}FgDQ--k)aV;Ex6&I;XCw2oZ;wg^(sh@`^gtg5uW3ZP
> z+h>-BsY6-aFK$(*vW)t2uW!>Ni6y~zau}GMZI`{L8na%E+R^NIrLt?oOlm~y?-Wxx
> z;4|Ic>FGXg=o{K<B0Doo#aPjlden_4%Y6lTpH{-Vy*+eQXil+^=^WWek7J6vJpvP{
> zF~u^I=C`+tPoh|o-%F|6lfv7)o(?wVzbb@{8%vop-
> Z6x3p9ytiMo<MRo6_S9oNI3t
> zlV{uFB(;3VT0|QjtZsz=)VtN1V<z=W>z>oqy{5Pl;x=d&bVyj7+~3|p-s|0DzCo=i
> z1>73Z{R%cDBRJY)O#03>;eI-
> AUJ$mrJ>j?**@MO1u0Gb4_N}BXZ)C@EayvSQ<n~^-
> z+l6hHPR~X+O>y7#^Nd8YrtI*10h!^$)05DK!Rh&BW84>}AQ(fe*xzbLAFHpe(Ol
> @1
> zLA{@gLG^(M;ifn*QoqB=diD&fL^}1!QxH_Y9QH+s4fX}OxTz1tL#_>DNH)@b+iW
> LO
> zncXSfw-U2lClgg9XxGL4s3tO%^)K#f-Q%a1ka}g6&u-52u-
> g&4Gq|jsQ^@bQ4e4Gh
> z8Wnmx&3I^Dq^AmwTtHqo3M>|P=W29BD(Rfv){VU;(upUp9pe;+PPTo9Re<$#
> (SS+s
> zqE629Ti*SRF~f?>P^*S@_0VI^E9%<Hs#r}fnz(_r!!)y2hK?`?o3&}x$aJV%>Cjl*
> z3eBv+bw@Q?E5BtvkCiAjVI?$deJ4Fv{U+xlkB;HX!8=8}HSsWsrsWS`7violJLDb1
> z{lRAE(^k3R{TsUtIiESru5?Q|DO)tDukw3}J2oMhT_Wb{$nQ6HtWbOZPFp$vS3K
> b^
> zKs{T+7i|NaAYR%9#WwKhVn++%wtImYOW>DG2^sQ(yjjU1Y7^^6=72=>t|kC`
> KFf??
> zDGIpzc5^$}HNlC3cglelkc;gGA$>K!m2<CoV0P}sc5-;Cgb;aZ%{{iG&X%RDnYMMY
> z-5f<`Cz&sqsZF)U+HUiZY=nei$CNd;XHs&?T|M@Od0{Jz`Cc(lvm)!JnE{(`t1i=l
> zNeXVUQ`NoKqisz3iSh!MEb3y;sju&tMzctu?sZL-G251}3T}%Vh64$*dAXe)!FueO
> zQ65;*8!#@m@OeARR_C|Wm}euc5Z7xxBh!W|*5c{iLp&{N3`J5aabdZoTKBN}c
> TAJ`
> zi=4$8Qtdfxk!_-rr{}E4+EbC+2w<dJ$6`o+9Sa=k%&JxeuUppLvludG0&t=<R(k=-
> zE@k)U3G>#tytvt3S^3s>tz^`F=QTGH(wItE@5&CG&XN=ZKkbIv^z>SJ#;pb9MET
> 3i
> zP+Qr&`A*8pQ>|yjk=F}muQrl*+X9v?U&;BsEr41KSuy3;Q+b<hCqi_t2v4^%LOy
> wu
> zlbCgTCvep78*FCJPita%TM((fXwOJa$}e}7aIEJ<&lRmX!IgJiwDcYHT8{~pyq=Ex
> z7E`7x2_3p8XP4J^um{Uza({Pyc_t(9zNoGdY$A^W5t#d*n(pDw3fJRfjHL=T&hM
> #U
> zc+0dJmCeouXqn>k8s;rb8g&NeFabsMCaj!*FHeXG1$fo;;oEi}v+Bm1S^)t2XZvou
> zqPKVlgG9YjmEF+p69e5_>Af*!WDI|n<|YJgcMk~)V|CX<F--
> *wv2vAGMj9ri^RD0G
> z$V^+lU1Wjc5zaGX-3OzbwlVCn0n*)4=3zA=MU9w`Iizh$bzj^JrK(OZh!~YjoHtB{
> zz=ti)&QHzt7X(}DG&MBKIyYBOSg+UL>*^6r&P;?-
> JS(#!^BOX>H0_=m2gNNjLcVE3
> z_r<kbTa>D5fh)C>Apn26DvH(gs%93Fw~1Yy7=wj^4R=}bEiR1d(isi?^wc8E7G9}x
> zc5}Kmw4)tu!+3OthW}FbdjC5+6T`<$nL8+0vm%ac`efynH<GY>%@M(?Vk(engi!
> xb
> zn-HF`t1L*1P_i=DEFV#c+}c>m+pFC>f{=ncAJE30F}YLNAJw7pgDtl-%B;~RA4=EL
> zd()FlkEG_*)lq)r=9%=4k}0YJjhPiT3Uvru3V|@9I-LrS=G2(N<sM3)2lqI*m%oW*
> zx(ma~xh*C<n&B&ggEprDO0^20cA!w!Gn8=_7W`HMx1OtU^gxa7D-
> MX01)sG^jMSJl
> zQ@|d{bjX7f+k7^`vgO8VmXaD<|7t&xF<Z?KZ_FN5@oze&$yBJnU@-
> wizkUNb!40@v
> z3MbP@7Y3UyiPE{^khU<!R%o1uu4QFgUS|R~uub=543etI;C-
> {@Qp;~vRR3M5NkN&f
> zn4Bq=apLi-CC?k^7&cumtWZi}V<#(#YNlYY;6qt*=U=TIn1Gzhi6v%VbggRkk*0fO
> zDkQcN9egY4K-MfcLzHs|MR;r(P}ZG%(Qb3P)QYjU3|eSX*>}=&Igl#uNlE41ZJ1e5
> zLmH}&^e*O9nPIJ`MpTVUguLR*7tBm^No^$`5bRJ&jnJSvwH6mGSV*HPy8DTq
> 3t7-H
> zh>8tN<<OW`-BaR3&9x%-
> QfxWUS0yC*)io?Lpa@t?Sfou?eGHWJq^VV*f>R?+b!j`)
> z6s0ZC)1g%A#VrA$I@7XAw$<>03V=>2;d8`EM@g3=zrIo2vZ=?ev4o|Vup;R>_
> pcCU
> zaYL*oX+Ama8^$T8?IUIPIn}}A1wlW%5Xk40Te4mmN~bA_sfshwdH_<YM?;?cu
> n1%}
> zt6lve!e4!f1Hcd&nA(6q5gJ91&BANbmQ(9!y|l}{^i&E+ensF6qzanVi*{F)B@-V#
> zS<RZKMJD!!e#H_tSb|R+3}FW*V+0P=UhvGWQzO>GZMqo^mcBC~0iLGTxcoR
> PfI4bJ
> zi#Zt+D)DJhSju1%g_Nq4tQBDvwAfC`THc+Pp+nrL#pH-
> kM>=E)BNaA;HiI5BVazx~
> zRMW5{YzXLc2(7PDrPvFCeR|ejVaf3rO?&L9fdya1kf~mQie`GjnAS1Bs>-K>la3zd
> z!1r~S2c^3pRAy|FP|`5f=^fxmZ<Uf(f@<-bsR;5t5fGIbJ+B)QW=dT})t0Ip)D^K(
> zpbw1YBI}jT+CQ;AtRtd0U7d@uUh`p_8n*&Jiu&AP%i<g_aa+?WC%v*G1I%p5P
> 1$`S
> zhcd)Ks2*9|(N`0TK;}jmR`Nn2G8^?w8jzcR56nss$;I-m3PGi_0o?kC3#>C0!XwjN
> zs^``Y2~}`~#QS<O_?nAx12&N#xt(BiqNh;S`85$}AfwJ#1<-V8nk1${kl_N)k<4(A
> z*9#F{u9$a#6J;aTGoq8U*Hq)H%hB8-
> 0!hy}tzim>;jQ!G*ZEaVH7bS!pmRQRnVw2f
> z#WH;Q*7B~Wqz6U(tk2a6V6pH)&N8)<f;bzQR9HFF{1pNnNdvNn1)p+o1gzeJ6
> B%-a
> z0`*Z>^XqY9NnI+3O#o5Y^u${EuHu`3oa#%69p^u7%R$c7B2J?E(^G5=ISTIZmk1
> 1n
> zBeo{euhu>j*@5>@q&8cxx%`xMxL=*F4ajkTNouWz<0@Z!d_ZTR_^>{+voM4X
> f6<eD
> zn=Xjz3Tm;4V}(m9d74M>Dmy3a#8W=XH(K1d-o&)86K+CM6-
> <U|d3eLJ>BjW2l5J47
> zysnA{hdWWh8KOxu8R=MB=%~r2N!0(UNlQ8{l4!!L$Oy=2r0IVWk;Yf7uPTcSGH
> dcx
> zrwC~7^K5+szx{8iusa=ED`U(CSE2H*5V3+pgp|L-I+)f!o95ii-T9@vYQ<mpd`V_a
> zXz+kBG)|$nA+)kTGXO$Y&U;VE5Tqw9196AT+S8#>NkwFu^50h1<!kt>Qx-
> Qaa8eMl
> z@+Ehm%$+p(eqPq{D%i}BBBzI{hDzfv9OO#Iy6N~psUkXl54EfH%L}5eq=&|)SoC
> VC
> z7A;oQAw$GCy`v`c!C>?KLDX~tK*@<;=o-iK&_q1>AjCI-
> sF_wW)1uaQuHwj|1l18?
> zRciFrj>v4aqM}LBCgY=H#MKM2)r2)p&siS2nf$pVniiXv(o7<`zew5sL;tF&Ju0>;
> zxI~600TJnh<(CmdsmZyzQd5xa7B^XwiMa?t>FfZx<kH-ub-
> }z1*q$RA{#@s)#C9I^
> zOe!q8KCL6?E_mz#@K7-@qVLq|XV%`1^pj;Ys;-r%M(};f*C?ftkf_i6!9T6nQ3;ix
> z)P&*#hTJ;}<n!xj73=Ui(0w`ATF}%D846L0UDSRHWPH|>{xX}bR(-ggctEQq#z=0S
> z-;iWh>M2hNF$0uJWA;Zk_xE>KL#?O}M1BQE`J}|-
> O=JXH#oT2SxR}HWB*k+!S*@}P
> z`6xPqQD>RN3K=rt9k^%NbY8=WN^v#E>9A~0uLM#!9qxu&;!Ib2$o1$dgw+-
> 1oCbkq
> zD3u9-
> 3dFBQt=nX*n1Hw!cUP^&yg7@#r)o+X*ebSkX^qkW3(CO}U81VO<s>%cP>`eH
> zRZK%sNsdfkNa0zl@mNC>tyPdKD%bF?m2%6o7qW9{9)TfC5};_n;E0c8Dl|19Dj
> Gzy
> z))6N;{kM!UU==K3Tlz{PU`6!m8$GmgqIm2zRsI`Ldqs21z{<!0FBI80CauTnFi+GX
> zUfR)QxRlWp+$$L{BnCz%WwZ1ZHEqt)RW~<GXUs!fox7`gyb09i@yd>xv4$el;op
> qN
> z;Y+9xHAP6SJP=twGR8wkgHrBT{-
> ){#)M~Y8qiNH{2AoDhB8=r(Otd4X{(&EBdw#M7
> zQU@v`J#o5Hg$_{>SDuZKNS&15M4aSOOJ+V)a*h!ii=d1%Su-
> NXa`fRH#dIvhqau9~
> z4Rv4+ottZ*-
> *iiUcZ&warM+JB*quyAAba+z=|z@&Ao~EVvkBMuOsYeqB=zpFq%j@5
> zUi0h)nbw40SePx=_*7?dR)I#$l|kntblG6i5}B~g*1V-M3bjKxLUtphB<T-GJ##*N
> z#k!Q4t-6h`cX%!-t48-ali?I<?7_Vf;!b94WH6DDO3KxmgKgEu8h4ewt3o!&G``Bf
> z*uNPDGto_C@Sf&Erd&{iE=MO!>!>MzvH)0iU*`SDhdB+>v~6_9bXWPXup?tOz
> z;Fg
> z(UU<TD3b5cKiZ<bxttseP|GXh@oWnv+5M<{C4sVlhICi;^3KgzgS|G0y%rvMSItN
> x
> zwc`{&)MF(Q$=G`vbPiTVuBD`LSUJZ{!@nv8gV<B0msvbRMwfO=;7_e}YH~lBfiZ
> OC
> zDY&WZI;hl`I3JAC?Ep!GPJ$kZoF5_ablpM83Q0BKqiF}J4CU>p9#U%uK)HLrlyFCF
> zmZEO${U;V+wIk$#N=aY7AcFywQ%W_xoZ=&E61sxq`G_Ffl}Ycrdi;7BBzA4)K*4
> $+
> zBTU6TsGiKw2PiqUq6GIRI8`ZB%)t^d9x|Vs&<!YDw~OH+DRXQkhK#JPSW@pcE
> zabu
> z7NQ~clj$1N7W=&q3@fvuRM-
> Zm{maUz2z8?5WCK+#(zp;$QifOAeho6zw?_=m*r^7_
> z;M~cwQn3ZKr3pp0+WT|uPwmYRq>81!kQ_<Vw#p@MBw0xA06{?}a`ui-
> 6m7<rmgpM^
> zi84igXq4egWX*52vpz)YJodTt_-
> F)6@`}>#ObiD}?xyrvm^PL&$MZS2Y^{u2x~?q@
> zlC^}K@9@)+gD?amqNiITwtI0I3!=%Ba_C0p{L>3WIv(`X64HpWbQ>8hp*CszR!C
> _>
> zgyej>M8}n3gK+B`bA^#`wmp8^zae8y#7|OdT*%N(4hLy;SBe00cf};{n)+<pW1q;
> ;
> z3=&%e#JX}K2Z|JYQx@X`LF<B|y#r=Dz9Jo7I+rcizmgsD<?IKUagwXfX^b+F8UJ+
> s
> z=PoTUZMsN>v9cFv|ABf3BA*}Gx@Oy{?}FSe@5tDAaTTG+y~Oh9)5-
> }SG8~lqljSsV
> zT_z2SNtIZ4+cW8RBO&EFD`_KL8MdOuOb%8V9Bpyhr<_bZpt12xtlJ~g>oOysY`
> 81)
> zPS|2l6{Y9y=?*PX(_27omd*mPcbV>j4B-
> PGDeqWfEhZgzKyHUu<Xj#Vc4>TL+JH1W
> zWJXp7)XBsMC<c*Kzkicc8K88O<n!qr>uVPa7Fq0C^XV-%^W1^r&9BJJ7djx6)-
> pOn
> zGF(F3G8yS3UI6R`ClocyTWm(O?y2Rj7AzJG(Kc)A0dCV}v<}%?Ji~mt9KF#&hIGs$
> zdUDE%#6;!V4&o)lnq$Eam8Drn^@jU>Bla#o8ZPm5)aEM(Et@U_lnq!M>X95%(
> XBz`
> z06k6~NFgA@NI7a@!*eN(2hj*}428tz3H6ZtZKRX%&pRY)!5DxM0m?%Wy#bDl
> Hqq`Z
> zRdXCn%N#=zzLNZ4={$0y5thc;fMw$&bB{PWkb<{U8Bjo`@sGQii9}*B(}>4G9!k
> p6
> z8A2KPh`m{MH^N1k@Xx{}GL`x;fmAyL#UsaNM&g96YUxV<1z5(vS#uDIHv>_cC
> k`?a
> zN!mEkr}z;A5cMwsBFEuJ(v_ADdp`+rA_=VJRqNOyEYc=97|R{=kfT>(nG<R2<J_v
> 8
> zog-F93Ka`qDT{QV)fLkJMt;c8x0%@sm(1&xx)z}<c%IWSd4aH%=Sp06iC#1XiXU-
> Y
> zS8sHnHYp!;N@cH>TI2LWY*%G&PsylVGnk3%RQJNM)ywizcw{7@(l4SED1O9l*
> 2oVz
> zQfAa>g>OwE>l@YUl?Xve(Z%l1!@(UH48<a`*)^3P^0t(8nr$w9ujsnU<X$qalOn)
> O
> zwuqPP8%`vINaai?QgY6hbfm^sq+<1n@vSS^>Ld0xQscg-
> S+@`0EbFi=Zy36YKmp}P
> z{m`y~AI&C$Cq0rRx_w)h*xzU2dscO<9ey~q&B4qOV()3^0=|^Bn%@c;mYHQF5
> ~a3L
> zh+b_&+(XV0aTCEDvx29C?8%bU$TnOvZvw2P+J_Cp!K{l)qlt1R1~Ypi>Rvx7Cz5kI
> z4XzWZ+VNu>`QXA%=1*yI(IJ{B7sMka<@Z@kYL95`sT{L9hVV6`wES-
> 8{g{cwx60m4
> zKAQL;LR4HnAcR#$F4}yXYP-
> hDBnwB$xUA6uvurx`@y*?@z!DwEF%J!5tAW^7R9o?*
> z8uB*qL)mjKA4%G~m@HSz*(F!)+flxzw5%H$BEHXJd?5&ij&V2(kj(%k{pLVT?d
> @-i
> z^aHkzb~k%2<}t|Ls*V1xLpkg8dOhh^v~Ns9N#omkFjvlXjqHHPGclhoV@Oy;PC7
> PV
> zvH6kM`h_GvCr#sz2LGy5I*2M9gdb8N2#dNI*?mfM#gr!ECO;%S5c#ZFhEfC<^N
> 8-|
> zitL$sL7OEOlhdsfn#Skt`9TC;W^M5h5yk2l=T_HVaR(~3GZHB_nH77NAFrY>Y<Vv
> C
> zEuO^)KvVpxemuzBR_HyHAEIwPEkDfI`<x{&Bz8EM#8GQ(I#B{!(q9%o;hE6|<%h
> _K
> zqUKK~X2igOlpHeuQTb0O<Z#5Gm&EEQ*O?suAP%%qP^&e?3)u^?lj>nILXnDZc
> l-rE
> z)`TBY!0G&lbk-
> wjRg}K+yb}3RWa94lZ}X=4eU^y117+ECSYAaLVg)F35un@#Eml_U
> zZ842COPv(Q;AE(Py#tQeDmfob@{gMUGNg`m(c=3oFw@~%ME{EARWbyDMH
> hU<^sX&P
> z2ee)gylI5g)Sc_6mKwYO*|EsfdaU)RXQu|S`FE3(RHh9efyC#!?ZHg!$-B2f?l(>S
> zD>>&x^Gl@b8Y6Ei3K>ViGDO7kuXb<47H`&k4TnK6qar+eA(iP)$TKmRVK7@?$
> i>NY
> zF|3@Cp!rvFXcvbPGVPaS1j_ux?e|}3-
> LATVnbo!Bx2vq>RdGTAL0b!S)klr%aA>+O
> zH}9rj;%LfGl%exDm9cC7ZWERVeAcyyExy}ley*FxS_fqe79}GbE4lB~4rphi5}N-d
> z+1)aKcTIQJlUV{WA5QMSPV(F3UgO99Fn~!9zJYFNy+|(V8oOhPDc&=q$N|0w*
> +f0D
> zaWNrmqE=VLe9`PuaQHfsMfS}Dbf^ft?U|T}^w^5oVHp&~LgI7XQbS-
> 7F_>wK5h*9N
> zJz3--
> H#5vf<UP5PCFWC$03~ch5&aG+RWXZ>fIjxA+Km<|DL<)VnHl1_1CH4ZA4ww=
> z8m!x`8Op>)Z%8^y#4slf>kZU`39`IPdI3)xFexb{dyJzb|K^%j0FK%$9Be7R;+9P)
> zmNmBjmATu?7^{&3J34)?*5i;=AUX9zjHMj4aHpj`)_ayz+e9F-
> <A~Nlx0Y9l&vncA
> z1wz^Pd-P;-5W&Hhsj9Zh(KJ<#awP{@uclUbk#*!vAgg+x;Kckkx=^0hIGu-
> s%>X5x
> z)ZV@&ayUpQALVe6c4oO>GTl%{j>3uBm2G7EGi;Cj?r-
> #s{bWQ4%BD682WQrNI$PAT
> zEryv`oV+IAv5}S0>}MI?rJ*gkDF)GVQsw5+T5XH@p5^6g6Q>*a`t(d%J1j$$1Plw
> M
> z!w4k`qMx@$Qts?c=Fio4C8&=sXO^h)l@U_1fKU!V<X42Z#((D*GRs}%-
> )BiWMvh!T
> zwFJzkiz#hn**-R1c35JL<R)qb{RE(#Nr>Sq>@<i~JjjHn=CR0V*qOdtzu38nX*DIT
> z;`=O+y`WuM{<-edvgtY53295b<fm~-
> c9)FPvaJqfE^AyK1&+BG^0N?(AOi1gTOz+-
> zaeFU!-
> ao92M4r811}Il@1NF9;rt&j^#286mh?s#Sk;_x!@EoT6&&&Q6e#r(V(nsLx
> zxGma;DR*ilEiPl+2P-jcI(I_M0OgD)2e-yo#x~Z(7Rj*!Rj!$s$>n=n$nTTR<B9_*
> z-gJ!F8tX$9lr6;W!@s%K?sMH*sloS!V^CrXbmb77s+LQ!O%F5KVk<YYJp<G(l_1IK
> zQWfs5YPV=+O;OXPlj(kZt;O;x8RBqSK@4VUFp#%pE(kH_$`zvSm0Y{O<bediEn<
> {p
> zOiV6Rk_aC6+Wf*DSs#J5%O2#Y9cO#6i0pq@B<J5s!eX0`RDL^}*a*4JIotb1dhd
> KM
> z1-YRCU0^JiVmzZk2l|{yJBXCzd$}jp2c6fP+QXGrS-X5EQhKH|S4x_5_R&(gaTFaY
> z>I@~S1tllxnybwn=-
> ?$}a+2%X{0n!fjK{e$d^v>F?O24`+m?7s>$<*+(MdTtWuB1q
> z%j4`I)-
> 2~7*Ru##R+(S6#PvwUWdHEQW|f)YU>YET(tIru0)bD4#84oESAQW>AIa88
> zYDp0_=c&xnkh3{Le3#L|l7sj4z5(j`*0p+~0!B#56(5D9<`yT6+A`jaP}aPcZbnD$
> zj6}Cz7HQTTxZJ8rd~YI=A2=ubDrHxKS5KW2C&{98Hd2y*pCvJuS8)$Y23QfwYD?
> !)
> z1_i-uuCSHQ*eAy1{wi|ou&$6FI@2p<a=-
> X=h41bsG7f>16yImr^>f|CJ!*lU%2z1J
> zOt&;2WS&Yd73c017<3`vG>J(136xhYkUl~Yt80sIqpQuJkY{{8-5ktpWz%K)I*d)L
> z)~ZjVFtsALcBYA02tq04c{J$CpXYl`RTv!QBpaNM&Ie+BSvnL!HAie7f=aFVbWUya
> z1Jcy$ZfcRLf~YIGU*(!<OPPBl(?nzv>UtH&i)#Bj5;EI_@t)5+XLs|(ayh>jskSlz
> ziu{1@v#^MVNp1PLZebb$3jf$-BmV09(=>1?-
> N1r2K`mAl>!e{&D|%c`rq$%`M#QOW
> z#CPw9z3Vb%YQcIJ>Q_xk`Gvclu|8d_N4AoK+uL+$A*gqy(yQqFcp~G4dbdsK{?
> QSk
> zoX&l!?S<*=QXyQ?p0RU&E|?}qPAEi6rWvwxu~ZL>5F^moqvT8!+w-
> O)H4<C@BVE=x
> zch{j>xmE0X9)(|f*-
> @D_V!Yo&z8_4^KJ@{cX&UqCOTMHdHL1;}c+JmsivVR^E7W`?
> zUGuFLIIw8}*_p)0fS^X1rM=FhC!Jmh<?u8LORORgQA4$#7k2GAXIdsFMX?NDG
> SQXu
> zbWoxoX1R_TxW5)cqX&)b$#nXHdK(?Fs(;PnJ+98apgGOdm7|w}<WSTjyyp}7!2
> `Kn
> zjro0+DW6vAT2s87+SXvE%}03kYHYfDgxtD&O=grpwgs)%9BW6oOlne+G^#vaG
> C#5>
> z)oWkZi=C;1g0FRq5R~}l8f*wAn=U=5R1UAO#}^`;WMC=%CoXu(A*XX6Y8WY^J
> +3yn
> zQ~P=qM<B|*Bnb}&s)x8`d@zR_2dJbk)i6*p7k1yW>HKruH5*<>^JzAxC++o`?e
> D8*
> z1*p1G-;T1>jY{IBLNpNGFpdA3=<a({&GP`Mb)P*|L_r6NQL@$Ny2ZRIN(h+-
> x7w0v
> z*`%W~HNGJ6S(w3;_0c?_sy1CJ3W)rw7i`v6y?2b0RIaf{645ReDkb|1VF`B#cQu
> pq
> zX;_GnC+Wz^2rMGCBWtF$UmA6w<hrOeQ&&TTPY!7rLsim&oW&@G3a8Nc7
> Q^%~7b+YL
> z*z-
> @G`+C&Z5wVrzW3O1MML3vk&=UwHrb~FcWRee}N22+uw8gA1soZd48E7>!ld
> >Q+
> zsP9>?qB~4s9Ohh!BhrWs<jQ(v925%{BKEGwZBU3$@yh4~f+4$9l(mK5^i(?uRG
> aGM
> zD$Cfl!4DC8UeE=(v?e)-Uy~Fq^{rwWS*Ab^aV}SYA$8V7T4^0B#0o{p3O-
> k~#quhn
> z!>{RZf>vopGwJ@osY*$uo6D<EVKJi6<9W6eY$qcyHC$XXmPa55I5YQuS=DW@
> Wx1<7
> zd8X!b-
> OL=N#(a9gqrqj%%oKUHS)o!UYZ}kUu3Z0$e{}FFR3&}&oCHj@MmNTkCCYpK
> z+WR9h>QVTX16AD662@!-5`%|>4Tou6%y?3Y18VKy0qTz^Bo%t%-
> l+PhDTz#RwB>RI
> zs<3n=2j29qLPf_Rz$BQ)!@tte4iw#D#}%^7j0gu?8(y!Mw_@a+of$!6?rWrS?i)sz
> z#06Kzg)C60Xy8wJ!qBXV!b)U3WrIg3K)1iNGSmzDogW3t_&&=ry6V2TwHts42g
> ?N+
> zPNC$}t3ia-J-
> aO@0HV5qGxk+2mC?Ii(&(+4O{yO{q)K6toF$b2e4MW=c4eX%G`C<=
> zor)i7mvk6kL>h+TC(@e-xGOf|x56)2Xm)dP+J`*}PtGpy=5izl1pq&4u66Ds*Pe3S
> z;9AGps}`yVGTly8&Pufj@>G!9o@65_qtITme9nZE%2bZ^T$i)DKMx068#p*}FK3
> hc
> zyZh-
> }1}X3%90mI>km~>ZV`J%1u#`?TNvu_(C0W>+WU7bJrxMg|*Xfx^B*yk`{vNOl
> zLGd2xQ8B~8lejh+rW~x%J|eK;-
> ~oJ@C=Jq0tcM<*Hmw)X3X4wOXuHYeeK!v9x8#Ct
> zq{NB}DKB1KiE%nhttkt2WKIXb=HcMXnl9PEjCH~DXLU4yrR}QEr1C&~iEH_*5+>;
> K
> z|E`Jxh#l@rC_Ddlb(9YFzi$%>$Y?+{zok90!lpkFssc#OZMyBtHgjY#sw#jJ{bdFo
> zEl_dN!p1eg>`QgApm9UFcLt<DQqO_nwbMDBFE5EuOycH&O+b5**g2nYif@_
> WU=oCY
> ztPVM?SE5n-
> %je^bwGL!$EMTHmlQyX<V6TdF(x|1}83J_40k^RQ{Vk_4feJI)AtGt@
> zS?_M)x_`d7C2==i&N2{udDXTI5$woRV0X>G`k<!OX`F>4>#o#-
> FuEgVqE{0iWQVnY
> zhqZ6<W?No0B86NnNY%RKQ|Q%WJTWs8dG^9q3@MgOx?mz!&8c(oP?0$qY
> Gdfag<R9a
> z$Cg?^ng-
> 4i_J(V1p1|Hx@!aq}JkEMuHSl0>nV;*PkXQ#UcN0;(T2%$Za_a6tMMfBa
> z4yl1(${xf7Q-)}Dq0%i_{-hqPiP@hD&ekWXG5IRKn6@=c{eqRfAo{2oFEp8=;*Bcc
> zwC3WGs!#9ozM%0<RJfEaVpoI91MLY3h{)L&q(EK7+rYc+E!94#CLgi4&Ch=t3{iG
> U
> zYpXR+bykxDWc4RQAzr9Op*-xSQY0Z*z{EX5+UhKoiyE-~$H-!lLq|vF6&)4=-
> exwc
> z;K<@!w%hmurO+Nqe)v$*q?qzS$XZ*_t}?_0!{?C+XRDj3N|=Dw%Z$XWAl4Snl
> +HlT
> zi!n}S?L0sklHc^Dr7{8l1r5U+3x5kfOKIY)XE*6iC+e$`fMjcz)U40lRO23O`*yax
> z9=LeY6PvX-GD|(4b}x**AY4)Sli!_6;Yh4}Nw$I$N=Sdc&B`X7I>FvDzSAo<&=JjV
> zb19cwyLPu4m$!i~%P1`l)#;v^^)But{TyD!{ASqI0RST!DV7N7R`Ny863=k0c4R5o
> z;vMxEyUTvVbn^=Z)4B=T8noNrHtlt;v%9k1@akU7cjWWC(ZJw_nVTn;>nibBwV
> Gnp
> z-
> %e&0glC<*9;1>1+tUV1c2v|1pt9u>+risd+O+9QYaH3>4==9oCbRisv6#>9Z?Dcz
> zd(v*W>a55cANeQR+_!Wel}pG2{9R)y4Bw@2BSBb!j`ARY9V;=?VsGqyp}QPZIah
> 0x
> zTs>*0H#i**&xXUnNiWlS$`vx#Vu`r4YG&K9bVrR)dC<#nv%$$SyG;wqnM-
> 2w>zanQ
> z0NAF8`MK_?&5#!GOoht^(w1l1!rAq8tLZkL&6=GX6J<-
> Se_J#JLLAnb8E&y!!P&Bq
> znZ2+pLpnyX&|2<>qDF3oke~V%7;`Et<JZ~~a=kKgW9q9YpV;i6du^5_5BzI=u6w
> ;3
> zL%J3_a^bDZ1^%07p-
> F>vq?PBy%Kb>4RTrDD5^(jWoeMR`g_?X*kgXnI`zKa#e?7B|
> z`UaRiJuL)nkS?c={Lu{)H&meogim9o*5>u=;%eJ1);i_{=^+OE8ybj@_2dC|g~qgY
> z18UkAJ1Mxn$+D~QEuFHuRWL{{P=hfB3-
> M%fMWM&ycDpfyJw2M!k7O7WIMglkbKS6f
> zM31~1YD}%cB~VMGQ>J?EeygcfHE#kvhj~0YUD0u5dYZCg4J}F16Dz_F0b>zMY
> J#!X
> zGc!no^YyKpkYw_EfWBX<Z(R@6%)Ll4-qaA4^9WNz3{9OL=TPA(W{tI|;i_*-
> %Ry2j
> z=#~%FK+9vWDcvhVw*?%sR$>u%rq_e4TRT@ClumkF)8!ygNUmb=ZGmi~miY
> %XAtbzu
> zKOzJt8g}4IH9PGQX}e{{&{!@95Q-`5xsa8hL&|c0rHu{K`Rrn5-Y`+FHO2C}HlLuX
> z6%4sOD>^@9f<#qa-
> H8?Z!A2B|7Ne<?Te}U#Oh)tc`U9G&UWXjNueL}AEX5dHd&Q0+
> z>wJFMYy!F$Go?@ct8zk`<8=5dGr<8-Sxq)LTK#L4uIZZq>lg%{nf?T|oNp0tSeJ4`
> z6GW1vSHmmj#@i05)$Cg2>Bkz<{^iuz+|#|c>mWZu-
> }cPfFT<fytR@$=hCMyKu`{dT
> z)fp!eL?E=bTJI8_Q_I)XlDf1;{{mL4`R&Dt4r!(Rv)fr6Hy}}WD_?V4+MDIAe0s-_
> zb+MdYpBXI4PDb~&+<?hBX*~4UL27;zF?Cbt#=%@USB+-
> 0!?y;Tb9;Gq(hVWeH0$<<
> zqnoKuS_@_P&vUQ?^LvbFTtF<JPjIn8Cv>bd>kZDX?q;^#z;}w7ib?AERxy@Sgs;1
> y
> zv#nH+Dm%Ab4Bwt&HJ`$q!R6&>ba{1iKbhAz1YT%kL+eo8=YChMvhdi4HZ13py
> Blo7
> z<>mG5{d7?)-B7-
> mO6jn^2F_z0TcB>t6Uj+}?5ts$IkYHWt@6CafXAk99jVx&A<acQ
> z)|!)u7@p;>4Yo@dOBVOic0l-A&-
> wCLU^8y)srA9K30dQbh0~$Ape`cW@@)2`jxK8^
> zY#wPvHCrMci{)~$AyCH{a^@pm`xaM5P`XfQ1}C@m3OFL$e3r9?F<W4Gn4+)
> @Xj9*B
> z#vh+9Z}hn9M6E=J0rMVCi=kTiiV37g?@G($X7p)^l}hzH44vCU8SE|Pi%ah7VBO
> Y4
> z(Y$TKzJ<J=gNJ^gBA_sfu}}9Z=354HEKK*k*S!&$B(%S5KF_V06KimjU+smdwE?G
> g
> zgdpm?(O%cKDWC4sWA<tteL1ZS8q{JQAFM=bj{|J2N93s?wEmXoYT6f&Frpd|c-
> T!u
> ziY5O_c}uj8QS9VyM?+Yct5nP{S?!(6X?_!#tzrwL>F*>WhR1#kQn!PdHjbvEG>Eg
> 6
> za&cUBIx7Ui7Nd5UG?cPdOsvfXtY_O>k;TDR=r**Z#iOn{fh_3HFQG@7fUP~|*N
> yv3
> zm|*nHp<L60_?QgY)~+u%#DO&~N57Ny&1rSc0&-
> Q%YU02qI}S3}mKsA$V2IT#(%waT
> zM}Bc>r(PbN=FJskC)cgr_hNEx<?=!Wa<f{;!UIk2=zK+l&cEGIwlV9Sx3Y>kM6-4H
> zw}kS%zn%W5Rj*p!4(paHTDzry@i<V6jSX~=AvXB5dkPaAu0PcM$!Ax?7t0Oo3
> y|4f
> zJKYo-
> wVK#@?yf6Ydzq`?_#U0kPHI`!4dXif)4Hv2U@CNSb=I$u@;y*I@T+O}<m`G<
> z6OYD42dBN-
> u!rgB?((s)+BT)uun@ero7#M<PVe;m@)jcOc{wa8^5uMb2MPQAj+n8j
> zt@e2zq%dIviwz*cUbdkqR<P9%%<2r9q`PKPNbF?3U)$2583E1jPa9NXr+0EXJc
> p@|
> z>+9>Q%hCDS=}GSc;YCTUw9_A)o?VQt$~Fv7s~NVkjQH)^(R(>jA>P{d(sr`!9R@k
> <
> zG|f7lEUQ~N!3)38t2A?MXp!p&{<7(vEo<E3og190wYuK0Ev{;H*3NZ(xG!d>#tub
> 5
> zsDrsyku<3hdq<Y!cf(rC7T^B=<E&c~aLKP4)cUTZN$aLLU|{!QSm<3_-txV)Uqd1J
> zz2lbfHWf>4)d(UoIn#47o1p#OJ@1^^`QebEeFW)1^3_TR?9hGkK^yG-
> J4aSy$f36$
> ziygp_`taxKx_0sD{*8U{5Ympd4AOZ#Ir#$j;oD(5*REpVNDGJX@F=|ih%jC*hrNy
> z
> z<j)bM!!`WO*dMp7KEES-IlllhJrN2u(F;eFV=vrJlA+p?u4D(~=jGGO|KElqo%34R
> zfS7B;zVip_E$Kj~&qt1|^X25yNTfbc<u46PI=GsZ(JexR@^o?NQMuKA2njSMlN7
> 7P
> z^ycE^1B+ByE!}Vr6Wtrq!(r*c4y&g()M-Ah37M6>0)F%5Vs>{kIv);TC;D!gA8rEs
> zFmI-P*!ySRoKvH-d5_iBY&apruQ@I9)nYN5&8E}I-AJw(Iu>R}hnse~C&P;?48zyC
> zRGuEIYmw=EOw`hW@gdS0zQAo<Z1jPLR62tTSaEQ5eS0^Vl3AVFHZMj`JLd*#0
> Bdov
> z9*EC09<#F?1NQ07bcxF*ie{lGTV71mx}0NRMPa6=w`QcjL`nXx)KV1+?PZ^DoBz
> JN
> zc|u)Pk*+(6d)Q0r8`o+Xa0Te4pXiSk7|n~fis>_~gLE_;)GsrQ=v8MQtbp{kQO(8T
> zw%v{h$LNLdxv`oYjEW2K<RBX-
> AEOl;U}opB4I9rkE?nPG*}jiE=aUVNU)2P@clN#&
> zKi&K0*ITPru@lHFYu*as39#;5wB!i;?9~$>cBm@UX8;)s$VIWZc@g8R>}=8y#Hk
> SG
> zn`a-2TE~aeYv)H6>f@2eN3E`gba1;_YduA9tq#F`?ziK|>REi;`gV0Lrj237_3GI*
> zYd!LfPr5CFLoYC=BhC7a1CmyoV>c4!nI2}NO6A%o`Q6#ejAmz@{`pPKUP^~p8u
> UyI
> zX;fH{=>C#3k~7#|`{H`C5GxMaeAMxosJ*$`^sFXoRV?l<26bydHp6|Y62Oy_!TIP
> 4
> zwqJ2O(J!Xg#`iLw3Y!DelNp=!uI6`Far>eJRB~hxu)$Kd-#<ASz|sHE)8(?^UDz%F
> zXLVrB!PUiwm#lwehCeO%9!x@A!K#T1ST+HZo_~i^o=;29{cD3o2Os#diT!Et3gM
> Lk
> TuM~Ktz$*n_Dey{xHWc`O(cS1K
>
> literal 0
> HcmV?d00001
>
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.id
> f
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.i
> df
> new file mode 100644
> index 0000000000..1f79332020
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.i
> df
> @@ -0,0 +1,10 @@
> +// /** @file
> +// Platform Logo image definition file.
> +//
> +// Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +#image IMG_LOGO Logo.bmp
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.in
> f
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.i
> nf
> new file mode 100644
> index 0000000000..3380f3c1d5
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.i
> nf
> @@ -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. <BR>
> +#
> +# 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.u
> ni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.u
> ni
> new file mode 100644
> index 0000000000..9d1bbaffa9
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.u
> ni
> @@ -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.<BR>
> +//
> +// 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/LogoD
> xe.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.inf
> new file mode 100644
> index 0000000000..01102b138f
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.inf
> @@ -0,0 +1,55 @@
> +## @file
> +# The default logo bitmap picture shown on setup screen.
> +#
> +# Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved. <BR>
> +#
> +# 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/LogoD
> xe.uni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.uni
> new file mode 100644
> index 0000000000..9635701b60
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.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.<BR>
> +//
> +// 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/LogoD
> xeExtra.uni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xeExtra.uni
> new file mode 100644
> index 0000000000..c6ea34b81d
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xeExtra.uni
> @@ -0,0 +1,14 @@
> +// /** @file
> +// Logo Localized Strings and Content
> +//
> +// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +//
> +// 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/LogoEx
> tra.uni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoEx
> tra.uni
> new file mode 100644
> index 0000000000..041179fb75
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoEx
> tra.uni
> @@ -0,0 +1,14 @@
> +// /** @file
> +// Logo Localized Strings and Content
> +//
> +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
> +//
> +// 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/BasePciLibCf
> 8/DxePciLibX58Ich10.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf
> 8/DxePciLibX58Ich10.inf
> new file mode 100644
> index 0000000000..e5ca95e20e
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf
> 8/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. <BR>
> +#
> +# 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/AcpiTa
> bles/AcpiPlatform.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.h
> new file mode 100644
> index 0000000000..2deb2a88eb
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.h
> @@ -0,0 +1,45 @@
> +/** @file
> + This is an implementation of the ACPI platform driver.
> +
> + Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _ACPI_PLATFORM_H_
> +#define _ACPI_PLATFORM_H_
> +
> +//
> +// Statements that include other header files
> +//
> +
> +#include <Base.h>
> +#include <Uefi.h>
> +#include <IndustryStandard/Pci30.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/HighPrecisionEventTimerTable.h>
> +#include
> <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
> +#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
> +#include <Register/Hpet.h>
> +#include <Guid/EventGroup.h>
> +#include <Guid/GlobalVariable.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/BoardAcpiTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/AslUpdateLib.h>
> +#include <Library/PciSegmentInfoLib.h>
> +
> +#include <Protocol/AcpiTable.h>
> +#include <Protocol/MpService.h>
> +#include <Protocol/PciIo.h>
> +
> +#include <Register/Cpuid.h>
> +
> +#endif
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.inf
> new file mode 100644
> index 0000000000..b4b52b6622
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.inf
> @@ -0,0 +1,105 @@
> +## @file
> +# Component information file for AcpiPlatform module
> +#
> +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +#
> +# 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/Qe
> mu.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qe
> mu.h
> new file mode 100644
> index 0000000000..f6ef44a14f
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qe
> mu.h
> @@ -0,0 +1,507 @@
> +/** @file
> + QEMU Video Controller Driver
> +
> + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// QEMU Video Controller Driver
> +//
> +
> +#ifndef _QEMU_H_
> +#define _QEMU_H_
> +
> +
> +#include <Uefi.h>
> +#include <Protocol/GraphicsOutput.h>
> +#include <Protocol/PciIo.h>
> +#include <Protocol/DriverSupportedEfiVersion.h>
> +#include <Protocol/DevicePath.h>
> +
> +#include <Library/DebugLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/UefiLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/FrameBufferBltLib.h>
> +
> +#include <IndustryStandard/Pci.h>
> +#include <IndustryStandard/Acpi.h>
> +
> +#include <Library/S3BootScriptLib.h>
> +
> +//
> +// 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/Qe
> muVideoDxe.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qe
> muVideoDxe.inf
> new file mode 100644
> index 0000000000..8370559016
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qe
> muVideoDxe.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. <BR>
> +#
> +# 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/Vb
> eShim.asm
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.asm
> new file mode 100644
> index 0000000000..cb2a60d827
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.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.<BR>
> +;
> +; 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/Vb
> eShim.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.h
> new file mode 100644
> index 0000000000..cc9b6e14cd
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.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/Vb
> eShim.sh
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.sh
> new file mode 100644
> index 0000000000..7669f8a219
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.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.<BR>
> +#
> +# 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/8259Interru
> ptControllerDxe/8259.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.h
> new file mode 100644
> index 0000000000..a9673f9c87
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.h
> @@ -0,0 +1,218 @@
> +/** @file
> + Driver implementing the Tiano Legacy 8259 Protocol
> +
> +Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _8259_H__
> +#define _8259_H__
> +
> +#include <Protocol/Legacy8259.h>
> +#include <Protocol/PciIo.h>
> +
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/PcdLib.h>
> +
> +#include <IndustryStandard/Pci.h>
> +
> +// 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/8259Interru
> ptControllerDxe/8259.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.inf
> new file mode 100644
> index 0000000000..e66b21c914
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/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.<BR>
> +# 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/8259Interru
> ptControllerDxe/Legacy8259.uni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/Legacy8259.uni
> new file mode 100644
> index 0000000000..d035292419
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/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.<BR>
> +//
> +// 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/8259Interru
> ptControllerDxe/Legacy8259Extra.uni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/Legacy8259Extra.uni
> new file mode 100644
> index 0000000000..ee43f6923c
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/Legacy8259Extra.uni
> @@ -0,0 +1,14 @@
> +// /** @file
> +// Legacy8259 Localized Strings and Content
> +//
> +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
> +//
> +// 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
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#46070): https://edk2.groups.io/g/devel/message/46070
Mute This Topic: https://groups.io/mt/32816099/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
Hi Mike,
Please see the updates online below. Please let me know if you have any more comments.
Thanks
David
-----Original Message-----
From: Kubacki, Michael A
Sent: Monday, August 19, 2019 6:05 PM
To: Wei, David Y <david.y.wei@intel.com>; devel@edk2.groups.io
Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince <prince.agyeman@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: RE: [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform
Agree with Nate's feedback on moving the noted items out of the "Overrides" directory.
Ydwei: done
Please do submit a patch for style fixes in MinPlatformPkg/Acpi/AcpiTables directly.
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 9, 2019 3:47 PM
> To: devel@edk2.groups.io
> Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince
> <prince.agyeman@intel.com>; Kubacki, Michael A
> <michael.a.kubacki@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides
> modules for SIMICS QSP Platform
>
> 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 <hao.a.wu@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Cc: Agyeman Prince <prince.agyeman@intel.com>
> Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
>
> Signed-off-by: David Wei <david.y.wei@intel.com>
> ---
> .../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/PciHos
> tBridgeLib/PciHostBridgeLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platfor
> mBootManagerLib/BdsPlatform.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platfor
> mBootManagerLib/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/AcpiTabl
> es/AcpiPlatform.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/Facs/Facs.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/Fadt/Fadt.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/Hpet/Hpet.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/Wsmt/Wsmt.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Com
> ponentName.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Driv
> er.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Driv
> erSupportedEfiVersion.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Gop.
> c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Initia
> lize.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeS
> him.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interrupt
> ControllerDxe/8259.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHos
> tBridgeLib/PciHostBridge.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHos
> tBridgeLib/PciHostBridgeLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platfor
> mBootManagerLib/BdsPlatform.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platfor
> mBootManagerLib/PlatformBootManagerLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.bm
> p
> 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/LogoDxe
> Extra.uni
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtr
> a.uni
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/
> DxePciLibX58Ich10.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/AcpiPlatform.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/AcpiPlatform.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qem
> u.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qem
> uVideoDxe.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeS
> him.asm
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeS
> him.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeS
> him.sh
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interrupt
> ControllerDxe/8259.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interrupt
> ControllerDxe/8259.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interrupt
> ControllerDxe/Legacy8259.uni
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interrupt
> ControllerDxe/Legacy8259Extra.uni
>
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridgeLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridgeLib.c
> new file mode 100644
> index 0000000000..2aaa4b3e90
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/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.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiDxe.h>
> +
> +#include <IndustryStandard/Pci.h>
> +#include <IndustryStandard/X58Ich10.h>
> +
> +#include <Protocol/PciHostBridgeResourceAllocation.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PciHostBridgeLib.h>
> +#include <Library/PciLib.h>
> +#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/Platf
> ormBootManagerLib/BdsPlatform.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/BdsPlatform.c
> new file mode 100644
> index 0000000000..0b66862e46
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/BdsPlatform.c
> @@ -0,0 +1,1553 @@
> +/** @file
> + Platform BDS customizations.
> +
> + Copyright (c) 2004 - 2018 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "BdsPlatform.h"
> +#include <Guid/RootBridgesConnectedEventGroup.h>
> +#include <Protocol/FirmwareVolume2.h>
> +
> +#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"<unavailable>" : 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"<failed to convert>";
> + 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/Platf
> ormBootManagerLib/PlatformData.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/PlatformData.c
> new file mode 100644
> index 0000000000..5f1b16dd56
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/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. <BR>
> +
> + 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. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Uefi.h>
> +#include <Protocol/HiiDatabase.h>
> +#include <Protocol/GraphicsOutput.h>
> +#include <Protocol/HiiImageEx.h>
> +#include <Protocol/PlatformLogo.h>
> +#include <Protocol/HiiPackageList.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +
> +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/BasePciLibCf
> 8/PciLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf
> 8/PciLib.c
> new file mode 100644
> index 0000000000..7544117a03
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf
> 8/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. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Base.h>
> +
> +#include <IndustryStandard/X58Ich10.h>
> +
> +#include <Library/PciLib.h>
> +#include <Library/PciCf8Lib.h>
> +#include <Library/PciExpressLib.h>
> +#include <Library/PcdLib.h>
> +
> +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/AcpiTa
> bles/AcpiPlatform.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.c
> new file mode 100644
> index 0000000000..b1d7552792
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.c
> @@ -0,0 +1,1579 @@
> +/** @file
> + ACPI Platform Driver
> +
> + Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +
> + 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; Index<MAX_CPU_NUM; Index++) {
> + DEBUG ((EFI_D_ERROR, " %02d 0x%02X 0x%02X %d 0x%02X
> %d\n",
> + Index, mCpuApicIdOrderTable[Index].AcpiProcessorId,
> + mCpuApicIdOrderTable[Index].ApicId,
> + mCpuApicIdOrderTable[Index].Flags,
> + mCpuApicIdOrderTable[Index].SwProcApicId,
> + mCpuApicIdOrderTable[Index].SocketNum));
> + }
> +}
> +
> +EFI_STATUS
> +AppendCpuMapTableEntry (
> + IN VOID *ApicPtr,
> + IN UINT32 LocalApicCounter
> + )
> +{
> + EFI_STATUS Status;
> + EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE *LocalApicPtr;
> + EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE *LocalX2ApicPtr;
> + UINT8 Type;
> +
> + Status = EFI_SUCCESS;
> + Type = ((ACPI_APIC_STRUCTURE_PTR *)ApicPtr)->AcpiApicCommon.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_HEA
> DER *McfgTable;
> +
> EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_AD
> DRESS_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_BA
> SE_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_B
> ASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
> +
> EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVIS
> ION,
> + 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_HEA
> DER) +
> + sizeof
> (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_A
> DDRESS_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_B
> ASE_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/AcpiTa
> bles/Facs/Facs.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/Facs/Facs.c
> new file mode 100644
> index 0000000000..a16c13466a
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/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. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// Statements that include other files
> +//
> +
> +#include <IndustryStandard/Acpi.h>
> +
> +//
> +// 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/AcpiTa
> bles/Fadt/Fadt.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/Fadt/Fadt.c
> new file mode 100644
> index 0000000000..8aa10a4a5b
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/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. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// Statements that include other files
> +//
> +#include <IndustryStandard/Acpi.h>
> +
> +//
> +// 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/AcpiTa
> bles/Hpet/Hpet.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/Hpet/Hpet.c
> new file mode 100644
> index 0000000000..aa386ba149
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/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. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// Statements that include other files
> +//
> +
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/HighPrecisionEventTimerTable.h>
> +
> +//
> +// 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/AcpiTa
> bles/Wsmt/Wsmt.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/Wsmt/Wsmt.c
> new file mode 100644
> index 0000000000..12e2feacb4
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/Wsmt/Wsmt.c
> @@ -0,0 +1,46 @@
> +/** @file
> + ACPI WSMT table
> +
> + Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// Statements that include other files
> +//
> +
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
> +#include <Library/PcdLib.h>
> +
> +//
> +// 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/Co
> mponentName.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Co
> mponentName.c
> new file mode 100644
> index 0000000000..dd9cc80e42
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Co
> mponentName.c
> @@ -0,0 +1,205 @@
> +/** @file
> + Component name for the QEMU video controller.
> +
> + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved. <BR>
> +
> + 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/Dri
> ver.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dri
> ver.c
> new file mode 100644
> index 0000000000..e49e7a465c
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dri
> ver.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. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "Qemu.h"
> +#include <IndustryStandard/Acpi.h>
> +
> +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/Dri
> verSupportedEfiVersion.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dri
> verSupportedEfiVersion.c
> new file mode 100644
> index 0000000000..c2d82e7324
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dri
> verSupportedEfiVersion.c
> @@ -0,0 +1,15 @@
> +/** @file
> + Driver supported version protocol for the QEMU video driver.
> +
> + Copyright (c) 2007 - 2010 Intel Corporation. All rights reserved. <BR>
> +
> + 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/Go
> p.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Go
> p.c
> new file mode 100644
> index 0000000000..19ff5209d2
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Go
> p.c
> @@ -0,0 +1,417 @@
> +/** @file
> + Graphics Output Protocol functions for the QEMU video controller.
> +
> + Copyright (c) 2007 - 2018 Intel Corporation. All rights reserved. <BR>
> +
> + 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/Ini
> tialize.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Ini
> tialize.c
> new file mode 100644
> index 0000000000..fbf40e9eaf
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Ini
> tialize.c
> @@ -0,0 +1,341 @@
> +/** @file
> + Graphics Output Protocol functions for the QEMU video controller.
> +
> + Copyright (c) 2007 - 2010 Intel Corporation. All rights reserved. <BR>
> +
> + 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/Vb
> eShim.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.c
> new file mode 100644
> index 0000000000..aa4648f813
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.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:
> + <http://www.cs.cmu.edu/~ralf/files.html>
> + <http://www.ctyme.com/rbrown.htm>
> +
> + Copyright (C) 2014, Red Hat, Inc.
> + Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <IndustryStandard/LegacyVgaBios.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/PrintLib.h>
> +#include <SimicsPlatforms.h>
> +
> +#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/8259Interru
> ptControllerDxe/8259.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.c
> new file mode 100644
> index 0000000000..b57bacdda4
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.c
> @@ -0,0 +1,622 @@
> +/** @file
> + This contains the installation function for the driver.
> +
> + Copyright (c) 2005 - 2018 Intel Corporation. All rights reserved. <BR>
> +
> + 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/PciH
> ostBridgeLib/PciHostBridge.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridge.h
> new file mode 100644
> index 0000000000..3bf31067fa
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridge.h
> @@ -0,0 +1,68 @@
> +/** @file
> + Header file of OVMF instance of PciHostBridgeLib.
> +
> + Copyright (c) 2016 Intel Corporation. All rights reserved. <BR>
> +
> + 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/PciH
> ostBridgeLib/PciHostBridgeLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridgeLib.inf
> new file mode 100644
> index 0000000000..8c6de3dca6
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/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. <BR>
> +#
> +# 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/Platf
> ormBootManagerLib/BdsPlatform.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/BdsPlatform.h
> new file mode 100644
> index 0000000000..1fb031b752
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/BdsPlatform.h
> @@ -0,0 +1,156 @@
> +/** @file
> + Platform BDS customizations include file.
> +
> + Copyright (c) 2006 - 2017 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
> +#define _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
> +
> +
> +#include <PiDxe.h>
> +
> +#include <IndustryStandard/Pci.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/SmBios.h>
> +#include <IndustryStandard/PeImage.h>
> +
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/UefiBootManagerLib.h>
> +#include <Library/BootLogoLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/DxeServicesTableLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/NvVarsFileLib.h>
> +
> +#include <Protocol/Decompress.h>
> +#include <Protocol/PciIo.h>
> +#include <Protocol/FirmwareVolume2.h>
> +#include <Protocol/SimpleFileSystem.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +#include <Protocol/S3SaveState.h>
> +#include <Protocol/DxeSmmReadyToLock.h>
> +#include <Protocol/LoadedImage.h>
> +
> +#include <Guid/Acpi.h>
> +#include <Guid/SmBios.h>
> +#include <Guid/Mps.h>
> +#include <Guid/HobList.h>
> +#include <Guid/GlobalVariable.h>
> +#include <Guid/EventGroup.h>
> +
> +#include <SimicsPlatforms.h>
> +
> +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/Platf
> ormBootManagerLib/PlatformBootManagerLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/PlatformBootManagerLib.inf
> new file mode 100644
> index 0000000000..55da35e87d
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/PlatformBootManagerLib.inf
> @@ -0,0 +1,69 @@
> +## @file
> +# Platform BDS customizations library.
> +#
> +# Copyright (c) 2007 - 2018 Intel Corporation. All rights reserved. <BR>
> +#
> +# 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.b
> mp
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.b
> mp
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..86d7030833a096f54539
> 3735d931d9f4f2fbf8c0
> GIT binary patch
> literal 141078
> zcmeHwJ9Hz-kzh@gFoN)Qu|weq&F~F*XbyPdaEHTfE*dKcjU5ohf-
> &!%BU8pXGG)q?
> zD^tc9GS`(UQ>MIoGG)r#cb?2OW$Gd_vnu0Pg~E?y>sT{Q)F&%4G9u%Xk&#)e
> |2h0&
> zn&2`0PLf>1@BjWNN&Xl7`zYzU`~UYcP5w_masS+n@=v#$bm8A8pL~*ZKm9c
> M6#l(=
> z^C_Iaf!{aDCtrS<d<p+Pc?<u(e4D(*e{bKy^(^^xHcMvkZ-xI>tK`$wx5>BPew+N{
> zCqGF({r0EHo1gqN`6>SUDV+cGXUUiF?`J>zS@QFr|2+Bf=f6mP@rz$1Z-
> 4R2<d?tv
> zW%A`Oeg)^hN`Cb#`2FRtlefS6b@J<9|2p~dSHDSq^PAr!Z-
> 4zC$qfGe$A7@@Z+@Hn
> z_P4)H-u~uyaQ?gGcfW(*-~K-N{qKLDtbX^0<PU%NLo)l_AL0Cu$shj+zrX)e@~1!j
> zDf#vfe@_1V=RYT_KmKR(E&Th>|AgN^{U!O!U;dK(*MI$2^6j7hn*8;ze@*`Ox4
> )It
> zdHsE*z$*n_Dey{xR|>pR;FSWe6nLe;D+OLD@JfMK3cOO_l>)C6c%=ZLK$`j}9J%
> #+
> z`g{~f-@JKc$n%k3)||b2c=-
> M+LnK+A>$>;;@$vEfKfY?L=VAb__wxr}$K&JI&mkaS
> zw~kS*1G~9@9j0;vimRVfxy_Y(?c(tf7y|!~-77nSYEzvqlcpIQf^ZIl@W;O*3M7fT
> z!9kZ0_+7Z-
> @1+@3FK$(@q_Qx*CNCLHfLrh%DN_M$JaLeE@0@S|JKldEOG8tTLJSzc
> zYJ|Dn!`@e*DIXr+U-e-
> ^H5^DwWD+9bE5=`ek8z`XKS_FDqrkua>L0^f)%(?nEBo=A
> z_fYpY?}i^&&`AMu>PnMqa+)M3U!$^re1FlY5cqf;0Cy_D)w70^J`w{D#QyQ|9Rf
> @{
> z8kVb`(W3$AHjlEeUB&Ltb>`mu&NuNEoIQM&cK+Snc~b#~A`kH2n~2dD(13?{J;
> ulG
> z|Id&fV>kskN%9G{)3wsUdQ;W(-n%jm@Z%%a^j$>b;a#Vy<Dc-
> |$FJd0z%bzRz4!P4
> z{sCjp0*YfS>J9)L?rr`_zY37>O@Q{_-78}U2meqcS?f20ZdoD)$&5I7LUsP#5!2mA
> zEIv!W^NqXXbtyvT1i?FFELrj6Q@p|h8in*2V;#tu|Ax1|Dk=1pD}m+Uwxe4Bj5U
> 1+
> zJNV<fsLOyKaN}*L9!@<z9mh8h<ni$wkx9P7lK%h4Z%*B<7Jsrp4EO5e<5xcS!oh
> MF
> zJ_0O6y=;Bij258V7V**nn0p+qQDwP~>Dq?`cmO&E`M9W{0!H{GGAQ{1E-
> QX`E<5s}
> zixRkn@-
> arZCEI?0@4(@!dEW!@f%90CZ#9t*CtDBKkZs|re|+@#d>x=TP>&8u37Fif
> zP;WRXRfWgu@yZqbfd>-qeS<tg%t&h+Aa47}cR8#P>jS!=`3l7Lc);J!$~z?;OIihj
> zxJtjk;$;D^S?~^kMG7IeoW6RCcaSk~q(8<IzH0o9OmK=1x&^#M_~DWL3Z%@l
> %Bx4@
> zQb6AQ0u=1$cz8ZPP&8e|HGe+wWG;a{KAZ!dmCOWS0ZA+r)prfR?Qf3}ZHIRt
> %l`lv
> zzO}JApCzUJ@O1P=5WkZCa0l!MTn7vs`QQIzf_!;+1fA~c0XAemf*X$MP!igY&BD
> W#
> zd-rkbYJv*{4EhQVuCL$*Dm%m{luAOUt{}bp7>!hUi69=~R-
> 0q&3OmUD4Bta0ky`-E
> zBMCQ&c4z~>MVXJ@dBmalpL?R*f<qBnTQ#X(J_tX?h<1tLTfD%Bj#$v8##j&Vq
> k}Yl
> z@AY!xHNnH@N%pU<a<nu~HUmE#yNG;vNkH|7S}oL&{>V4s^ECYzID`MbpMs
> Hs!vn@!
> z&V+3w2Pj#D`tZXJ_M-sGAqlrXPlBcONaEABVz;s4SiqS=@9#jn@OTgGC#?-
> dgT$2G
> z--
> !^SMEK$C2MRMB*}oyW&Rm32W4K0r<wWA0cjG*hKmZaaM^HJ~Vp3Cse}#_#
> BI4uv
> z?}PKYf)sz2zQKnMuroQOk$1S&{|Qw)?8fju9MHeU6|8@9k`j?5-
> ef({?Vfmz{NTul
> z6~lkvK)7~A<pUsHuchXjkS)~s1>zt017ZiRi1VxPE@+rB{(^ty{I0;Y<X_;P2a4d3
> zzTPsx848;6ue=%x{w`7+O9gX_Fu@+d-G_0CQt1Jgj02h4c>L1?!h9HEL8Lugef_t;
> zp{PGRq8g8|BDz@ifQQ!rNT?+7E-FwFyj#SjQa(^$Ab&|ne*?-
> yfnolYlQqW=01AB<
> z`2nRtKFVKgL(mTh)C&}X`>xkSc+-
> }ThiiC5@cGo?>P&AiC2xWXLl_@<ZAS2fn>B~y
> zEP9hpAtG3)%foU#Ho^kTkU&H`)PUUf_74!O_alHGC?AjDQv~}Fsb9)RL?Ea%Qe
> =$y
> zhXSsny77dg7WC*bJj9k_&vlFfOrd>PIjS`$P>+v5YSQ(Be8ll!kPo0&7$ISGu3jg5
> zXsxgbZ_sH7fPv9?AP+Yl!AUOpf$xFw@~#>p8DWL)(2C0&tEB~kMLm!50Ugba{s
> 5Us
> z{jxvCJA`Zj-WP~}DDcsbfH{urt^(i(j^2?UIN(APg@+Rg<Px4DH&KuPFrJR#rf;?B
> zU-?Il{bQ^byA-
> _PT`lAX@&y408LS4N0a^3MwID!3+5?Pt9q;bCP7`5;K~m|xn9z2*
> z>AQp%c031C0MSbO0qqHgqY^dWo@^!kv6Qptfgi3X1$_k|p?4zHpiv*AdsRkD
> KJvp4
> zCm;S4$mS{S0Q*XVe}%Ys?dtt2B$q2SM)p<m;qHcx>;OAaaYNG3l=>gnf&eMdp2
> >%o
> z=g?`O9Y^r5u=@fRaNGm>3J*Lli5*cdsZ`zZu8ix(;hvL#HxLPh>lAxe&{qJ{*>j-T
> zxp#cZ&g$A6<iop~AV{7GB|qS0Cm%j|=!XJm&x4gg_WNFq-
> 6+ThAcfEZU}xf;_f_Fu
> zcj6*&ffzxTI(}$a&VJDDSqF04`;~k^V}kt%@&V){;uxqD?;wMq2+^Qppxxuh6E6K
> R
> zJo^TR`e2}fJ;%pzH=2)NKVbCl)CxWd_5;oku&)D1;=FPgmV0jy`9Z251JJTdy~Wyq
> zmtH6;zz^;0#~4uv^5JwTigFn02i=EN5hSti9rSSO-H;DQIAW}^{cyxP!JbD3d3}ZN
> zfu3>%iSkkUSMU%B1_L+W2G?fj#&8u}NoPMCO%bpc0?=+K7Y}~e4JT-
> u0UxXixi*Gh
> zIGlXAVJO)1f5UnLVAmAXaT^aO;V4#6*vZF3u;&2GBU!=<_5-pV%C>9--
> mZXie*!<6
> z><6ePY@xE}kwK;20D^trTk6uDd-;H-I6}j3nY4jg4Jiqz_FYR+BAt^PLs>wQ%xgJd
> zuaCaq3@Yg#m6nMlC-
> M;iZzf34d`@{+@&UT97RiyDq}mL)eTmB7g~n9&qa1%k>X+@0
> zcN~L|v{hZf8oJ;_91jwI*R>1&c*9b?=T1I#{CK$doA3Fa^Iix*K76-7`y2AZhl_)F
> zV)bLZ7vzHj#VZ61{a}RWn-
> 1Rs@HzmhX9EppR<NKCVs~(WK^wdqVOaV=2iI4w0|Ppt
> zIwy`^BB_8n5%nFE+Vim|sk0j(?EnkM=Z?wf@8XTm(ykMU(x6w32r*QA!#fI&(Y
> }s%
> z8JG`j{I%nUleUr|jvrWW&@vUk@+4?~he~;`_IK<^?429bS8y4eJNHTn%Lg#9*7
> CTH
> zvy!#I+dZi4ITWwt!;Q9}E-#LbA)Yjk7k)|_=v=X^s>ew?VhMH}q}|yOjAp>C;O~NF
> z#yA9O<?1bWQch96hj1!!U7!wN;=4}JIqyD>^5IJP;pZ5tf&&e%Iy_*QiUz=&53jF
> 0
> zKcc=W-=nYsIgn-8;)nM=tM>BEEq+lx0HzyEMf>5ZgNm>&-
> %{+g{t9lO2Z{q^IHbM`
> z*G@jd_yb-H_8bRQuKSk*!hmQg9d48mnp*l-
> *hR;_(GTAb;}3X^lo~rkeG_=gQvmFd
> zRszWjhAU^!12IrO0P{*dI4txuT(wvTk9HN9wX&Oa@)6pBRUs9z{jO#B2apT|0W
> }|?
> zx!x77g?xYoeuJO@k^{u}k%mMkCs-KkcTFw*D-
> <T2)WzyQ13`fw?_VJ%&Lj7|+IvM2
> z8$1hu(W3DOHCG4;tHHjGEr9ci9~@Rts;<04<eNba%q?$69fkVJH8<D~#0F79&
> 0O_I
> zk1z(LgTN4fcZ_8NKb(9-`vJYjJq1WXJ|dcFIfWix4m}?oH-Gx>AH4AdLyq#{`yxJq
> z3oJFpli(sous~4&?4EeHm_DjGuOLB#-H@`94++clDgch~-
> QR~%4a_ZXoBkCN&DZ3r
> zLx0rWDes|tkT7hh()H88A0i*fC8w_dRwW<NBk4eD2*QPbo|mDisQBFJ<GTTtz
> +&%C
> zTsa&|c>Ceh<rrRt|D9JvT91IkL4=qT(5IEYf=6Co1^EcD5MYHQ!UiP2hn@=@IBR
> %-
> zqp}|WtFj-y6GJ`zKja7YM?Bmeln-
> ~qyQKjQ=Picuh?5VeC7b|K`+<O>zAE9u%|Nwq
> zC-
> 4Jme0K&9zj*_#et6@sD97h`1Bft&$8hRQV5CTJh>=)ChU0VV%=M_?sZo7pB8il!
> zkfcqrAh*6}+mGPgx`sl}189H}BH)j}54=Q-!r@vIu8DjAsi=Ioj$OGsp%+4tO2xaH
> zJa;@A@7_U0@B0`S{^0}GNyq2N54<P+-
> O@J=MybTH`PcQRAZcOR1MP=bT~Gx>5=r5@
> zkjrj)I8fd-%17C`VCV#OVn=gIzUr~qh_csK4RSY_d;ndlYaC7aVc!^Gdi&u#13!OW
> z>MQpSV(@jC!L0-jJGHO$Jr0n+c2gVgoL7OqjDO^YKdv80eFcF15dl}I*Pe{sD?k7!
> z5mH}}AO1Exi?Bk6b&}`ncg|!j<kk<Ue0bheN}kTnmhurr9|(d?*7D&5#s@4=uv}x
> H
> z6kzQ<12?5q%15B;<2Rp2goEuu#RszFDuKTj<+Lo4#qq;+9<1JRT*wE$iSJUtWfh-
> 5
> zYAM*GfBm$)QT>Abz&1HcgflqsAMgWu5ZvXkLWgzQ+0_rCbC5_DlMk%bIV!X|
> kFBR1
> zizm7UGkyU6V~nr?kub~3X?K_*a#G{4K2QCisvHlxU<y$KSeL7*Qq4#o_y?`^u`9
> gt
> z@pgFNCD>bGZqHp3qyX$2@~O)q!gn7Ovs_On_5%t5KYXrA)Kw*tfR=0h7;!`leF
> gjd
> z4HR)*!k?qKx;|PdpMU`Nmq`9nK4SH*HHaGG<}M)F)eo&fP{!^FfI#fO3U8GJ@R
> yE}
> zUJ`v%LnnY2z<Wud!}_DLA6|mT?yegpIXKuI+&!Qy1?<kDTYNMA2RQxi7(~crlK3
> +C
> zx3V8_j+PB71bzT4#G1kKt@qI)Yy=cIkbFR$0PF&pTggh$&V>5<j-wS*X-
> ?W5y?t*+
> z^5G@uhAy<#pTa%35!!~+t5C{iV1mYWhxhGD`EcN%2$~F^=K(K7`{Cr(QSkxhx?
> BhK
> zP<#d{2aFVlA<0*jrTY9EAUEDEk1=8w^c8p{NE+aW8;x2>9z#AVn*ohM`2ZaJpb
> bx>
> zG*rE|M7_Kb{9C;3I=gES_)5-
> k0$}byaR^Uc4Q02CNerd@0I7Y~b9FnOBLvs^$Bub$
> z75GtN2>0>8QLFd09>41N&W(cPMa8}2T1dwt;EN-
> y>hPM+OPY`GqI~=aiQ=5P2+JWE
> z2sFmp52df1Jr61~%15vt1a~D4;RazD_EY~K`mVuIz_vJ7wtNbx|ELV^1)YHTxPg*
> j
> zsy!2&D!@~uh4<7#HX8a`rGMqPR#6e5xEH<--
> mY6}Hg>%NeE`ho0)ZI2=pyjqGw39h
> zn~hBQ!dK@w>v4lgFvl2l*)@{h-^Kc&-
> G{LsOg@mB&YlAy@H~1`Wv`9m;EDu^#kN!u
> zfb_#~5i}0L0Xv*_!b?0J-bKF#@)@v%Zz?`RQio6-
> _JvRfYVq>Qm5&$L9mc*MFCPxz
> zS1yiN(y#>V6f)of{DAElzd<7gfqW_;6=$IWudgt4>gB_Cni5t((h&&ihvPu@Japq=
> z&mCm1ukbWdpK5hL77pyY(0C$3{(k)XJ($dffm~Qa5%0${udguri&VnWpkW+fU
> ^Ltd
> zr!GDWmwr~N8V^EoS89we2CYAKr(bpaoSvg~1sDOKrW`-
> K?*e3}G{0t%czhdxxdkLn
> z;X?2E*tzb=TLVe&?_&Md92>l_^-;+Oyb0$38r3JDi}FE~k-
> J01A>1G$v~}HRWUwuj
> zd^mL;>PEofG}s1^I4{6hK6rpw%2Uy6eV>2zwHuBKz$sSeE!q2C$%h}XeqDA>Y)
> NPz
> z*bgDZ6iG)QtRKjBD1C(#@x~DCxj!%M2lfen0D8!+$f0n9h)`Ly{jblz^77$5BIt#o
> zZUpS=fNDdy%g;t3nX5-
> w%2Uxd!9y9la7_@a3NS)OsT*S>AAjW3rn4dy!oEY|>IkRG
> zuo&<jWi7}@1&b2M^#PcXs=(}X0tf|}K<@(&CLhofJx@Y+!5LhiVFef=_acLKz`~D
> #
> z(T6EBrvRL*$#XuOmcxYdGVr66U`Iv&LZID+2^b-
> Jeth$<Ujy!V4n9KZd*c<hC@kJ_
> zaRg*3z{J}%NJ9Vdfr>KZumc(BD?Z-tJC{q9a<Wpg->t1h7Wl3TjjrxM;}CgF>)ict
> z76H4z?}d)NW!+_^q!MpHoIH_IL2Q6>kf(*DgVtDpOMZL-
> _5&9^;iw3BN%#?h_>S~r
> z2MJvo3szZumimR!dJ1|+q5wj0c;&0)!=nV_xt`b8uA^XaXfa7>-mz+U?F)qU`1r$*
> zLq-
> o0CrAMbUMUbI$$|k9<Bzh`=V|ss*BEf`#s=Whet3TuEQsR=b$Ek+@%YupKCa-S
> z&K9gtXGtKab}vI3DHw#^Ig9Zes-
> p+UqPT+#Ze0l!`rVJ9Aga2ML<Dd+#k=mPB!QI*
> zNz{(BjzCb}O(c41Ip7{d@UM^)Fcd)z^VV^tYCz~8;YIktG7U%~*Re4CZ8sxa)l_#<
> z8bf>@&p{lqqVhk)-%a3`Hy~Rt6xoj-*darET&u!J5351Izz;k{r^p@OaY+?UUxi1m
> z`p}O`P&kOO0GHZn3=RTjZ^OF)1*@zMH{>i4!e4}M!3x!55npYEV+Cus6Q{32Kq;
> O>
> zb@YH<;se;#O}C&BuN*;ks~X>ORXUd7AE!G)-
> 3U0GMpfWOG;Dm1K>SdFLoom&yayO{
> zj9n|<V~Bsu$L9$w*z(+PML;~9WE!v{fw03oKK{52IUqj!94He2&}ry+4%Ol9@;@
> gZ
> z)fL`7kbF3|3flu9;c(0ibq9VxWkeNteS&?Fl=2!SLh)VIhbk#xcnc^?I}luoevKY@
> zfCN9KZPBm@fe`T+quhrV_^#*u<B*@DVju_F4}ND@-
> k{Cf1(%Qh8R|g}!~Y&usLAoe
> zRf;-19NvI9et3LB_1{DN6QBeNYrqKOpC2D0?I4AxjBJ(_B=I#EqLelv-V{h8jUL{O
> zOZ!$q`H)Y(`vns7@yGkM>XWyQK@^G!7$nTke{{y6lNCFFkl*`fr>tq54T5S1LGnX
> p
> z)3I>>)M+HAlfq^($ExWSZaWHiQL^UG+r9r<>Xibo6nLe;D+OLD@JfMK3cOO_l>
> )C6
> zc%{HA1zsueN`Y4jyi(wm0<RR<mI7I)+w1jD`u*-
> +87A9S`&wR7Ano=C!?V%l_3iEb
> z{r%+rW;FOa;0S&Q;lpc2);k$qT;EL>t9)G@`ShHvqL2)H`PbdS`Diq{I6oVn4o>>r
> zxL^EBMm_EHPe-
> @YWl=GrI>|@X8kd*cf*Rb?!Obi$)<sd|tHpeBcRe~Aym+Q``opV<
> z#S6!j;_Snd^^!a3`J(Dr;iOnhZ!S(>u4T-+gUcz=P!j+3dj7#q>8Hb*hUL?nGZ2%K
> zZ7=6H>z?1&;2aq<{7?m?tE3|~s#xBh^<J1YN&A-#7+1I-
> Zbz=C?TFb$)dc%wc{6xP
> z9O>UIZ9K)@`wvuMbtj@B#^sEBl<H}Fi>$3JH`eP9l^?w}!e1;d53|}v(s#S--u1$8
> zZjBBEw{AYrAxLj!w@2J97FYf4h<EVPozZNg6^~fEJy;Ho!|?&Ok`HWVKEHZa85v
> Gi
> zt%YN~UOX$Vd$6sI{Rq8oH61;hk?dW~x8TNl?e^Q)gDlVX>PG)6s(|%+dH+0aeR
> ?+8
> zLRGET#fNG=pd0k(l;RuCi~034n33M)HaNoI{OZ}{cz?M{&)Qk^z^VNH?1_i$>EN~
> v
> zh8TQX%xAON{q^vPG2EXC6hb=MPBkyC4z>3&#iI7Sb2i;%Ir8Ofa(8n%g7`E9sQ
> Vu@
> zH-HZ5@NTxs^Ss#9?jRz?-
> RaXcxqH#9tBNHE#7mBS)^@ap2i@W5>iXv9_I@&*v8kOJ
> zb259X37@oo)ugNP<@EMq@PUr}8u;NK!FB>L^?81IGnp-
> 6KBVbbUiP0Newv=#*85e(
> zYJPX|Bxr1;+>r}(PR?&&3bctK#qG)Qbyhm453Uuf+11HY^ob+Wx-Iz5>D81@N-
> O3}
> zj&4NK;Y`&UZWQ_S#l$$<QgrWf+3<GJptt77o)bN*4Rz+TW7oYm@s0za*W?Q?
> jvJIX
> ztDWeWyA9Kh)8dy7H9N2OH&>TO#QwaF9m~tVSBI({H5)jxx;~mktz$=i_XLhaJH
> k9y
> zskD1p*H@3mkUC{Gzlb06eJ*-Df4$kDZXB?>IfjI!L%RdycZ1`5+0Rez78rETXZ8s3
> z7!r~WY|jd2jgP_o7R`ToMY6$-
> JwRMt9hyezi9PPvkd~Xdyz29d3zzr$;u9=Q7DGPr
> z>F_+X0g^<UNDIENIXqj9n%*+2ZM>QG@2z@@`}zTB+QTr<-
> DEnSFP6(C#@!*${qp>@
> z_u;5FNPxY#gb3nnzVL0BO?~QaEmN|ydsAmE&kx$_-
> i=jDep?qE>71NhL58~?xk4EJ
> z{_1@20XP6@_w?fWex}ori+nM?y*#UNDIxLN)LDx|PEmC(tq|hs+D=f&`e#>@h
> Ag0B
> zIlVqVdD#P&&fwy9Y7*A#iDGeoHMD1SdRM07GlMUv9_Yv}tQwYArU-
> TiqkF43*LSPQ
> z<!P<Z9|-
> N8!KA(6b&EWv#ofh;CFq@z>H6H)DU)sSOox_{T3%ZG?hdYMoIcJExLRDl
> zOpc_zv)j!b$~7mSURtU*y)YSab0AOj#E7sL%aOs>&fwa_MDfDkSlygj{mTISbhm
> &T
> zn-le8dy4s`Wk}4hYjK#MQuiiSU!7U(NNY4_^^!hW-B_)8I_j&MI;VG*snnRqJ9BFU
> zc53y@<slL@(@VpwEiY9|((IzahDY?p*^3%arYE*@Bybj&#mw-
> X1{N`9Zi`k$x~*=U
> z8OCFEr9h;8L#qkI?aS%&<nyT(z~^pky>FvU?-
> qC3G?)@{zjvlwZ%Qln=eZ6cXQOS!
> zJc3<azl>D5{x*gqqVLXDS`}FgDQ--k)aV;Ex6&I;XCw2oZ;wg^(sh@`^gtg5uW3ZP
> z+h>-BsY6-aFK$(*vW)t2uW!>Ni6y~zau}GMZI`{L8na%E+R^NIrLt?oOlm~y?-Wxx
> z;4|Ic>FGXg=o{K<B0Doo#aPjlden_4%Y6lTpH{-Vy*+eQXil+^=^WWek7J6vJpvP{
> zF~u^I=C`+tPoh|o-%F|6lfv7)o(?wVzbb@{8%vop-
> Z6x3p9ytiMo<MRo6_S9oNI3t
> zlV{uFB(;3VT0|QjtZsz=)VtN1V<z=W>z>oqy{5Pl;x=d&bVyj7+~3|p-s|0DzCo=i
> z1>73Z{R%cDBRJY)O#03>;eI-
> AUJ$mrJ>j?**@MO1u0Gb4_N}BXZ)C@EayvSQ<n~^-
> z+l6hHPR~X+O>y7#^Nd8YrtI*10h!^$)05DK!Rh&BW84>}AQ(fe*xzbLAFHpe(Ol
> @1
> zLA{@gLG^(M;ifn*QoqB=diD&fL^}1!QxH_Y9QH+s4fX}OxTz1tL#_>DNH)@b+iW
> LO
> zncXSfw-U2lClgg9XxGL4s3tO%^)K#f-Q%a1ka}g6&u-52u-
> g&4Gq|jsQ^@bQ4e4Gh
> z8Wnmx&3I^Dq^AmwTtHqo3M>|P=W29BD(Rfv){VU;(upUp9pe;+PPTo9Re<$#
> (SS+s
> zqE629Ti*SRF~f?>P^*S@_0VI^E9%<Hs#r}fnz(_r!!)y2hK?`?o3&}x$aJV%>Cjl*
> z3eBv+bw@Q?E5BtvkCiAjVI?$deJ4Fv{U+xlkB;HX!8=8}HSsWsrsWS`7violJLDb1
> z{lRAE(^k3R{TsUtIiESru5?Q|DO)tDukw3}J2oMhT_Wb{$nQ6HtWbOZPFp$vS3K
> b^
> zKs{T+7i|NaAYR%9#WwKhVn++%wtImYOW>DG2^sQ(yjjU1Y7^^6=72=>t|kC`
> KFf??
> zDGIpzc5^$}HNlC3cglelkc;gGA$>K!m2<CoV0P}sc5-;Cgb;aZ%{{iG&X%RDnYMMY
> z-5f<`Cz&sqsZF)U+HUiZY=nei$CNd;XHs&?T|M@Od0{Jz`Cc(lvm)!JnE{(`t1i=l
> zNeXVUQ`NoKqisz3iSh!MEb3y;sju&tMzctu?sZL-G251}3T}%Vh64$*dAXe)!FueO
> zQ65;*8!#@m@OeARR_C|Wm}euc5Z7xxBh!W|*5c{iLp&{N3`J5aabdZoTKBN}c
> TAJ`
> zi=4$8Qtdfxk!_-rr{}E4+EbC+2w<dJ$6`o+9Sa=k%&JxeuUppLvludG0&t=<R(k=-
> zE@k)U3G>#tytvt3S^3s>tz^`F=QTGH(wItE@5&CG&XN=ZKkbIv^z>SJ#;pb9MET
> 3i
> zP+Qr&`A*8pQ>|yjk=F}muQrl*+X9v?U&;BsEr41KSuy3;Q+b<hCqi_t2v4^%LOy
> wu
> zlbCgTCvep78*FCJPita%TM((fXwOJa$}e}7aIEJ<&lRmX!IgJiwDcYHT8{~pyq=Ex
> z7E`7x2_3p8XP4J^um{Uza({Pyc_t(9zNoGdY$A^W5t#d*n(pDw3fJRfjHL=T&hM
> #U
> zc+0dJmCeouXqn>k8s;rb8g&NeFabsMCaj!*FHeXG1$fo;;oEi}v+Bm1S^)t2XZvou
> zqPKVlgG9YjmEF+p69e5_>Af*!WDI|n<|YJgcMk~)V|CX<F--
> *wv2vAGMj9ri^RD0G
> z$V^+lU1Wjc5zaGX-3OzbwlVCn0n*)4=3zA=MU9w`Iizh$bzj^JrK(OZh!~YjoHtB{
> zz=ti)&QHzt7X(}DG&MBKIyYBOSg+UL>*^6r&P;?-
> JS(#!^BOX>H0_=m2gNNjLcVE3
> z_r<kbTa>D5fh)C>Apn26DvH(gs%93Fw~1Yy7=wj^4R=}bEiR1d(isi?^wc8E7G9}x
> zc5}Kmw4)tu!+3OthW}FbdjC5+6T`<$nL8+0vm%ac`efynH<GY>%@M(?Vk(engi!
> xb
> zn-HF`t1L*1P_i=DEFV#c+}c>m+pFC>f{=ncAJE30F}YLNAJw7pgDtl-%B;~RA4=EL
> zd()FlkEG_*)lq)r=9%=4k}0YJjhPiT3Uvru3V|@9I-LrS=G2(N<sM3)2lqI*m%oW*
> zx(ma~xh*C<n&B&ggEprDO0^20cA!w!Gn8=_7W`HMx1OtU^gxa7D-
> MX01)sG^jMSJl
> zQ@|d{bjX7f+k7^`vgO8VmXaD<|7t&xF<Z?KZ_FN5@oze&$yBJnU@-
> wizkUNb!40@v
> z3MbP@7Y3UyiPE{^khU<!R%o1uu4QFgUS|R~uub=543etI;C-
> {@Qp;~vRR3M5NkN&f
> zn4Bq=apLi-CC?k^7&cumtWZi}V<#(#YNlYY;6qt*=U=TIn1Gzhi6v%VbggRkk*0fO
> zDkQcN9egY4K-MfcLzHs|MR;r(P}ZG%(Qb3P)QYjU3|eSX*>}=&Igl#uNlE41ZJ1e5
> zLmH}&^e*O9nPIJ`MpTVUguLR*7tBm^No^$`5bRJ&jnJSvwH6mGSV*HPy8DTq
> 3t7-H
> zh>8tN<<OW`-BaR3&9x%-
> QfxWUS0yC*)io?Lpa@t?Sfou?eGHWJq^VV*f>R?+b!j`)
> z6s0ZC)1g%A#VrA$I@7XAw$<>03V=>2;d8`EM@g3=zrIo2vZ=?ev4o|Vup;R>_
> pcCU
> zaYL*oX+Ama8^$T8?IUIPIn}}A1wlW%5Xk40Te4mmN~bA_sfshwdH_<YM?;?cu
> n1%}
> zt6lve!e4!f1Hcd&nA(6q5gJ91&BANbmQ(9!y|l}{^i&E+ensF6qzanVi*{F)B@-V#
> zS<RZKMJD!!e#H_tSb|R+3}FW*V+0P=UhvGWQzO>GZMqo^mcBC~0iLGTxcoR
> PfI4bJ
> zi#Zt+D)DJhSju1%g_Nq4tQBDvwAfC`THc+Pp+nrL#pH-
> kM>=E)BNaA;HiI5BVazx~
> zRMW5{YzXLc2(7PDrPvFCeR|ejVaf3rO?&L9fdya1kf~mQie`GjnAS1Bs>-K>la3zd
> z!1r~S2c^3pRAy|FP|`5f=^fxmZ<Uf(f@<-bsR;5t5fGIbJ+B)QW=dT})t0Ip)D^K(
> zpbw1YBI}jT+CQ;AtRtd0U7d@uUh`p_8n*&Jiu&AP%i<g_aa+?WC%v*G1I%p5P
> 1$`S
> zhcd)Ks2*9|(N`0TK;}jmR`Nn2G8^?w8jzcR56nss$;I-m3PGi_0o?kC3#>C0!XwjN
> zs^``Y2~}`~#QS<O_?nAx12&N#xt(BiqNh;S`85$}AfwJ#1<-V8nk1${kl_N)k<4(A
> z*9#F{u9$a#6J;aTGoq8U*Hq)H%hB8-
> 0!hy}tzim>;jQ!G*ZEaVH7bS!pmRQRnVw2f
> z#WH;Q*7B~Wqz6U(tk2a6V6pH)&N8)<f;bzQR9HFF{1pNnNdvNn1)p+o1gzeJ6
> B%-a
> z0`*Z>^XqY9NnI+3O#o5Y^u${EuHu`3oa#%69p^u7%R$c7B2J?E(^G5=ISTIZmk1
> 1n
> zBeo{euhu>j*@5>@q&8cxx%`xMxL=*F4ajkTNouWz<0@Z!d_ZTR_^>{+voM4X
> f6<eD
> zn=Xjz3Tm;4V}(m9d74M>Dmy3a#8W=XH(K1d-o&)86K+CM6-
> <U|d3eLJ>BjW2l5J47
> zysnA{hdWWh8KOxu8R=MB=%~r2N!0(UNlQ8{l4!!L$Oy=2r0IVWk;Yf7uPTcSGH
> dcx
> zrwC~7^K5+szx{8iusa=ED`U(CSE2H*5V3+pgp|L-I+)f!o95ii-T9@vYQ<mpd`V_a
> zXz+kBG)|$nA+)kTGXO$Y&U;VE5Tqw9196AT+S8#>NkwFu^50h1<!kt>Qx-
> Qaa8eMl
> z@+Ehm%$+p(eqPq{D%i}BBBzI{hDzfv9OO#Iy6N~psUkXl54EfH%L}5eq=&|)SoC
> VC
> z7A;oQAw$GCy`v`c!C>?KLDX~tK*@<;=o-iK&_q1>AjCI-
> sF_wW)1uaQuHwj|1l18?
> zRciFrj>v4aqM}LBCgY=H#MKM2)r2)p&siS2nf$pVniiXv(o7<`zew5sL;tF&Ju0>;
> zxI~600TJnh<(CmdsmZyzQd5xa7B^XwiMa?t>FfZx<kH-ub-
> }z1*q$RA{#@s)#C9I^
> zOe!q8KCL6?E_mz#@K7-@qVLq|XV%`1^pj;Ys;-r%M(};f*C?ftkf_i6!9T6nQ3;ix
> z)P&*#hTJ;}<n!xj73=Ui(0w`ATF}%D846L0UDSRHWPH|>{xX}bR(-ggctEQq#z=0S
> z-;iWh>M2hNF$0uJWA;Zk_xE>KL#?O}M1BQE`J}|-
> O=JXH#oT2SxR}HWB*k+!S*@}P
> z`6xPqQD>RN3K=rt9k^%NbY8=WN^v#E>9A~0uLM#!9qxu&;!Ib2$o1$dgw+-
> 1oCbkq
> zD3u9-
> 3dFBQt=nX*n1Hw!cUP^&yg7@#r)o+X*ebSkX^qkW3(CO}U81VO<s>%cP>`eH
> zRZK%sNsdfkNa0zl@mNC>tyPdKD%bF?m2%6o7qW9{9)TfC5};_n;E0c8Dl|19Dj
> Gzy
> z))6N;{kM!UU==K3Tlz{PU`6!m8$GmgqIm2zRsI`Ldqs21z{<!0FBI80CauTnFi+GX
> zUfR)QxRlWp+$$L{BnCz%WwZ1ZHEqt)RW~<GXUs!fox7`gyb09i@yd>xv4$el;op
> qN
> z;Y+9xHAP6SJP=twGR8wkgHrBT{-
> ){#)M~Y8qiNH{2AoDhB8=r(Otd4X{(&EBdw#M7
> zQU@v`J#o5Hg$_{>SDuZKNS&15M4aSOOJ+V)a*h!ii=d1%Su-
> NXa`fRH#dIvhqau9~
> z4Rv4+ottZ*-
> *iiUcZ&warM+JB*quyAAba+z=|z@&Ao~EVvkBMuOsYeqB=zpFq%j@5
> zUi0h)nbw40SePx=_*7?dR)I#$l|kntblG6i5}B~g*1V-M3bjKxLUtphB<T-GJ##*N
> z#k!Q4t-6h`cX%!-t48-ali?I<?7_Vf;!b94WH6DDO3KxmgKgEu8h4ewt3o!&G``Bf
> z*uNPDGto_C@Sf&Erd&{iE=MO!>!>MzvH)0iU*`SDhdB+>v~6_9bXWPXup?tOz
> z;Fg
> z(UU<TD3b5cKiZ<bxttseP|GXh@oWnv+5M<{C4sVlhICi;^3KgzgS|G0y%rvMSItN
> x
> zwc`{&)MF(Q$=G`vbPiTVuBD`LSUJZ{!@nv8gV<B0msvbRMwfO=;7_e}YH~lBfiZ
> OC
> zDY&WZI;hl`I3JAC?Ep!GPJ$kZoF5_ablpM83Q0BKqiF}J4CU>p9#U%uK)HLrlyFCF
> zmZEO${U;V+wIk$#N=aY7AcFywQ%W_xoZ=&E61sxq`G_Ffl}Ycrdi;7BBzA4)K*4
> $+
> zBTU6TsGiKw2PiqUq6GIRI8`ZB%)t^d9x|Vs&<!YDw~OH+DRXQkhK#JPSW@pcE
> zabu
> z7NQ~clj$1N7W=&q3@fvuRM-
> Zm{maUz2z8?5WCK+#(zp;$QifOAeho6zw?_=m*r^7_
> z;M~cwQn3ZKr3pp0+WT|uPwmYRq>81!kQ_<Vw#p@MBw0xA06{?}a`ui-
> 6m7<rmgpM^
> zi84igXq4egWX*52vpz)YJodTt_-
> F)6@`}>#ObiD}?xyrvm^PL&$MZS2Y^{u2x~?q@
> zlC^}K@9@)+gD?amqNiITwtI0I3!=%Ba_C0p{L>3WIv(`X64HpWbQ>8hp*CszR!C
> _>
> zgyej>M8}n3gK+B`bA^#`wmp8^zae8y#7|OdT*%N(4hLy;SBe00cf};{n)+<pW1q;
> ;
> z3=&%e#JX}K2Z|JYQx@X`LF<B|y#r=Dz9Jo7I+rcizmgsD<?IKUagwXfX^b+F8UJ+
> s
> z=PoTUZMsN>v9cFv|ABf3BA*}Gx@Oy{?}FSe@5tDAaTTG+y~Oh9)5-
> }SG8~lqljSsV
> zT_z2SNtIZ4+cW8RBO&EFD`_KL8MdOuOb%8V9Bpyhr<_bZpt12xtlJ~g>oOysY`
> 81)
> zPS|2l6{Y9y=?*PX(_27omd*mPcbV>j4B-
> PGDeqWfEhZgzKyHUu<Xj#Vc4>TL+JH1W
> zWJXp7)XBsMC<c*Kzkicc8K88O<n!qr>uVPa7Fq0C^XV-%^W1^r&9BJJ7djx6)-
> pOn
> zGF(F3G8yS3UI6R`ClocyTWm(O?y2Rj7AzJG(Kc)A0dCV}v<}%?Ji~mt9KF#&hIGs$
> zdUDE%#6;!V4&o)lnq$Eam8Drn^@jU>Bla#o8ZPm5)aEM(Et@U_lnq!M>X95%(
> XBz`
> z06k6~NFgA@NI7a@!*eN(2hj*}428tz3H6ZtZKRX%&pRY)!5DxM0m?%Wy#bDl
> Hqq`Z
> zRdXCn%N#=zzLNZ4={$0y5thc;fMw$&bB{PWkb<{U8Bjo`@sGQii9}*B(}>4G9!k
> p6
> z8A2KPh`m{MH^N1k@Xx{}GL`x;fmAyL#UsaNM&g96YUxV<1z5(vS#uDIHv>_cC
> k`?a
> zN!mEkr}z;A5cMwsBFEuJ(v_ADdp`+rA_=VJRqNOyEYc=97|R{=kfT>(nG<R2<J_v
> 8
> zog-F93Ka`qDT{QV)fLkJMt;c8x0%@sm(1&xx)z}<c%IWSd4aH%=Sp06iC#1XiXU-
> Y
> zS8sHnHYp!;N@cH>TI2LWY*%G&PsylVGnk3%RQJNM)ywizcw{7@(l4SED1O9l*
> 2oVz
> zQfAa>g>OwE>l@YUl?Xve(Z%l1!@(UH48<a`*)^3P^0t(8nr$w9ujsnU<X$qalOn)
> O
> zwuqPP8%`vINaai?QgY6hbfm^sq+<1n@vSS^>Ld0xQscg-
> S+@`0EbFi=Zy36YKmp}P
> z{m`y~AI&C$Cq0rRx_w)h*xzU2dscO<9ey~q&B4qOV()3^0=|^Bn%@c;mYHQF5
> ~a3L
> zh+b_&+(XV0aTCEDvx29C?8%bU$TnOvZvw2P+J_Cp!K{l)qlt1R1~Ypi>Rvx7Cz5kI
> z4XzWZ+VNu>`QXA%=1*yI(IJ{B7sMka<@Z@kYL95`sT{L9hVV6`wES-
> 8{g{cwx60m4
> zKAQL;LR4HnAcR#$F4}yXYP-
> hDBnwB$xUA6uvurx`@y*?@z!DwEF%J!5tAW^7R9o?*
> z8uB*qL)mjKA4%G~m@HSz*(F!)+flxzw5%H$BEHXJd?5&ij&V2(kj(%k{pLVT?d
> @-i
> z^aHkzb~k%2<}t|Ls*V1xLpkg8dOhh^v~Ns9N#omkFjvlXjqHHPGclhoV@Oy;PC7
> PV
> zvH6kM`h_GvCr#sz2LGy5I*2M9gdb8N2#dNI*?mfM#gr!ECO;%S5c#ZFhEfC<^N
> 8-|
> zitL$sL7OEOlhdsfn#Skt`9TC;W^M5h5yk2l=T_HVaR(~3GZHB_nH77NAFrY>Y<Vv
> C
> zEuO^)KvVpxemuzBR_HyHAEIwPEkDfI`<x{&Bz8EM#8GQ(I#B{!(q9%o;hE6|<%h
> _K
> zqUKK~X2igOlpHeuQTb0O<Z#5Gm&EEQ*O?suAP%%qP^&e?3)u^?lj>nILXnDZc
> l-rE
> z)`TBY!0G&lbk-
> wjRg}K+yb}3RWa94lZ}X=4eU^y117+ECSYAaLVg)F35un@#Eml_U
> zZ842COPv(Q;AE(Py#tQeDmfob@{gMUGNg`m(c=3oFw@~%ME{EARWbyDMH
> hU<^sX&P
> z2ee)gylI5g)Sc_6mKwYO*|EsfdaU)RXQu|S`FE3(RHh9efyC#!?ZHg!$-B2f?l(>S
> zD>>&x^Gl@b8Y6Ei3K>ViGDO7kuXb<47H`&k4TnK6qar+eA(iP)$TKmRVK7@?$
> i>NY
> zF|3@Cp!rvFXcvbPGVPaS1j_ux?e|}3-
> LATVnbo!Bx2vq>RdGTAL0b!S)klr%aA>+O
> zH}9rj;%LfGl%exDm9cC7ZWERVeAcyyExy}ley*FxS_fqe79}GbE4lB~4rphi5}N-d
> z+1)aKcTIQJlUV{WA5QMSPV(F3UgO99Fn~!9zJYFNy+|(V8oOhPDc&=q$N|0w*
> +f0D
> zaWNrmqE=VLe9`PuaQHfsMfS}Dbf^ft?U|T}^w^5oVHp&~LgI7XQbS-
> 7F_>wK5h*9N
> zJz3--
> H#5vf<UP5PCFWC$03~ch5&aG+RWXZ>fIjxA+Km<|DL<)VnHl1_1CH4ZA4ww=
> z8m!x`8Op>)Z%8^y#4slf>kZU`39`IPdI3)xFexb{dyJzb|K^%j0FK%$9Be7R;+9P)
> zmNmBjmATu?7^{&3J34)?*5i;=AUX9zjHMj4aHpj`)_ayz+e9F-
> <A~Nlx0Y9l&vncA
> z1wz^Pd-P;-5W&Hhsj9Zh(KJ<#awP{@uclUbk#*!vAgg+x;Kckkx=^0hIGu-
> s%>X5x
> z)ZV@&ayUpQALVe6c4oO>GTl%{j>3uBm2G7EGi;Cj?r-
> #s{bWQ4%BD682WQrNI$PAT
> zEryv`oV+IAv5}S0>}MI?rJ*gkDF)GVQsw5+T5XH@p5^6g6Q>*a`t(d%J1j$$1Plw
> M
> z!w4k`qMx@$Qts?c=Fio4C8&=sXO^h)l@U_1fKU!V<X42Z#((D*GRs}%-
> )BiWMvh!T
> zwFJzkiz#hn**-R1c35JL<R)qb{RE(#Nr>Sq>@<i~JjjHn=CR0V*qOdtzu38nX*DIT
> z;`=O+y`WuM{<-edvgtY53295b<fm~-
> c9)FPvaJqfE^AyK1&+BG^0N?(AOi1gTOz+-
> zaeFU!-
> ao92M4r811}Il@1NF9;rt&j^#286mh?s#Sk;_x!@EoT6&&&Q6e#r(V(nsLx
> zxGma;DR*ilEiPl+2P-jcI(I_M0OgD)2e-yo#x~Z(7Rj*!Rj!$s$>n=n$nTTR<B9_*
> z-gJ!F8tX$9lr6;W!@s%K?sMH*sloS!V^CrXbmb77s+LQ!O%F5KVk<YYJp<G(l_1IK
> zQWfs5YPV=+O;OXPlj(kZt;O;x8RBqSK@4VUFp#%pE(kH_$`zvSm0Y{O<bediEn<
> {p
> zOiV6Rk_aC6+Wf*DSs#J5%O2#Y9cO#6i0pq@B<J5s!eX0`RDL^}*a*4JIotb1dhd
> KM
> z1-YRCU0^JiVmzZk2l|{yJBXCzd$}jp2c6fP+QXGrS-X5EQhKH|S4x_5_R&(gaTFaY
> z>I@~S1tllxnybwn=-
> ?$}a+2%X{0n!fjK{e$d^v>F?O24`+m?7s>$<*+(MdTtWuB1q
> z%j4`I)-
> 2~7*Ru##R+(S6#PvwUWdHEQW|f)YU>YET(tIru0)bD4#84oESAQW>AIa88
> zYDp0_=c&xnkh3{Le3#L|l7sj4z5(j`*0p+~0!B#56(5D9<`yT6+A`jaP}aPcZbnD$
> zj6}Cz7HQTTxZJ8rd~YI=A2=ubDrHxKS5KW2C&{98Hd2y*pCvJuS8)$Y23QfwYD?
> !)
> z1_i-uuCSHQ*eAy1{wi|ou&$6FI@2p<a=-
> X=h41bsG7f>16yImr^>f|CJ!*lU%2z1J
> zOt&;2WS&Yd73c017<3`vG>J(136xhYkUl~Yt80sIqpQuJkY{{8-5ktpWz%K)I*d)L
> z)~ZjVFtsALcBYA02tq04c{J$CpXYl`RTv!QBpaNM&Ie+BSvnL!HAie7f=aFVbWUya
> z1Jcy$ZfcRLf~YIGU*(!<OPPBl(?nzv>UtH&i)#Bj5;EI_@t)5+XLs|(ayh>jskSlz
> ziu{1@v#^MVNp1PLZebb$3jf$-BmV09(=>1?-
> N1r2K`mAl>!e{&D|%c`rq$%`M#QOW
> z#CPw9z3Vb%YQcIJ>Q_xk`Gvclu|8d_N4AoK+uL+$A*gqy(yQqFcp~G4dbdsK{?
> QSk
> zoX&l!?S<*=QXyQ?p0RU&E|?}qPAEi6rWvwxu~ZL>5F^moqvT8!+w-
> O)H4<C@BVE=x
> zch{j>xmE0X9)(|f*-
> @D_V!Yo&z8_4^KJ@{cX&UqCOTMHdHL1;}c+JmsivVR^E7W`?
> zUGuFLIIw8}*_p)0fS^X1rM=FhC!Jmh<?u8LORORgQA4$#7k2GAXIdsFMX?NDG
> SQXu
> zbWoxoX1R_TxW5)cqX&)b$#nXHdK(?Fs(;PnJ+98apgGOdm7|w}<WSTjyyp}7!2
> `Kn
> zjro0+DW6vAT2s87+SXvE%}03kYHYfDgxtD&O=grpwgs)%9BW6oOlne+G^#vaG
> C#5>
> z)oWkZi=C;1g0FRq5R~}l8f*wAn=U=5R1UAO#}^`;WMC=%CoXu(A*XX6Y8WY^J
> +3yn
> zQ~P=qM<B|*Bnb}&s)x8`d@zR_2dJbk)i6*p7k1yW>HKruH5*<>^JzAxC++o`?e
> D8*
> z1*p1G-;T1>jY{IBLNpNGFpdA3=<a({&GP`Mb)P*|L_r6NQL@$Ny2ZRIN(h+-
> x7w0v
> z*`%W~HNGJ6S(w3;_0c?_sy1CJ3W)rw7i`v6y?2b0RIaf{645ReDkb|1VF`B#cQu
> pq
> zX;_GnC+Wz^2rMGCBWtF$UmA6w<hrOeQ&&TTPY!7rLsim&oW&@G3a8Nc7
> Q^%~7b+YL
> z*z-
> @G`+C&Z5wVrzW3O1MML3vk&=UwHrb~FcWRee}N22+uw8gA1soZd48E7>!ld
> >Q+
> zsP9>?qB~4s9Ohh!BhrWs<jQ(v925%{BKEGwZBU3$@yh4~f+4$9l(mK5^i(?uRG
> aGM
> zD$Cfl!4DC8UeE=(v?e)-Uy~Fq^{rwWS*Ab^aV}SYA$8V7T4^0B#0o{p3O-
> k~#quhn
> z!>{RZf>vopGwJ@osY*$uo6D<EVKJi6<9W6eY$qcyHC$XXmPa55I5YQuS=DW@
> Wx1<7
> zd8X!b-
> OL=N#(a9gqrqj%%oKUHS)o!UYZ}kUu3Z0$e{}FFR3&}&oCHj@MmNTkCCYpK
> z+WR9h>QVTX16AD662@!-5`%|>4Tou6%y?3Y18VKy0qTz^Bo%t%-
> l+PhDTz#RwB>RI
> zs<3n=2j29qLPf_Rz$BQ)!@tte4iw#D#}%^7j0gu?8(y!Mw_@a+of$!6?rWrS?i)sz
> z#06Kzg)C60Xy8wJ!qBXV!b)U3WrIg3K)1iNGSmzDogW3t_&&=ry6V2TwHts42g
> ?N+
> zPNC$}t3ia-J-
> aO@0HV5qGxk+2mC?Ii(&(+4O{yO{q)K6toF$b2e4MW=c4eX%G`C<=
> zor)i7mvk6kL>h+TC(@e-xGOf|x56)2Xm)dP+J`*}PtGpy=5izl1pq&4u66Ds*Pe3S
> z;9AGps}`yVGTly8&Pufj@>G!9o@65_qtITme9nZE%2bZ^T$i)DKMx068#p*}FK3
> hc
> zyZh-
> }1}X3%90mI>km~>ZV`J%1u#`?TNvu_(C0W>+WU7bJrxMg|*Xfx^B*yk`{vNOl
> zLGd2xQ8B~8lejh+rW~x%J|eK;-
> ~oJ@C=Jq0tcM<*Hmw)X3X4wOXuHYeeK!v9x8#Ct
> zq{NB}DKB1KiE%nhttkt2WKIXb=HcMXnl9PEjCH~DXLU4yrR}QEr1C&~iEH_*5+>;
> K
> z|E`Jxh#l@rC_Ddlb(9YFzi$%>$Y?+{zok90!lpkFssc#OZMyBtHgjY#sw#jJ{bdFo
> zEl_dN!p1eg>`QgApm9UFcLt<DQqO_nwbMDBFE5EuOycH&O+b5**g2nYif@_
> WU=oCY
> ztPVM?SE5n-
> %je^bwGL!$EMTHmlQyX<V6TdF(x|1}83J_40k^RQ{Vk_4feJI)AtGt@
> zS?_M)x_`d7C2==i&N2{udDXTI5$woRV0X>G`k<!OX`F>4>#o#-
> FuEgVqE{0iWQVnY
> zhqZ6<W?No0B86NnNY%RKQ|Q%WJTWs8dG^9q3@MgOx?mz!&8c(oP?0$qY
> Gdfag<R9a
> z$Cg?^ng-
> 4i_J(V1p1|Hx@!aq}JkEMuHSl0>nV;*PkXQ#UcN0;(T2%$Za_a6tMMfBa
> z4yl1(${xf7Q-)}Dq0%i_{-hqPiP@hD&ekWXG5IRKn6@=c{eqRfAo{2oFEp8=;*Bcc
> zwC3WGs!#9ozM%0<RJfEaVpoI91MLY3h{)L&q(EK7+rYc+E!94#CLgi4&Ch=t3{iG
> U
> zYpXR+bykxDWc4RQAzr9Op*-xSQY0Z*z{EX5+UhKoiyE-~$H-!lLq|vF6&)4=-
> exwc
> z;K<@!w%hmurO+Nqe)v$*q?qzS$XZ*_t}?_0!{?C+XRDj3N|=Dw%Z$XWAl4Snl
> +HlT
> zi!n}S?L0sklHc^Dr7{8l1r5U+3x5kfOKIY)XE*6iC+e$`fMjcz)U40lRO23O`*yax
> z9=LeY6PvX-GD|(4b}x**AY4)Sli!_6;Yh4}Nw$I$N=Sdc&B`X7I>FvDzSAo<&=JjV
> zb19cwyLPu4m$!i~%P1`l)#;v^^)But{TyD!{ASqI0RST!DV7N7R`Ny863=k0c4R5o
> z;vMxEyUTvVbn^=Z)4B=T8noNrHtlt;v%9k1@akU7cjWWC(ZJw_nVTn;>nibBwV
> Gnp
> z-
> %e&0glC<*9;1>1+tUV1c2v|1pt9u>+risd+O+9QYaH3>4==9oCbRisv6#>9Z?Dcz
> zd(v*W>a55cANeQR+_!Wel}pG2{9R)y4Bw@2BSBb!j`ARY9V;=?VsGqyp}QPZIah
> 0x
> zTs>*0H#i**&xXUnNiWlS$`vx#Vu`r4YG&K9bVrR)dC<#nv%$$SyG;wqnM-
> 2w>zanQ
> z0NAF8`MK_?&5#!GOoht^(w1l1!rAq8tLZkL&6=GX6J<-
> Se_J#JLLAnb8E&y!!P&Bq
> znZ2+pLpnyX&|2<>qDF3oke~V%7;`Et<JZ~~a=kKgW9q9YpV;i6du^5_5BzI=u6w
> ;3
> zL%J3_a^bDZ1^%07p-
> F>vq?PBy%Kb>4RTrDD5^(jWoeMR`g_?X*kgXnI`zKa#e?7B|
> z`UaRiJuL)nkS?c={Lu{)H&meogim9o*5>u=;%eJ1);i_{=^+OE8ybj@_2dC|g~qgY
> z18UkAJ1Mxn$+D~QEuFHuRWL{{P=hfB3-
> M%fMWM&ycDpfyJw2M!k7O7WIMglkbKS6f
> zM31~1YD}%cB~VMGQ>J?EeygcfHE#kvhj~0YUD0u5dYZCg4J}F16Dz_F0b>zMY
> J#!X
> zGc!no^YyKpkYw_EfWBX<Z(R@6%)Ll4-qaA4^9WNz3{9OL=TPA(W{tI|;i_*-
> %Ry2j
> z=#~%FK+9vWDcvhVw*?%sR$>u%rq_e4TRT@ClumkF)8!ygNUmb=ZGmi~miY
> %XAtbzu
> zKOzJt8g}4IH9PGQX}e{{&{!@95Q-`5xsa8hL&|c0rHu{K`Rrn5-Y`+FHO2C}HlLuX
> z6%4sOD>^@9f<#qa-
> H8?Z!A2B|7Ne<?Te}U#Oh)tc`U9G&UWXjNueL}AEX5dHd&Q0+
> z>wJFMYy!F$Go?@ct8zk`<8=5dGr<8-Sxq)LTK#L4uIZZq>lg%{nf?T|oNp0tSeJ4`
> z6GW1vSHmmj#@i05)$Cg2>Bkz<{^iuz+|#|c>mWZu-
> }cPfFT<fytR@$=hCMyKu`{dT
> z)fp!eL?E=bTJI8_Q_I)XlDf1;{{mL4`R&Dt4r!(Rv)fr6Hy}}WD_?V4+MDIAe0s-_
> zb+MdYpBXI4PDb~&+<?hBX*~4UL27;zF?Cbt#=%@USB+-
> 0!?y;Tb9;Gq(hVWeH0$<<
> zqnoKuS_@_P&vUQ?^LvbFTtF<JPjIn8Cv>bd>kZDX?q;^#z;}w7ib?AERxy@Sgs;1
> y
> zv#nH+Dm%Ab4Bwt&HJ`$q!R6&>ba{1iKbhAz1YT%kL+eo8=YChMvhdi4HZ13py
> Blo7
> z<>mG5{d7?)-B7-
> mO6jn^2F_z0TcB>t6Uj+}?5ts$IkYHWt@6CafXAk99jVx&A<acQ
> z)|!)u7@p;>4Yo@dOBVOic0l-A&-
> wCLU^8y)srA9K30dQbh0~$Ape`cW@@)2`jxK8^
> zY#wPvHCrMci{)~$AyCH{a^@pm`xaM5P`XfQ1}C@m3OFL$e3r9?F<W4Gn4+)
> @Xj9*B
> z#vh+9Z}hn9M6E=J0rMVCi=kTiiV37g?@G($X7p)^l}hzH44vCU8SE|Pi%ah7VBO
> Y4
> z(Y$TKzJ<J=gNJ^gBA_sfu}}9Z=354HEKK*k*S!&$B(%S5KF_V06KimjU+smdwE?G
> g
> zgdpm?(O%cKDWC4sWA<tteL1ZS8q{JQAFM=bj{|J2N93s?wEmXoYT6f&Frpd|c-
> T!u
> ziY5O_c}uj8QS9VyM?+Yct5nP{S?!(6X?_!#tzrwL>F*>WhR1#kQn!PdHjbvEG>Eg
> 6
> za&cUBIx7Ui7Nd5UG?cPdOsvfXtY_O>k;TDR=r**Z#iOn{fh_3HFQG@7fUP~|*N
> yv3
> zm|*nHp<L60_?QgY)~+u%#DO&~N57Ny&1rSc0&-
> Q%YU02qI}S3}mKsA$V2IT#(%waT
> zM}Bc>r(PbN=FJskC)cgr_hNEx<?=!Wa<f{;!UIk2=zK+l&cEGIwlV9Sx3Y>kM6-4H
> zw}kS%zn%W5Rj*p!4(paHTDzry@i<V6jSX~=AvXB5dkPaAu0PcM$!Ax?7t0Oo3
> y|4f
> zJKYo-
> wVK#@?yf6Ydzq`?_#U0kPHI`!4dXif)4Hv2U@CNSb=I$u@;y*I@T+O}<m`G<
> z6OYD42dBN-
> u!rgB?((s)+BT)uun@ero7#M<PVe;m@)jcOc{wa8^5uMb2MPQAj+n8j
> zt@e2zq%dIviwz*cUbdkqR<P9%%<2r9q`PKPNbF?3U)$2583E1jPa9NXr+0EXJc
> p@|
> z>+9>Q%hCDS=}GSc;YCTUw9_A)o?VQt$~Fv7s~NVkjQH)^(R(>jA>P{d(sr`!9R@k
> <
> zG|f7lEUQ~N!3)38t2A?MXp!p&{<7(vEo<E3og190wYuK0Ev{;H*3NZ(xG!d>#tub
> 5
> zsDrsyku<3hdq<Y!cf(rC7T^B=<E&c~aLKP4)cUTZN$aLLU|{!QSm<3_-txV)Uqd1J
> zz2lbfHWf>4)d(UoIn#47o1p#OJ@1^^`QebEeFW)1^3_TR?9hGkK^yG-
> J4aSy$f36$
> ziygp_`taxKx_0sD{*8U{5Ympd4AOZ#Ir#$j;oD(5*REpVNDGJX@F=|ih%jC*hrNy
> z
> z<j)bM!!`WO*dMp7KEES-IlllhJrN2u(F;eFV=vrJlA+p?u4D(~=jGGO|KElqo%34R
> zfS7B;zVip_E$Kj~&qt1|^X25yNTfbc<u46PI=GsZ(JexR@^o?NQMuKA2njSMlN7
> 7P
> z^ycE^1B+ByE!}Vr6Wtrq!(r*c4y&g()M-Ah37M6>0)F%5Vs>{kIv);TC;D!gA8rEs
> zFmI-P*!ySRoKvH-d5_iBY&apruQ@I9)nYN5&8E}I-AJw(Iu>R}hnse~C&P;?48zyC
> zRGuEIYmw=EOw`hW@gdS0zQAo<Z1jPLR62tTSaEQ5eS0^Vl3AVFHZMj`JLd*#0
> Bdov
> z9*EC09<#F?1NQ07bcxF*ie{lGTV71mx}0NRMPa6=w`QcjL`nXx)KV1+?PZ^DoBz
> JN
> zc|u)Pk*+(6d)Q0r8`o+Xa0Te4pXiSk7|n~fis>_~gLE_;)GsrQ=v8MQtbp{kQO(8T
> zw%v{h$LNLdxv`oYjEW2K<RBX-
> AEOl;U}opB4I9rkE?nPG*}jiE=aUVNU)2P@clN#&
> zKi&K0*ITPru@lHFYu*as39#;5wB!i;?9~$>cBm@UX8;)s$VIWZc@g8R>}=8y#Hk
> SG
> zn`a-2TE~aeYv)H6>f@2eN3E`gba1;_YduA9tq#F`?ziK|>REi;`gV0Lrj237_3GI*
> zYd!LfPr5CFLoYC=BhC7a1CmyoV>c4!nI2}NO6A%o`Q6#ejAmz@{`pPKUP^~p8u
> UyI
> zX;fH{=>C#3k~7#|`{H`C5GxMaeAMxosJ*$`^sFXoRV?l<26bydHp6|Y62Oy_!TIP
> 4
> zwqJ2O(J!Xg#`iLw3Y!DelNp=!uI6`Far>eJRB~hxu)$Kd-#<ASz|sHE)8(?^UDz%F
> zXLVrB!PUiwm#lwehCeO%9!x@A!K#T1ST+HZo_~i^o=;29{cD3o2Os#diT!Et3gM
> Lk
> TuM~Ktz$*n_Dey{xHWc`O(cS1K
>
> literal 0
> HcmV?d00001
>
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.id
> f
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.i
> df
> new file mode 100644
> index 0000000000..1f79332020
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.i
> df
> @@ -0,0 +1,10 @@
> +// /** @file
> +// Platform Logo image definition file.
> +//
> +// Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +#image IMG_LOGO Logo.bmp
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.in
> f
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.i
> nf
> new file mode 100644
> index 0000000000..3380f3c1d5
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.i
> nf
> @@ -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. <BR>
> +#
> +# 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.u
> ni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.u
> ni
> new file mode 100644
> index 0000000000..9d1bbaffa9
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.u
> ni
> @@ -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.<BR>
> +//
> +// 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/LogoD
> xe.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.inf
> new file mode 100644
> index 0000000000..01102b138f
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.inf
> @@ -0,0 +1,55 @@
> +## @file
> +# The default logo bitmap picture shown on setup screen.
> +#
> +# Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved. <BR>
> +#
> +# 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/LogoD
> xe.uni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.uni
> new file mode 100644
> index 0000000000..9635701b60
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.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.<BR>
> +//
> +// 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/LogoD
> xeExtra.uni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xeExtra.uni
> new file mode 100644
> index 0000000000..c6ea34b81d
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xeExtra.uni
> @@ -0,0 +1,14 @@
> +// /** @file
> +// Logo Localized Strings and Content
> +//
> +// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +//
> +// 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/LogoEx
> tra.uni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoEx
> tra.uni
> new file mode 100644
> index 0000000000..041179fb75
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoEx
> tra.uni
> @@ -0,0 +1,14 @@
> +// /** @file
> +// Logo Localized Strings and Content
> +//
> +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
> +//
> +// 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/BasePciLibCf
> 8/DxePciLibX58Ich10.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf
> 8/DxePciLibX58Ich10.inf
> new file mode 100644
> index 0000000000..e5ca95e20e
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf
> 8/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. <BR>
> +#
> +# 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/AcpiTa
> bles/AcpiPlatform.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.h
> new file mode 100644
> index 0000000000..2deb2a88eb
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.h
> @@ -0,0 +1,45 @@
> +/** @file
> + This is an implementation of the ACPI platform driver.
> +
> + Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _ACPI_PLATFORM_H_
> +#define _ACPI_PLATFORM_H_
> +
> +//
> +// Statements that include other header files
> +//
> +
> +#include <Base.h>
> +#include <Uefi.h>
> +#include <IndustryStandard/Pci30.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/HighPrecisionEventTimerTable.h>
> +#include
> <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
> +#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
> +#include <Register/Hpet.h>
> +#include <Guid/EventGroup.h>
> +#include <Guid/GlobalVariable.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/BoardAcpiTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/AslUpdateLib.h>
> +#include <Library/PciSegmentInfoLib.h>
> +
> +#include <Protocol/AcpiTable.h>
> +#include <Protocol/MpService.h>
> +#include <Protocol/PciIo.h>
> +
> +#include <Register/Cpuid.h>
> +
> +#endif
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.inf
> new file mode 100644
> index 0000000000..b4b52b6622
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.inf
> @@ -0,0 +1,105 @@
> +## @file
> +# Component information file for AcpiPlatform module
> +#
> +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +#
> +# 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/Qe
> mu.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qe
> mu.h
> new file mode 100644
> index 0000000000..f6ef44a14f
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qe
> mu.h
> @@ -0,0 +1,507 @@
> +/** @file
> + QEMU Video Controller Driver
> +
> + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// QEMU Video Controller Driver
> +//
> +
> +#ifndef _QEMU_H_
> +#define _QEMU_H_
> +
> +
> +#include <Uefi.h>
> +#include <Protocol/GraphicsOutput.h>
> +#include <Protocol/PciIo.h>
> +#include <Protocol/DriverSupportedEfiVersion.h>
> +#include <Protocol/DevicePath.h>
> +
> +#include <Library/DebugLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/UefiLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/FrameBufferBltLib.h>
> +
> +#include <IndustryStandard/Pci.h>
> +#include <IndustryStandard/Acpi.h>
> +
> +#include <Library/S3BootScriptLib.h>
> +
> +//
> +// 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/Qe
> muVideoDxe.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qe
> muVideoDxe.inf
> new file mode 100644
> index 0000000000..8370559016
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qe
> muVideoDxe.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. <BR>
> +#
> +# 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/Vb
> eShim.asm
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.asm
> new file mode 100644
> index 0000000000..cb2a60d827
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.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.<BR>
> +;
> +; 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/Vb
> eShim.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.h
> new file mode 100644
> index 0000000000..cc9b6e14cd
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.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/Vb
> eShim.sh
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.sh
> new file mode 100644
> index 0000000000..7669f8a219
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.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.<BR>
> +#
> +# 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/8259Interru
> ptControllerDxe/8259.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.h
> new file mode 100644
> index 0000000000..a9673f9c87
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.h
> @@ -0,0 +1,218 @@
> +/** @file
> + Driver implementing the Tiano Legacy 8259 Protocol
> +
> +Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _8259_H__
> +#define _8259_H__
> +
> +#include <Protocol/Legacy8259.h>
> +#include <Protocol/PciIo.h>
> +
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/PcdLib.h>
> +
> +#include <IndustryStandard/Pci.h>
> +
> +// 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/8259Interru
> ptControllerDxe/8259.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.inf
> new file mode 100644
> index 0000000000..e66b21c914
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/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.<BR>
> +# 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/8259Interru
> ptControllerDxe/Legacy8259.uni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/Legacy8259.uni
> new file mode 100644
> index 0000000000..d035292419
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/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.<BR>
> +//
> +// 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/8259Interru
> ptControllerDxe/Legacy8259Extra.uni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/Legacy8259Extra.uni
> new file mode 100644
> index 0000000000..ee43f6923c
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/Legacy8259Extra.uni
> @@ -0,0 +1,14 @@
> +// /** @file
> +// Legacy8259 Localized Strings and Content
> +//
> +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
> +//
> +// 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
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#46315): https://edk2.groups.io/g/devel/message/46315
Mute This Topic: https://groups.io/mt/32816099/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
Thanks David. No more comments for this patch.
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 23, 2019 10:10 AM
> To: Kubacki, Michael A <michael.a.kubacki@intel.com>;
> devel@edk2.groups.io
> Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince
> <prince.agyeman@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: RE: [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides
> modules for SIMICS QSP Platform
>
> Hi Mike,
> Please see the updates online below. Please let me know if you have any
> more comments.
>
> Thanks
> David
>
> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Monday, August 19, 2019 6:05 PM
> To: Wei, David Y <david.y.wei@intel.com>; devel@edk2.groups.io
> Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince
> <prince.agyeman@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: RE: [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides
> modules for SIMICS QSP Platform
>
> Agree with Nate's feedback on moving the noted items out of the
> "Overrides" directory.
> Ydwei: done
> Please do submit a patch for style fixes in MinPlatformPkg/Acpi/AcpiTables
> directly.
>
> > -----Original Message-----
> > From: Wei, David Y
> > Sent: Friday, August 9, 2019 3:47 PM
> > To: devel@edk2.groups.io
> > Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming
> <liming.gao@intel.com>;
> > Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince
> > <prince.agyeman@intel.com>; Kubacki, Michael A
> > <michael.a.kubacki@intel.com>; Desimone, Nathaniel L
> > <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> > <michael.d.kinney@intel.com>
> > Subject: [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides
> > modules for SIMICS QSP Platform
> >
> > 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 <hao.a.wu@intel.com>
> > Cc: Liming Gao <liming.gao@intel.com>
> > Cc: Ankit Sinha <ankit.sinha@intel.com>
> > Cc: Agyeman Prince <prince.agyeman@intel.com>
> > Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
> > Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > Contributed-under: TianoCore Contribution Agreement 1.0
> >
> > Signed-off-by: David Wei <david.y.wei@intel.com>
> > ---
> > .../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/Pci
> Hos
> > tBridgeLib/PciHostBridgeLib.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Plat
> for
> > mBootManagerLib/BdsPlatform.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Plat
> for
> > mBootManagerLib/PlatformData.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.
> c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibC
> f8/
> > PciLib.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiT
> abl
> > es/AcpiPlatform.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiT
> abl
> > es/Facs/Facs.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiT
> abl
> > es/Fadt/Fadt.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiT
> abl
> > es/Hpet/Hpet.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiT
> abl
> > es/Wsmt/Wsmt.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/C
> om
> > ponentName.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dr
> iv
> > er.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dr
> iv
> > erSupportedEfiVersion.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/G
> op.
> > c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Ini
> tia
> > lize.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/V
> beS
> > him.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> pt
> > ControllerDxe/8259.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Pci
> Hos
> > tBridgeLib/PciHostBridge.h
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Pci
> Hos
> > tBridgeLib/PciHostBridgeLib.inf
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Plat
> for
> > mBootManagerLib/BdsPlatform.h
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Plat
> for
> > mBootManagerLib/PlatformBootManagerLib.inf
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.
> bm
> > p
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.i
> df
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.i
> nf
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.
> uni
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.
> > inf
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.
> > uni
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe
> > Extra.uni
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoE
> xtr
> > a.uni
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibC
> f8/
> > DxePciLibX58Ich10.inf
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiT
> abl
> > es/AcpiPlatform.h
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiT
> abl
> > es/AcpiPlatform.inf
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Q
> em
> > u.h
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Q
> em
> > uVideoDxe.inf
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/V
> beS
> > him.asm
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/V
> beS
> > him.h
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/V
> beS
> > him.sh
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> pt
> > ControllerDxe/8259.h
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> pt
> > ControllerDxe/8259.inf
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> pt
> > ControllerDxe/Legacy8259.uni
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> pt
> > ControllerDxe/Legacy8259Extra.uni
> >
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/P
> ciH
> > ostBridgeLib/PciHostBridgeLib.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/P
> ciH
> > ostBridgeLib/PciHostBridgeLib.c
> > new file mode 100644
> > index 0000000000..2aaa4b3e90
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/P
> ciH
> > ostBridgeLib/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.<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +#include <PiDxe.h>
> > +
> > +#include <IndustryStandard/Pci.h>
> > +#include <IndustryStandard/X58Ich10.h>
> > +
> > +#include <Protocol/PciHostBridgeResourceAllocation.h>
> > +#include <Protocol/PciRootBridgeIo.h>
> > +
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/DevicePathLib.h>
> > +#include <Library/MemoryAllocationLib.h>
> > +#include <Library/PciHostBridgeLib.h>
> > +#include <Library/PciLib.h>
> > +#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_PREFETCHABL
> E
> > + ) != 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/Pl
> atf
> > ormBootManagerLib/BdsPlatform.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Pl
> atf
> > ormBootManagerLib/BdsPlatform.c
> > new file mode 100644
> > index 0000000000..0b66862e46
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Pl
> atf
> > ormBootManagerLib/BdsPlatform.c
> > @@ -0,0 +1,1553 @@
> > +/** @file
> > + Platform BDS customizations.
> > +
> > + Copyright (c) 2004 - 2018 Intel Corporation. All rights reserved. <BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +#include "BdsPlatform.h"
> > +#include <Guid/RootBridgesConnectedEventGroup.h>
> > +#include <Protocol/FirmwareVolume2.h>
> > +
> > +#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"<unavailable>" : 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"<failed to convert>";
> > + 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/Pl
> atf
> > ormBootManagerLib/PlatformData.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Pl
> atf
> > ormBootManagerLib/PlatformData.c
> > new file mode 100644
> > index 0000000000..5f1b16dd56
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Pl
> atf
> > ormBootManagerLib/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. <BR>
> > +
> > + 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/Log
> o.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> o.c
> > new file mode 100644
> > index 0000000000..d4a75ad140
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> o.c
> > @@ -0,0 +1,154 @@
> > +/** @file
> > + Logo DXE Driver, install Edkii Platform Logo protocol.
> > +
> > + Copyright (c) 2016 - 2017 Intel Corporation. All rights reserved. <BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +#include <Uefi.h>
> > +#include <Protocol/HiiDatabase.h>
> > +#include <Protocol/GraphicsOutput.h>
> > +#include <Protocol/HiiImageEx.h>
> > +#include <Protocol/PlatformLogo.h>
> > +#include <Protocol/HiiPackageList.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/DebugLib.h>
> > +
> > +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/BasePciLi
> bCf
> > 8/PciLib.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLi
> bCf
> > 8/PciLib.c
> > new file mode 100644
> > index 0000000000..7544117a03
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLi
> bCf
> > 8/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. <BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +#include <Base.h>
> > +
> > +#include <IndustryStandard/X58Ich10.h>
> > +
> > +#include <Library/PciLib.h>
> > +#include <Library/PciCf8Lib.h>
> > +#include <Library/PciExpressLib.h>
> > +#include <Library/PcdLib.h>
> > +
> > +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/Acpi
> Ta
> > bles/AcpiPlatform.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/AcpiPlatform.c
> > new file mode 100644
> > index 0000000000..b1d7552792
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/AcpiPlatform.c
> > @@ -0,0 +1,1579 @@
> > +/** @file
> > + ACPI Platform Driver
> > +
> > + Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> > +
> > + 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; Index<MAX_CPU_NUM; Index++) {
> > + DEBUG ((EFI_D_ERROR, " %02d 0x%02X 0x%02X %d 0x%02X
> > %d\n",
> > + Index, mCpuApicIdOrderTable[Index].AcpiProcessorId,
> > + mCpuApicIdOrderTable[Index].ApicId,
> > + mCpuApicIdOrderTable[Index].Flags,
> > + mCpuApicIdOrderTable[Index].SwProcApicId,
> > + mCpuApicIdOrderTable[Index].SocketNum));
> > + }
> > +}
> > +
> > +EFI_STATUS
> > +AppendCpuMapTableEntry (
> > + IN VOID *ApicPtr,
> > + IN UINT32 LocalApicCounter
> > + )
> > +{
> > + EFI_STATUS Status;
> > + EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE *LocalApicPtr;
> > + EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE
> *LocalX2ApicPtr;
> > + UINT8 Type;
> > +
> > + Status = EFI_SUCCESS;
> > + Type = ((ACPI_APIC_STRUCTURE_PTR *)ApicPtr)-
> >AcpiApicCommon.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_HE
> A
> > DER *McfgTable;
> > +
> >
> EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_
> AD
> > DRESS_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_TAB
> LE
> > _HEADER) +
> > +
> >
> sizeof(EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_
> BA
> > SE_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_
> B
> > ASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
> > +
> >
> EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_RE
> VIS
> > ION,
> > + 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_H
> EA
> > DER) +
> > + sizeof
> >
> (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_
> A
> > DDRESS_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_
> B
> > ASE_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/Acpi
> Ta
> > bles/Facs/Facs.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/Facs/Facs.c
> > new file mode 100644
> > index 0000000000..a16c13466a
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/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. <BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +//
> > +// Statements that include other files
> > +//
> > +
> > +#include <IndustryStandard/Acpi.h>
> > +
> > +//
> > +// 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/Acpi
> Ta
> > bles/Fadt/Fadt.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/Fadt/Fadt.c
> > new file mode 100644
> > index 0000000000..8aa10a4a5b
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/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. <BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +//
> > +// Statements that include other files
> > +//
> > +#include <IndustryStandard/Acpi.h>
> > +
> > +//
> > +// 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/Acpi
> Ta
> > bles/Hpet/Hpet.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/Hpet/Hpet.c
> > new file mode 100644
> > index 0000000000..aa386ba149
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/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. <BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +//
> > +// Statements that include other files
> > +//
> > +
> > +#include <IndustryStandard/Acpi.h>
> > +#include <IndustryStandard/HighPrecisionEventTimerTable.h>
> > +
> > +//
> > +// 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/Acpi
> Ta
> > bles/Wsmt/Wsmt.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/Wsmt/Wsmt.c
> > new file mode 100644
> > index 0000000000..12e2feacb4
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/Wsmt/Wsmt.c
> > @@ -0,0 +1,46 @@
> > +/** @file
> > + ACPI WSMT table
> > +
> > + Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +//
> > +// Statements that include other files
> > +//
> > +
> > +#include <IndustryStandard/Acpi.h>
> > +#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
> > +#include <Library/PcdLib.h>
> > +
> > +//
> > +// 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/
> Co
> > mponentName.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Co
> > mponentName.c
> > new file mode 100644
> > index 0000000000..dd9cc80e42
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Co
> > mponentName.c
> > @@ -0,0 +1,205 @@
> > +/** @file
> > + Component name for the QEMU video controller.
> > +
> > + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved. <BR>
> > +
> > + 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/
> Dri
> > ver.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Dri
> > ver.c
> > new file mode 100644
> > index 0000000000..e49e7a465c
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Dri
> > ver.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. <BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +#include "Qemu.h"
> > +#include <IndustryStandard/Acpi.h>
> > +
> > +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/
> Dri
> > verSupportedEfiVersion.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Dri
> > verSupportedEfiVersion.c
> > new file mode 100644
> > index 0000000000..c2d82e7324
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Dri
> > verSupportedEfiVersion.c
> > @@ -0,0 +1,15 @@
> > +/** @file
> > + Driver supported version protocol for the QEMU video driver.
> > +
> > + Copyright (c) 2007 - 2010 Intel Corporation. All rights reserved. <BR>
> > +
> > + 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/
> Go
> > p.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Go
> > p.c
> > new file mode 100644
> > index 0000000000..19ff5209d2
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Go
> > p.c
> > @@ -0,0 +1,417 @@
> > +/** @file
> > + Graphics Output Protocol functions for the QEMU video controller.
> > +
> > + Copyright (c) 2007 - 2018 Intel Corporation. All rights reserved. <BR>
> > +
> > + 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/
> Ini
> > tialize.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Ini
> > tialize.c
> > new file mode 100644
> > index 0000000000..fbf40e9eaf
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Ini
> > tialize.c
> > @@ -0,0 +1,341 @@
> > +/** @file
> > + Graphics Output Protocol functions for the QEMU video controller.
> > +
> > + Copyright (c) 2007 - 2010 Intel Corporation. All rights reserved. <BR>
> > +
> > + 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/
> Vb
> > eShim.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Vb
> > eShim.c
> > new file mode 100644
> > index 0000000000..aa4648f813
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Vb
> > eShim.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:
> > + <http://www.cs.cmu.edu/~ralf/files.html>
> > + <http://www.ctyme.com/rbrown.htm>
> > +
> > + Copyright (C) 2014, Red Hat, Inc.
> > + Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +#include <IndustryStandard/LegacyVgaBios.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/PciLib.h>
> > +#include <Library/PrintLib.h>
> > +#include <SimicsPlatforms.h>
> > +
> > +#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/8259Interr
> u
> > ptControllerDxe/8259.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Inter
> ru
> > ptControllerDxe/8259.c
> > new file mode 100644
> > index 0000000000..b57bacdda4
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Inter
> ru
> > ptControllerDxe/8259.c
> > @@ -0,0 +1,622 @@
> > +/** @file
> > + This contains the installation function for the driver.
> > +
> > + Copyright (c) 2005 - 2018 Intel Corporation. All rights reserved. <BR>
> > +
> > + 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/P
> ciH
> > ostBridgeLib/PciHostBridge.h
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/P
> ciH
> > ostBridgeLib/PciHostBridge.h
> > new file mode 100644
> > index 0000000000..3bf31067fa
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/P
> ciH
> > ostBridgeLib/PciHostBridge.h
> > @@ -0,0 +1,68 @@
> > +/** @file
> > + Header file of OVMF instance of PciHostBridgeLib.
> > +
> > + Copyright (c) 2016 Intel Corporation. All rights reserved. <BR>
> > +
> > + 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/P
> ciH
> > ostBridgeLib/PciHostBridgeLib.inf
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/P
> ciH
> > ostBridgeLib/PciHostBridgeLib.inf
> > new file mode 100644
> > index 0000000000..8c6de3dca6
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/P
> ciH
> > ostBridgeLib/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. <BR>
> > +#
> > +# 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/Pl
> atf
> > ormBootManagerLib/BdsPlatform.h
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Pl
> atf
> > ormBootManagerLib/BdsPlatform.h
> > new file mode 100644
> > index 0000000000..1fb031b752
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Pl
> atf
> > ormBootManagerLib/BdsPlatform.h
> > @@ -0,0 +1,156 @@
> > +/** @file
> > + Platform BDS customizations include file.
> > +
> > + Copyright (c) 2006 - 2017 Intel Corporation. All rights reserved. <BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +#ifndef _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
> > +#define _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
> > +
> > +
> > +#include <PiDxe.h>
> > +
> > +#include <IndustryStandard/Pci.h>
> > +#include <IndustryStandard/Acpi.h>
> > +#include <IndustryStandard/SmBios.h>
> > +#include <IndustryStandard/PeImage.h>
> > +
> > +#include <Library/DebugLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/UefiRuntimeServicesTableLib.h>
> > +#include <Library/MemoryAllocationLib.h>
> > +#include <Library/BaseLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Library/PciLib.h>
> > +#include <Library/UefiBootManagerLib.h>
> > +#include <Library/BootLogoLib.h>
> > +#include <Library/HobLib.h>
> > +#include <Library/UefiLib.h>
> > +#include <Library/DxeServicesTableLib.h>
> > +#include <Library/DevicePathLib.h>
> > +#include <Library/IoLib.h>
> > +#include <Library/NvVarsFileLib.h>
> > +
> > +#include <Protocol/Decompress.h>
> > +#include <Protocol/PciIo.h>
> > +#include <Protocol/FirmwareVolume2.h>
> > +#include <Protocol/SimpleFileSystem.h>
> > +#include <Protocol/PciRootBridgeIo.h>
> > +#include <Protocol/S3SaveState.h>
> > +#include <Protocol/DxeSmmReadyToLock.h>
> > +#include <Protocol/LoadedImage.h>
> > +
> > +#include <Guid/Acpi.h>
> > +#include <Guid/SmBios.h>
> > +#include <Guid/Mps.h>
> > +#include <Guid/HobList.h>
> > +#include <Guid/GlobalVariable.h>
> > +#include <Guid/EventGroup.h>
> > +
> > +#include <SimicsPlatforms.h>
> > +
> > +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/Pl
> atf
> > ormBootManagerLib/PlatformBootManagerLib.inf
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Pl
> atf
> > ormBootManagerLib/PlatformBootManagerLib.inf
> > new file mode 100644
> > index 0000000000..55da35e87d
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Pl
> atf
> > ormBootManagerLib/PlatformBootManagerLib.inf
> > @@ -0,0 +1,69 @@
> > +## @file
> > +# Platform BDS customizations library.
> > +#
> > +# Copyright (c) 2007 - 2018 Intel Corporation. All rights reserved. <BR>
> > +#
> > +# 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/Log
> o.b
> > mp
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> o.b
> > mp
> > new file mode 100644
> > index
> > 0000000000000000000000000000000000000000..86d7030833a096f54539
> > 3735d931d9f4f2fbf8c0
> > GIT binary patch
> > literal 141078
> > zcmeHwJ9Hz-kzh@gFoN)Qu|weq&F~F*XbyPdaEHTfE*dKcjU5ohf-
> > &!%BU8pXGG)q?
> >
> zD^tc9GS`(UQ>MIoGG)r#cb?2OW$Gd_vnu0Pg~E?y>sT{Q)F&%4G9u%Xk&#)e
> > |2h0&
> >
> zn&2`0PLf>1@BjWNN&Xl7`zYzU`~UYcP5w_masS+n@=v#$bm8A8pL~*ZKm9c
> > M6#l(=
> > z^C_Iaf!{aDCtrS<d<p+Pc?<u(e4D(*e{bKy^(^^xHcMvkZ-
> xI>tK`$wx5>BPew+N{
> > zCqGF({r0EHo1gqN`6>SUDV+cGXUUiF?`J>zS@QFr|2+Bf=f6mP@rz$1Z-
> > 4R2<d?tv
> > zW%A`Oeg)^hN`Cb#`2FRtlefS6b@J<9|2p~dSHDSq^PAr!Z-
> > 4zC$qfGe$A7@@Z+@Hn
> > z_P4)H-u~uyaQ?gGcfW(*-~K-
> N{qKLDtbX^0<PU%NLo)l_AL0Cu$shj+zrX)e@~1!j
> >
> zDf#vfe@_1V=RYT_KmKR(E&Th>|AgN^{U!O!U;dK(*MI$2^6j7hn*8;ze@*`Ox
> 4
> > )It
> >
> zdHsE*z$*n_Dey{xR|>pR;FSWe6nLe;D+OLD@JfMK3cOO_l>)C6c%=ZLK$`j}9J
> %
> > #+
> > z`g{~f-@JKc$n%k3)||b2c=-
> > M+LnK+A>$>;;@$vEfKfY?L=VAb__wxr}$K&JI&mkaS
> > zw~kS*1G~9@9j0;vimRVfxy_Y(?c(tf7y|!~-
> 77nSYEzvqlcpIQf^ZIl@W;O*3M7fT
> > z!9kZ0_+7Z-
> > @1+@3FK$(@q_Qx*CNCLHfLrh%DN_M$JaLeE@0@S|JKldEOG8tTLJSzc
> > zYJ|Dn!`@e*DIXr+U-e-
> > ^H5^DwWD+9bE5=`ek8z`XKS_FDqrkua>L0^f)%(?nEBo=A
> >
> z_fYpY?}i^&&`AMu>PnMqa+)M3U!$^re1FlY5cqf;0Cy_D)w70^J`w{D#QyQ|9R
> f
> > @{
> >
> z8kVb`(W3$AHjlEeUB&Ltb>`mu&NuNEoIQM&cK+Snc~b#~A`kH2n~2dD(13?{
> J;
> > ulG
> > z|Id&fV>kskN%9G{)3wsUdQ;W(-n%jm@Z%%a^j$>b;a#Vy<Dc-
> > |$FJd0z%bzRz4!P4
> > z{sCjp0*YfS>J9)L?rr`_zY37>O@Q{_-
> 78}U2meqcS?f20ZdoD)$&5I7LUsP#5!2mA
> >
> zEIv!W^NqXXbtyvT1i?FFELrj6Q@p|h8in*2V;#tu|Ax1|Dk=1pD}m+Uwxe4Bj5
> U
> > 1+
> >
> zJNV<fsLOyKaN}*L9!@<z9mh8h<ni$wkx9P7lK%h4Z%*B<7Jsrp4EO5e<5xcS!o
> h
> > MF
> > zJ_0O6y=;Bij258V7V**nn0p+qQDwP~>Dq?`cmO&E`M9W{0!H{GGAQ{1E-
> > QX`E<5s}
> > zixRkn@-
> > arZCEI?0@4(@!dEW!@f%90CZ#9t*CtDBKkZs|re|+@#d>x=TP>&8u37Fif
> > zP;WRXRfWgu@yZqbfd>-qeS<tg%t&h+Aa47}cR8#P>jS!=`3l7Lc);J!$~z?;OIihj
> >
> zxJtjk;$;D^S?~^kMG7IeoW6RCcaSk~q(8<IzH0o9OmK=1x&^#M_~DWL3Z%@l
> > %Bx4@
> >
> zQb6AQ0u=1$cz8ZPP&8e|HGe+wWG;a{KAZ!dmCOWS0ZA+r)prfR?Qf3}ZHIRt
> > %l`lv
> >
> zzO}JApCzUJ@O1P=5WkZCa0l!MTn7vs`QQIzf_!;+1fA~c0XAemf*X$MP!igY&B
> D
> > W#
> > zd-rkbYJv*{4EhQVuCL$*Dm%m{luAOUt{}bp7>!hUi69=~R-
> > 0q&3OmUD4Bta0ky`-E
> >
> zBMCQ&c4z~>MVXJ@dBmalpL?R*f<qBnTQ#X(J_tX?h<1tLTfD%Bj#$v8##j&V
> q
> > k}Yl
> >
> z@AY!xHNnH@N%pU<a<nu~HUmE#yNG;vNkH|7S}oL&{>V4s^ECYzID`Mbp
> Ms
> > Hs!vn@!
> > z&V+3w2Pj#D`tZXJ_M-sGAqlrXPlBcONaEABVz;s4SiqS=@9#jn@OTgGC#?-
> > dgT$2G
> > z--
> >
> !^SMEK$C2MRMB*}oyW&Rm32W4K0r<wWA0cjG*hKmZaaM^HJ~Vp3Cse}#
> _#
> > BI4uv
> > z?}PKYf)sz2zQKnMuroQOk$1S&{|Qw)?8fju9MHeU6|8@9k`j?5-
> > ef({?Vfmz{NTul
> > z6~lkvK)7~A<pUsHuchXjkS)~s1>zt017ZiRi1VxPE@+rB{(^ty{I0;Y<X_;P2a4d3
> > zzTPsx848;6ue=%x{w`7+O9gX_Fu@+d-
> G_0CQt1Jgj02h4c>L1?!h9HEL8Lugef_t;
> > zp{PGRq8g8|BDz@ifQQ!rNT?+7E-FwFyj#SjQa(^$Ab&|ne*?-
> > yfnolYlQqW=01AB<
> > z`2nRtKFVKgL(mTh)C&}X`>xkSc+-
> > }ThiiC5@cGo?>P&AiC2xWXLl_@<ZAS2fn>B~y
> >
> zEP9hpAtG3)%foU#Ho^kTkU&H`)PUUf_74!O_alHGC?AjDQv~}Fsb9)RL?Ea%Q
> e
> > =$y
> > zhXSsny77dg7WC*bJj9k_&vlFfOrd>PIjS`$P>+v5YSQ(Be8ll!kPo0&7$ISGu3jg5
> >
> zXsxgbZ_sH7fPv9?AP+Yl!AUOpf$xFw@~#>p8DWL)(2C0&tEB~kMLm!50Ugba{
> s
> > 5Us
> > z{jxvCJA`Zj-WP~}DDcsbfH{urt^(i(j^2?UIN(APg@+Rg<Px4DH&KuPFrJR#rf;?B
> > zU-?Il{bQ^byA-
> > _PT`lAX@&y408LS4N0a^3MwID!3+5?Pt9q;bCP7`5;K~m|xn9z2*
> >
> z>AQp%c031C0MSbO0qqHgqY^dWo@^!kv6Qptfgi3X1$_k|p?4zHpiv*AdsRk
> D
> > KJvp4
> >
> zCm;S4$mS{S0Q*XVe}%Ys?dtt2B$q2SM)p<m;qHcx>;OAaaYNG3l=>gnf&eMd
> p2
> > >%o
> > z=g?`O9Y^r5u=@fRaNGm>3J*Lli5*cdsZ`zZu8ix(;hvL#HxLPh>lAxe&{qJ{*>j-T
> > zxp#cZ&g$A6<iop~AV{7GB|qS0Cm%j|=!XJm&x4gg_WNFq-
> > 6+ThAcfEZU}xf;_f_Fu
> >
> zcj6*&ffzxTI(}$a&VJDDSqF04`;~k^V}kt%@&V){;uxqD?;wMq2+^Qppxxuh6E6K
> > R
> >
> zJo^TR`e2}fJ;%pzH=2)NKVbCl)CxWd_5;oku&)D1;=FPgmV0jy`9Z251JJTdy~Wy
> q
> > zmtH6;zz^;0#~4uv^5JwTigFn02i=EN5hSti9rSSO-
> H;DQIAW}^{cyxP!JbD3d3}ZN
> > zfu3>%iSkkUSMU%B1_L+W2G?fj#&8u}NoPMCO%bpc0?=+K7Y}~e4JT-
> > u0UxXixi*Gh
> > zIGlXAVJO)1f5UnLVAmAXaT^aO;V4#6*vZF3u;&2GBU!=<_5-pV%C>9--
> > mZXie*!<6
> > z><6ePY@xE}kwK;20D^trTk6uDd-;H-
> I6}j3nY4jg4Jiqz_FYR+BAt^PLs>wQ%xgJd
> > zuaCaq3@Yg#m6nMlC-
> > M;iZzf34d`@{+@&UT97RiyDq}mL)eTmB7g~n9&qa1%k>X+@0
> > zcN~L|v{hZf8oJ;_91jwI*R>1&c*9b?=T1I#{CK$doA3Fa^Iix*K76-7`y2AZhl_)F
> > zV)bLZ7vzHj#VZ61{a}RWn-
> > 1Rs@HzmhX9EppR<NKCVs~(WK^wdqVOaV=2iI4w0|Ppt
> >
> zIwy`^BB_8n5%nFE+Vim|sk0j(?EnkM=Z?wf@8XTm(ykMU(x6w32r*QA!#fI&(Y
> > }s%
> >
> z8JG`j{I%nUleUr|jvrWW&@vUk@+4?~he~;`_IK<^?429bS8y4eJNHTn%Lg#9*7
> > CTH
> > zvy!#I+dZi4ITWwt!;Q9}E-
> #LbA)Yjk7k)|_=v=X^s>ew?VhMH}q}|yOjAp>C;O~NF
> >
> z#yA9O<?1bWQch96hj1!!U7!wN;=4}JIqyD>^5IJP;pZ5tf&&e%Iy_*QiUz=&53jF
> > 0
> > zKcc=W-=nYsIgn-8;)nM=tM>BEEq+lx0HzyEMf>5ZgNm>&-
> > %{+g{t9lO2Z{q^IHbM`
> > z*G@jd_yb-H_8bRQuKSk*!hmQg9d48mnp*l-
> > *hR;_(GTAb;}3X^lo~rkeG_=gQvmFd
> >
> zRszWjhAU^!12IrO0P{*dI4txuT(wvTk9HN9wX&Oa@)6pBRUs9z{jO#B2apT|0
> W
> > }|?
> > zx!x77g?xYoeuJO@k^{u}k%mMkCs-KkcTFw*D-
> > <T2)WzyQ13`fw?_VJ%&Lj7|+IvM2
> >
> z8$1hu(W3DOHCG4;tHHjGEr9ci9~@Rts;<04<eNba%q?$69fkVJH8<D~#0F79&
> > 0O_I
> > zk1z(LgTN4fcZ_8NKb(9-`vJYjJq1WXJ|dcFIfWix4m}?oH-Gx>AH4AdLyq#{`yxJq
> > z3oJFpli(sous~4&?4EeHm_DjGuOLB#-H@`94++clDgch~-
> > QR~%4a_ZXoBkCN&DZ3r
> >
> zLx0rWDes|tkT7hh()H88A0i*fC8w_dRwW<NBk4eD2*QPbo|mDisQBFJ<GTTt
> z
> > +&%C
> >
> zTsa&|c>Ceh<rrRt|D9JvT91IkL4=qT(5IEYf=6Co1^EcD5MYHQ!UiP2hn@=@IB
> R
> > %-
> > zqp}|WtFj-y6GJ`zKja7YM?Bmeln-
> > ~qyQKjQ=Picuh?5VeC7b|K`+<O>zAE9u%|Nwq
> > zC-
> >
> 4Jme0K&9zj*_#et6@sD97h`1Bft&$8hRQV5CTJh>=)ChU0VV%=M_?sZo7pB8il
> !
> > zkfcqrAh*6}+mGPgx`sl}189H}BH)j}54=Q-
> !r@vIu8DjAsi=Ioj$OGsp%+4tO2xaH
> > zJa;@A@7_U0@B0`S{^0}GNyq2N54<P+-
> > O@J=MybTH`PcQRAZcOR1MP=bT~Gx>5=r5@
> > zkjrj)I8fd-
> %17C`VCV#OVn=gIzUr~qh_csK4RSY_d;ndlYaC7aVc!^Gdi&u#13!OW
> > z>MQpSV(@jC!L0-
> jJGHO$Jr0n+c2gVgoL7OqjDO^YKdv80eFcF15dl}I*Pe{sD?k7!
> >
> z5mH}}AO1Exi?Bk6b&}`ncg|!j<kk<Ue0bheN}kTnmhurr9|(d?*7D&5#s@4=uv
> }x
> > H
> >
> z6kzQ<12?5q%15B;<2Rp2goEuu#RszFDuKTj<+Lo4#qq;+9<1JRT*wE$iSJUtWf
> h-
> > 5
> >
> zYAM*GfBm$)QT>Abz&1HcgflqsAMgWu5ZvXkLWgzQ+0_rCbC5_DlMk%bIV!X
> |
> > kFBR1
> >
> zizm7UGkyU6V~nr?kub~3X?K_*a#G{4K2QCisvHlxU<y$KSeL7*Qq4#o_y?`^u`
> 9
> > gt
> >
> z@pgFNCD>bGZqHp3qyX$2@~O)q!gn7Ovs_On_5%t5KYXrA)Kw*tfR=0h7;!`le
> F
> > gjd
> >
> z4HR)*!k?qKx;|PdpMU`Nmq`9nK4SH*HHaGG<}M)F)eo&fP{!^FfI#fO3U8GJ@
> R
> > yE}
> >
> zUJ`v%LnnY2z<Wud!}_DLA6|mT?yegpIXKuI+&!Qy1?<kDTYNMA2RQxi7(~crlK
> 3
> > +C
> > zx3V8_j+PB71bzT4#G1kKt@qI)Yy=cIkbFR$0PF&pTggh$&V>5<j-wS*X-
> > ?W5y?t*+
> >
> z^5G@uhAy<#pTa%35!!~+t5C{iV1mYWhxhGD`EcN%2$~F^=K(K7`{Cr(QSkxhx
> ?
> > BhK
> >
> zP<#d{2aFVlA<0*jrTY9EAUEDEk1=8w^c8p{NE+aW8;x2>9z#AVn*ohM`2ZaJp
> b
> > bx>
> > zG*rE|M7_Kb{9C;3I=gES_)5-
> > k0$}byaR^Uc4Q02CNerd@0I7Y~b9FnOBLvs^$Bub$
> > z75GtN2>0>8QLFd09>41N&W(cPMa8}2T1dwt;EN-
> > y>hPM+OPY`GqI~=aiQ=5P2+JWE
> >
> z2sFmp52df1Jr61~%15vt1a~D4;RazD_EY~K`mVuIz_vJ7wtNbx|ELV^1)YHTxPg
> *
> > j
> > zsy!2&D!@~uh4<7#HX8a`rGMqPR#6e5xEH<--
> > mY6}Hg>%NeE`ho0)ZI2=pyjqGw39h
> > zn~hBQ!dK@w>v4lgFvl2l*)@{h-^Kc&-
> > G{LsOg@mB&YlAy@H~1`Wv`9m;EDu^#kN!u
> > zfb_#~5i}0L0Xv*_!b?0J-bKF#@)@v%Zz?`RQio6-
> > _JvRfYVq>Qm5&$L9mc*MFCPxz
> >
> zS1yiN(y#>V6f)of{DAElzd<7gfqW_;6=$IWudgt4>gB_Cni5t((h&&ihvPu@Japq=
> >
> z&mCm1ukbWdpK5hL77pyY(0C$3{(k)XJ($dffm~Qa5%0${udguri&VnWpkW+f
> U
> > ^Ltd
> > zr!GDWmwr~N8V^EoS89we2CYAKr(bpaoSvg~1sDOKrW`-
> > K?*e3}G{0t%czhdxxdkLn
> > z;X?2E*tzb=TLVe&?_&Md92>l_^-;+Oyb0$38r3JDi}FE~k-
> > J01A>1G$v~}HRWUwuj
> >
> zd^mL;>PEofG}s1^I4{6hK6rpw%2Uy6eV>2zwHuBKz$sSeE!q2C$%h}XeqDA>Y)
> > NPz
> >
> z*bgDZ6iG)QtRKjBD1C(#@x~DCxj!%M2lfen0D8!+$f0n9h)`Ly{jblz^77$5BIt#o
> > zZUpS=fNDdy%g;t3nX5-
> > w%2Uxd!9y9la7_@a3NS)OsT*S>AAjW3rn4dy!oEY|>IkRG
> >
> zuo&<jWi7}@1&b2M^#PcXs=(}X0tf|}K<@(&CLhofJx@Y+!5LhiVFef=_acLKz`~
> D
> > #
> > z(T6EBrvRL*$#XuOmcxYdGVr66U`Iv&LZID+2^b-
> > Jeth$<Ujy!V4n9KZd*c<hC@kJ_
> > zaRg*3z{J}%NJ9Vdfr>KZumc(BD?Z-tJC{q9a<Wpg->t1h7Wl3TjjrxM;}CgF>)ict
> > z76H4z?}d)NW!+_^q!MpHoIH_IL2Q6>kf(*DgVtDpOMZL-
> > _5&9^;iw3BN%#?h_>S~r
> > z2MJvo3szZumimR!dJ1|+q5wj0c;&0)!=nV_xt`b8uA^XaXfa7>-
> mz+U?F)qU`1r$*
> > zLq-
> >
> o0CrAMbUMUbI$$|k9<Bzh`=V|ss*BEf`#s=Whet3TuEQsR=b$Ek+@%YupKCa-
> S
> > z&K9gtXGtKab}vI3DHw#^Ig9Zes-
> > p+UqPT+#Ze0l!`rVJ9Aga2ML<Dd+#k=mPB!QI*
> >
> zNz{(BjzCb}O(c41Ip7{d@UM^)Fcd)z^VV^tYCz~8;YIktG7U%~*Re4CZ8sxa)l_#<
> > z8bf>@&p{lqqVhk)-%a3`Hy~Rt6xoj-
> *darET&u!J5351Izz;k{r^p@OaY+?UUxi1m
> >
> z`p}O`P&kOO0GHZn3=RTjZ^OF)1*@zMH{>i4!e4}M!3x!55npYEV+Cus6Q{32K
> q;
> > O>
> > zb@YH<;se;#O}C&BuN*;ks~X>ORXUd7AE!G)-
> > 3U0GMpfWOG;Dm1K>SdFLoom&yayO{
> >
> zj9n|<V~Bsu$L9$w*z(+PML;~9WE!v{fw03oKK{52IUqj!94He2&}ry+4%Ol9@;
> @
> > gZ
> > z)fL`7kbF3|3flu9;c(0ibq9VxWkeNteS&?Fl=2!SLh)VIhbk#xcnc^?I}luoevKY@
> > zfCN9KZPBm@fe`T+quhrV_^#*u<B*@DVju_F4}ND@-
> > k{Cf1(%Qh8R|g}!~Y&usLAoe
> > zRf;-19NvI9et3LB_1{DN6QBeNYrqKOpC2D0?I4AxjBJ(_B=I#EqLelv-
> V{h8jUL{O
> >
> zOZ!$q`H)Y(`vns7@yGkM>XWyQK@^G!7$nTke{{y6lNCFFkl*`fr>tq54T5S1LGn
> X
> > p
> >
> z)3I>>)M+HAlfq^($ExWSZaWHiQL^UG+r9r<>Xibo6nLe;D+OLD@JfMK3cOO_l
> >
> > )C6
> > zc%{HA1zsueN`Y4jyi(wm0<RR<mI7I)+w1jD`u*-
> > +87A9S`&wR7Ano=C!?V%l_3iEb
> > z{r%+rW;FOa;0S&Q;lpc2);k$qT;EL>t9)G@`ShHvqL2)H`PbdS`Diq{I6oVn4o>>r
> > zxL^EBMm_EHPe-
> > @YWl=GrI>|@X8kd*cf*Rb?!Obi$)<sd|tHpeBcRe~Aym+Q``opV<
> > z#S6!j;_Snd^^!a3`J(Dr;iOnhZ!S(>u4T-+gUcz=P!j+3dj7#q>8Hb*hUL?nGZ2%K
> > zZ7=6H>z?1&;2aq<{7?m?tE3|~s#xBh^<J1YN&A-#7+1I-
> > Zbz=C?TFb$)dc%wc{6xP
> > z9O>UIZ9K)@`wvuMbtj@B#^sEBl<H}Fi>$3JH`eP9l^?w}!e1;d53|}v(s#S--
> u1$8
> >
> zZjBBEw{AYrAxLj!w@2J97FYf4h<EVPozZNg6^~fEJy;Ho!|?&Ok`HWVKEHZa85
> v
> > Gi
> >
> zt%YN~UOX$Vd$6sI{Rq8oH61;hk?dW~x8TNl?e^Q)gDlVX>PG)6s(|%+dH+0ae
> R
> > ?+8
> >
> zLRGET#fNG=pd0k(l;RuCi~034n33M)HaNoI{OZ}{cz?M{&)Qk^z^VNH?1_i$>E
> N~
> > v
> >
> zh8TQX%xAON{q^vPG2EXC6hb=MPBkyC4z>3&#iI7Sb2i;%Ir8Ofa(8n%g7`E9sQ
> > Vu@
> > zH-HZ5@NTxs^Ss#9?jRz?-
> > RaXcxqH#9tBNHE#7mBS)^@ap2i@W5>iXv9_I@&*v8kOJ
> > zb259X37@oo)ugNP<@EMq@PUr}8u;NK!FB>L^?81IGnp-
> > 6KBVbbUiP0Newv=#*85e(
> > zYJPX|Bxr1;+>r}(PR?&&3bctK#qG)Qbyhm453Uuf+11HY^ob+Wx-
> Iz5>D81@N-
> > O3}
> >
> zj&4NK;Y`&UZWQ_S#l$$<QgrWf+3<GJptt77o)bN*4Rz+TW7oYm@s0za*W?Q
> ?
> > jvJIX
> >
> ztDWeWyA9Kh)8dy7H9N2OH&>TO#QwaF9m~tVSBI({H5)jxx;~mktz$=i_XLhaJ
> H
> > k9y
> > zskD1p*H@3mkUC{Gzlb06eJ*-
> Df4$kDZXB?>IfjI!L%RdycZ1`5+0Rez78rETXZ8s3
> > z7!r~WY|jd2jgP_o7R`ToMY6$-
> > JwRMt9hyezi9PPvkd~Xdyz29d3zzr$;u9=Q7DGPr
> > z>F_+X0g^<UNDIENIXqj9n%*+2ZM>QG@2z@@`}zTB+QTr<-
> > DEnSFP6(C#@!*${qp>@
> > z_u;5FNPxY#gb3nnzVL0BO?~QaEmN|ydsAmE&kx$_-
> > i=jDep?qE>71NhL58~?xk4EJ
> >
> z{_1@20XP6@_w?fWex}ori+nM?y*#UNDIxLN)LDx|PEmC(tq|hs+D=f&`e#>@
> h
> > Ag0B
> > zIlVqVdD#P&&fwy9Y7*A#iDGeoHMD1SdRM07GlMUv9_Yv}tQwYArU-
> > TiqkF43*LSPQ
> > z<!P<Z9|-
> > N8!KA(6b&EWv#ofh;CFq@z>H6H)DU)sSOox_{T3%ZG?hdYMoIcJExLRDl
> >
> zOpc_zv)j!b$~7mSURtU*y)YSab0AOj#E7sL%aOs>&fwa_MDfDkSlygj{mTISbh
> m
> > &T
> > zn-le8dy4s`Wk}4hYjK#MQuiiSU!7U(NNY4_^^!hW-
> B_)8I_j&MI;VG*snnRqJ9BFU
> > zc53y@<slL@(@VpwEiY9|((IzahDY?p*^3%arYE*@Bybj&#mw-
> > X1{N`9Zi`k$x~*=U
> > z8OCFEr9h;8L#qkI?aS%&<nyT(z~^pky>FvU?-
> > qC3G?)@{zjvlwZ%Qln=eZ6cXQOS!
> > zJc3<azl>D5{x*gqqVLXDS`}FgDQ--
> k)aV;Ex6&I;XCw2oZ;wg^(sh@`^gtg5uW3ZP
> > z+h>-BsY6-aFK$(*vW)t2uW!>Ni6y~zau}GMZI`{L8na%E+R^NIrLt?oOlm~y?-
> Wxx
> > z;4|Ic>FGXg=o{K<B0Doo#aPjlden_4%Y6lTpH{-
> Vy*+eQXil+^=^WWek7J6vJpvP{
> > zF~u^I=C`+tPoh|o-%F|6lfv7)o(?wVzbb@{8%vop-
> > Z6x3p9ytiMo<MRo6_S9oNI3t
> > zlV{uFB(;3VT0|QjtZsz=)VtN1V<z=W>z>oqy{5Pl;x=d&bVyj7+~3|p-s|0DzCo=i
> > z1>73Z{R%cDBRJY)O#03>;eI-
> > AUJ$mrJ>j?**@MO1u0Gb4_N}BXZ)C@EayvSQ<n~^-
> >
> z+l6hHPR~X+O>y7#^Nd8YrtI*10h!^$)05DK!Rh&BW84>}AQ(fe*xzbLAFHpe(Ol
> > @1
> >
> zLA{@gLG^(M;ifn*QoqB=diD&fL^}1!QxH_Y9QH+s4fX}OxTz1tL#_>DNH)@b+i
> W
> > LO
> > zncXSfw-U2lClgg9XxGL4s3tO%^)K#f-Q%a1ka}g6&u-52u-
> > g&4Gq|jsQ^@bQ4e4Gh
> >
> z8Wnmx&3I^Dq^AmwTtHqo3M>|P=W29BD(Rfv){VU;(upUp9pe;+PPTo9Re<$
> #
> > (SS+s
> > zqE629Ti*SRF~f?>P^*S@_0VI^E9%<Hs#r}fnz(_r!!)y2hK?`?o3&}x$aJV%>Cjl*
> >
> z3eBv+bw@Q?E5BtvkCiAjVI?$deJ4Fv{U+xlkB;HX!8=8}HSsWsrsWS`7violJLDb1
> >
> z{lRAE(^k3R{TsUtIiESru5?Q|DO)tDukw3}J2oMhT_Wb{$nQ6HtWbOZPFp$vS3
> K
> > b^
> >
> zKs{T+7i|NaAYR%9#WwKhVn++%wtImYOW>DG2^sQ(yjjU1Y7^^6=72=>t|kC`
> > KFf??
> > zDGIpzc5^$}HNlC3cglelkc;gGA$>K!m2<CoV0P}sc5-
> ;Cgb;aZ%{{iG&X%RDnYMMY
> > z-5f<`Cz&sqsZF)U+HUiZY=nei$CNd;XHs&?T|M@Od0{Jz`Cc(lvm)!JnE{(`t1i=l
> > zNeXVUQ`NoKqisz3iSh!MEb3y;sju&tMzctu?sZL-
> G251}3T}%Vh64$*dAXe)!FueO
> >
> zQ65;*8!#@m@OeARR_C|Wm}euc5Z7xxBh!W|*5c{iLp&{N3`J5aabdZoTKBN
> }c
> > TAJ`
> > zi=4$8Qtdfxk!_-
> rr{}E4+EbC+2w<dJ$6`o+9Sa=k%&JxeuUppLvludG0&t=<R(k=-
> >
> zE@k)U3G>#tytvt3S^3s>tz^`F=QTGH(wItE@5&CG&XN=ZKkbIv^z>SJ#;pb9ME
> T
> > 3i
> >
> zP+Qr&`A*8pQ>|yjk=F}muQrl*+X9v?U&;BsEr41KSuy3;Q+b<hCqi_t2v4^%LOy
> > wu
> >
> zlbCgTCvep78*FCJPita%TM((fXwOJa$}e}7aIEJ<&lRmX!IgJiwDcYHT8{~pyq=Ex
> >
> z7E`7x2_3p8XP4J^um{Uza({Pyc_t(9zNoGdY$A^W5t#d*n(pDw3fJRfjHL=T&h
> M
> > #U
> >
> zc+0dJmCeouXqn>k8s;rb8g&NeFabsMCaj!*FHeXG1$fo;;oEi}v+Bm1S^)t2XZvo
> u
> > zqPKVlgG9YjmEF+p69e5_>Af*!WDI|n<|YJgcMk~)V|CX<F--
> > *wv2vAGMj9ri^RD0G
> > z$V^+lU1Wjc5zaGX-
> 3OzbwlVCn0n*)4=3zA=MU9w`Iizh$bzj^JrK(OZh!~YjoHtB{
> > zz=ti)&QHzt7X(}DG&MBKIyYBOSg+UL>*^6r&P;?-
> > JS(#!^BOX>H0_=m2gNNjLcVE3
> >
> z_r<kbTa>D5fh)C>Apn26DvH(gs%93Fw~1Yy7=wj^4R=}bEiR1d(isi?^wc8E7G9}
> x
> >
> zc5}Kmw4)tu!+3OthW}FbdjC5+6T`<$nL8+0vm%ac`efynH<GY>%@M(?Vk(eng
> i!
> > xb
> > zn-HF`t1L*1P_i=DEFV#c+}c>m+pFC>f{=ncAJE30F}YLNAJw7pgDtl-
> %B;~RA4=EL
> > zd()FlkEG_*)lq)r=9%=4k}0YJjhPiT3Uvru3V|@9I-
> LrS=G2(N<sM3)2lqI*m%oW*
> > zx(ma~xh*C<n&B&ggEprDO0^20cA!w!Gn8=_7W`HMx1OtU^gxa7D-
> > MX01)sG^jMSJl
> > zQ@|d{bjX7f+k7^`vgO8VmXaD<|7t&xF<Z?KZ_FN5@oze&$yBJnU@-
> > wizkUNb!40@v
> > z3MbP@7Y3UyiPE{^khU<!R%o1uu4QFgUS|R~uub=543etI;C-
> > {@Qp;~vRR3M5NkN&f
> > zn4Bq=apLi-
> CC?k^7&cumtWZi}V<#(#YNlYY;6qt*=U=TIn1Gzhi6v%VbggRkk*0fO
> > zDkQcN9egY4K-
> MfcLzHs|MR;r(P}ZG%(Qb3P)QYjU3|eSX*>}=&Igl#uNlE41ZJ1e5
> >
> zLmH}&^e*O9nPIJ`MpTVUguLR*7tBm^No^$`5bRJ&jnJSvwH6mGSV*HPy8DT
> q
> > 3t7-H
> > zh>8tN<<OW`-BaR3&9x%-
> > QfxWUS0yC*)io?Lpa@t?Sfou?eGHWJq^VV*f>R?+b!j`)
> >
> z6s0ZC)1g%A#VrA$I@7XAw$<>03V=>2;d8`EM@g3=zrIo2vZ=?ev4o|Vup;R>_
> > pcCU
> >
> zaYL*oX+Ama8^$T8?IUIPIn}}A1wlW%5Xk40Te4mmN~bA_sfshwdH_<YM?;?c
> u
> > n1%}
> > zt6lve!e4!f1Hcd&nA(6q5gJ91&BANbmQ(9!y|l}{^i&E+ensF6qzanVi*{F)B@-
> V#
> >
> zS<RZKMJD!!e#H_tSb|R+3}FW*V+0P=UhvGWQzO>GZMqo^mcBC~0iLGTxco
> R
> > PfI4bJ
> > zi#Zt+D)DJhSju1%g_Nq4tQBDvwAfC`THc+Pp+nrL#pH-
> > kM>=E)BNaA;HiI5BVazx~
> > zRMW5{YzXLc2(7PDrPvFCeR|ejVaf3rO?&L9fdya1kf~mQie`GjnAS1Bs>-
> K>la3zd
> > z!1r~S2c^3pRAy|FP|`5f=^fxmZ<Uf(f@<-bsR;5t5fGIbJ+B)QW=dT})t0Ip)D^K(
> >
> zpbw1YBI}jT+CQ;AtRtd0U7d@uUh`p_8n*&Jiu&AP%i<g_aa+?WC%v*G1I%p5
> P
> > 1$`S
> > zhcd)Ks2*9|(N`0TK;}jmR`Nn2G8^?w8jzcR56nss$;I-
> m3PGi_0o?kC3#>C0!XwjN
> > zs^``Y2~}`~#QS<O_?nAx12&N#xt(BiqNh;S`85$}AfwJ#1<-V8nk1${kl_N)k<4(A
> > z*9#F{u9$a#6J;aTGoq8U*Hq)H%hB8-
> > 0!hy}tzim>;jQ!G*ZEaVH7bS!pmRQRnVw2f
> >
> z#WH;Q*7B~Wqz6U(tk2a6V6pH)&N8)<f;bzQR9HFF{1pNnNdvNn1)p+o1gzeJ6
> > B%-a
> >
> z0`*Z>^XqY9NnI+3O#o5Y^u${EuHu`3oa#%69p^u7%R$c7B2J?E(^G5=ISTIZmk
> 1
> > 1n
> >
> zBeo{euhu>j*@5>@q&8cxx%`xMxL=*F4ajkTNouWz<0@Z!d_ZTR_^>{+voM4
> X
> > f6<eD
> > zn=Xjz3Tm;4V}(m9d74M>Dmy3a#8W=XH(K1d-o&)86K+CM6-
> > <U|d3eLJ>BjW2l5J47
> >
> zysnA{hdWWh8KOxu8R=MB=%~r2N!0(UNlQ8{l4!!L$Oy=2r0IVWk;Yf7uPTcSG
> H
> > dcx
> > zrwC~7^K5+szx{8iusa=ED`U(CSE2H*5V3+pgp|L-I+)f!o95ii-
> T9@vYQ<mpd`V_a
> > zXz+kBG)|$nA+)kTGXO$Y&U;VE5Tqw9196AT+S8#>NkwFu^50h1<!kt>Qx-
> > Qaa8eMl
> >
> z@+Ehm%$+p(eqPq{D%i}BBBzI{hDzfv9OO#Iy6N~psUkXl54EfH%L}5eq=&|)So
> C
> > VC
> > z7A;oQAw$GCy`v`c!C>?KLDX~tK*@<;=o-iK&_q1>AjCI-
> > sF_wW)1uaQuHwj|1l18?
> >
> zRciFrj>v4aqM}LBCgY=H#MKM2)r2)p&siS2nf$pVniiXv(o7<`zew5sL;tF&Ju0>;
> > zxI~600TJnh<(CmdsmZyzQd5xa7B^XwiMa?t>FfZx<kH-ub-
> > }z1*q$RA{#@s)#C9I^
> > zOe!q8KCL6?E_mz#@K7-@qVLq|XV%`1^pj;Ys;-
> r%M(};f*C?ftkf_i6!9T6nQ3;ix
> > z)P&*#hTJ;}<n!xj73=Ui(0w`ATF}%D846L0UDSRHWPH|>{xX}bR(-
> ggctEQq#z=0S
> > z-;iWh>M2hNF$0uJWA;Zk_xE>KL#?O}M1BQE`J}|-
> > O=JXH#oT2SxR}HWB*k+!S*@}P
> > z`6xPqQD>RN3K=rt9k^%NbY8=WN^v#E>9A~0uLM#!9qxu&;!Ib2$o1$dgw+-
> > 1oCbkq
> > zD3u9-
> >
> 3dFBQt=nX*n1Hw!cUP^&yg7@#r)o+X*ebSkX^qkW3(CO}U81VO<s>%cP>`eH
> >
> zRZK%sNsdfkNa0zl@mNC>tyPdKD%bF?m2%6o7qW9{9)TfC5};_n;E0c8Dl|19D
> j
> > Gzy
> >
> z))6N;{kM!UU==K3Tlz{PU`6!m8$GmgqIm2zRsI`Ldqs21z{<!0FBI80CauTnFi+GX
> >
> zUfR)QxRlWp+$$L{BnCz%WwZ1ZHEqt)RW~<GXUs!fox7`gyb09i@yd>xv4$el;o
> p
> > qN
> > z;Y+9xHAP6SJP=twGR8wkgHrBT{-
> > ){#)M~Y8qiNH{2AoDhB8=r(Otd4X{(&EBdw#M7
> > zQU@v`J#o5Hg$_{>SDuZKNS&15M4aSOOJ+V)a*h!ii=d1%Su-
> > NXa`fRH#dIvhqau9~
> > z4Rv4+ottZ*-
> > *iiUcZ&warM+JB*quyAAba+z=|z@&Ao~EVvkBMuOsYeqB=zpFq%j@5
> > zUi0h)nbw40SePx=_*7?dR)I#$l|kntblG6i5}B~g*1V-M3bjKxLUtphB<T-
> GJ##*N
> > z#k!Q4t-6h`cX%!-t48-
> ali?I<?7_Vf;!b94WH6DDO3KxmgKgEu8h4ewt3o!&G``Bf
> >
> z*uNPDGto_C@Sf&Erd&{iE=MO!>!>MzvH)0iU*`SDhdB+>v~6_9bXWPXup?tO
> z
> > z;Fg
> >
> z(UU<TD3b5cKiZ<bxttseP|GXh@oWnv+5M<{C4sVlhICi;^3KgzgS|G0y%rvMSIt
> N
> > x
> >
> zwc`{&)MF(Q$=G`vbPiTVuBD`LSUJZ{!@nv8gV<B0msvbRMwfO=;7_e}YH~lBfiZ
> > OC
> >
> zDY&WZI;hl`I3JAC?Ep!GPJ$kZoF5_ablpM83Q0BKqiF}J4CU>p9#U%uK)HLrlyFC
> F
> >
> zmZEO${U;V+wIk$#N=aY7AcFywQ%W_xoZ=&E61sxq`G_Ffl}Ycrdi;7BBzA4)K*
> 4
> > $+
> >
> zBTU6TsGiKw2PiqUq6GIRI8`ZB%)t^d9x|Vs&<!YDw~OH+DRXQkhK#JPSW@pc
> E
> > zabu
> > z7NQ~clj$1N7W=&q3@fvuRM-
> > Zm{maUz2z8?5WCK+#(zp;$QifOAeho6zw?_=m*r^7_
> > z;M~cwQn3ZKr3pp0+WT|uPwmYRq>81!kQ_<Vw#p@MBw0xA06{?}a`ui-
> > 6m7<rmgpM^
> > zi84igXq4egWX*52vpz)YJodTt_-
> > F)6@`}>#ObiD}?xyrvm^PL&$MZS2Y^{u2x~?q@
> >
> zlC^}K@9@)+gD?amqNiITwtI0I3!=%Ba_C0p{L>3WIv(`X64HpWbQ>8hp*CszR!
> C
> > _>
> >
> zgyej>M8}n3gK+B`bA^#`wmp8^zae8y#7|OdT*%N(4hLy;SBe00cf};{n)+<pW1q
> ;
> > ;
> >
> z3=&%e#JX}K2Z|JYQx@X`LF<B|y#r=Dz9Jo7I+rcizmgsD<?IKUagwXfX^b+F8UJ+
> > s
> > z=PoTUZMsN>v9cFv|ABf3BA*}Gx@Oy{?}FSe@5tDAaTTG+y~Oh9)5-
> > }SG8~lqljSsV
> >
> zT_z2SNtIZ4+cW8RBO&EFD`_KL8MdOuOb%8V9Bpyhr<_bZpt12xtlJ~g>oOysY
> `
> > 81)
> > zPS|2l6{Y9y=?*PX(_27omd*mPcbV>j4B-
> > PGDeqWfEhZgzKyHUu<Xj#Vc4>TL+JH1W
> > zWJXp7)XBsMC<c*Kzkicc8K88O<n!qr>uVPa7Fq0C^XV-
> %^W1^r&9BJJ7djx6)-
> > pOn
> >
> zGF(F3G8yS3UI6R`ClocyTWm(O?y2Rj7AzJG(Kc)A0dCV}v<}%?Ji~mt9KF#&hIGs
> $
> >
> zdUDE%#6;!V4&o)lnq$Eam8Drn^@jU>Bla#o8ZPm5)aEM(Et@U_lnq!M>X95
> %(
> > XBz`
> >
> z06k6~NFgA@NI7a@!*eN(2hj*}428tz3H6ZtZKRX%&pRY)!5DxM0m?%Wy#bD
> l
> > Hqq`Z
> >
> zRdXCn%N#=zzLNZ4={$0y5thc;fMw$&bB{PWkb<{U8Bjo`@sGQii9}*B(}>4G9!
> k
> > p6
> >
> z8A2KPh`m{MH^N1k@Xx{}GL`x;fmAyL#UsaNM&g96YUxV<1z5(vS#uDIHv>_c
> C
> > k`?a
> >
> zN!mEkr}z;A5cMwsBFEuJ(v_ADdp`+rA_=VJRqNOyEYc=97|R{=kfT>(nG<R2<J_
> v
> > 8
> > zog-
> F93Ka`qDT{QV)fLkJMt;c8x0%@sm(1&xx)z}<c%IWSd4aH%=Sp06iC#1XiXU-
> > Y
> >
> zS8sHnHYp!;N@cH>TI2LWY*%G&PsylVGnk3%RQJNM)ywizcw{7@(l4SED1O9l
> *
> > 2oVz
> >
> zQfAa>g>OwE>l@YUl?Xve(Z%l1!@(UH48<a`*)^3P^0t(8nr$w9ujsnU<X$qalOn
> )
> > O
> > zwuqPP8%`vINaai?QgY6hbfm^sq+<1n@vSS^>Ld0xQscg-
> > S+@`0EbFi=Zy36YKmp}P
> >
> z{m`y~AI&C$Cq0rRx_w)h*xzU2dscO<9ey~q&B4qOV()3^0=|^Bn%@c;mYHQF
> 5
> > ~a3L
> >
> zh+b_&+(XV0aTCEDvx29C?8%bU$TnOvZvw2P+J_Cp!K{l)qlt1R1~Ypi>Rvx7Cz5
> kI
> > z4XzWZ+VNu>`QXA%=1*yI(IJ{B7sMka<@Z@kYL95`sT{L9hVV6`wES-
> > 8{g{cwx60m4
> > zKAQL;LR4HnAcR#$F4}yXYP-
> > hDBnwB$xUA6uvurx`@y*?@z!DwEF%J!5tAW^7R9o?*
> >
> z8uB*qL)mjKA4%G~m@HSz*(F!)+flxzw5%H$BEHXJd?5&ij&V2(kj(%k{pLVT?d
> > @-i
> >
> z^aHkzb~k%2<}t|Ls*V1xLpkg8dOhh^v~Ns9N#omkFjvlXjqHHPGclhoV@Oy;PC
> 7
> > PV
> >
> zvH6kM`h_GvCr#sz2LGy5I*2M9gdb8N2#dNI*?mfM#gr!ECO;%S5c#ZFhEfC<^
> N
> > 8-|
> >
> zitL$sL7OEOlhdsfn#Skt`9TC;W^M5h5yk2l=T_HVaR(~3GZHB_nH77NAFrY>Y<
> Vv
> > C
> >
> zEuO^)KvVpxemuzBR_HyHAEIwPEkDfI`<x{&Bz8EM#8GQ(I#B{!(q9%o;hE6|<%
> h
> > _K
> >
> zqUKK~X2igOlpHeuQTb0O<Z#5Gm&EEQ*O?suAP%%qP^&e?3)u^?lj>nILXnDZ
> c
> > l-rE
> > z)`TBY!0G&lbk-
> > wjRg}K+yb}3RWa94lZ}X=4eU^y117+ECSYAaLVg)F35un@#Eml_U
> >
> zZ842COPv(Q;AE(Py#tQeDmfob@{gMUGNg`m(c=3oFw@~%ME{EARWbyDM
> H
> > hU<^sX&P
> > z2ee)gylI5g)Sc_6mKwYO*|EsfdaU)RXQu|S`FE3(RHh9efyC#!?ZHg!$-B2f?l(>S
> >
> zD>>&x^Gl@b8Y6Ei3K>ViGDO7kuXb<47H`&k4TnK6qar+eA(iP)$TKmRVK7@?
> $
> > i>NY
> > zF|3@Cp!rvFXcvbPGVPaS1j_ux?e|}3-
> > LATVnbo!Bx2vq>RdGTAL0b!S)klr%aA>+O
> > zH}9rj;%LfGl%exDm9cC7ZWERVeAcyyExy}ley*FxS_fqe79}GbE4lB~4rphi5}N-
> d
> >
> z+1)aKcTIQJlUV{WA5QMSPV(F3UgO99Fn~!9zJYFNy+|(V8oOhPDc&=q$N|0w
> *
> > +f0D
> > zaWNrmqE=VLe9`PuaQHfsMfS}Dbf^ft?U|T}^w^5oVHp&~LgI7XQbS-
> > 7F_>wK5h*9N
> > zJz3--
> >
> H#5vf<UP5PCFWC$03~ch5&aG+RWXZ>fIjxA+Km<|DL<)VnHl1_1CH4ZA4ww=
> > z8m!x`8Op>)Z%8^y#4slf>kZU`39`IPdI3)xFexb{dyJzb|K^%j0FK%$9Be7R;+9P)
> > zmNmBjmATu?7^{&3J34)?*5i;=AUX9zjHMj4aHpj`)_ayz+e9F-
> > <A~Nlx0Y9l&vncA
> > z1wz^Pd-P;-5W&Hhsj9Zh(KJ<#awP{@uclUbk#*!vAgg+x;Kckkx=^0hIGu-
> > s%>X5x
> > z)ZV@&ayUpQALVe6c4oO>GTl%{j>3uBm2G7EGi;Cj?r-
> > #s{bWQ4%BD682WQrNI$PAT
> >
> zEryv`oV+IAv5}S0>}MI?rJ*gkDF)GVQsw5+T5XH@p5^6g6Q>*a`t(d%J1j$$1Plw
> > M
> > z!w4k`qMx@$Qts?c=Fio4C8&=sXO^h)l@U_1fKU!V<X42Z#((D*GRs}%-
> > )BiWMvh!T
> > zwFJzkiz#hn**-
> R1c35JL<R)qb{RE(#Nr>Sq>@<i~JjjHn=CR0V*qOdtzu38nX*DIT
> > z;`=O+y`WuM{<-edvgtY53295b<fm~-
> > c9)FPvaJqfE^AyK1&+BG^0N?(AOi1gTOz+-
> > zaeFU!-
> > ao92M4r811}Il@1NF9;rt&j^#286mh?s#Sk;_x!@EoT6&&&Q6e#r(V(nsLx
> > zxGma;DR*ilEiPl+2P-jcI(I_M0OgD)2e-yo#x~Z(7Rj*!Rj!$s$>n=n$nTTR<B9_*
> > z-
> gJ!F8tX$9lr6;W!@s%K?sMH*sloS!V^CrXbmb77s+LQ!O%F5KVk<YYJp<G(l_1IK
> >
> zQWfs5YPV=+O;OXPlj(kZt;O;x8RBqSK@4VUFp#%pE(kH_$`zvSm0Y{O<bediEn
> <
> > {p
> >
> zOiV6Rk_aC6+Wf*DSs#J5%O2#Y9cO#6i0pq@B<J5s!eX0`RDL^}*a*4JIotb1dh
> d
> > KM
> > z1-YRCU0^JiVmzZk2l|{yJBXCzd$}jp2c6fP+QXGrS-
> X5EQhKH|S4x_5_R&(gaTFaY
> > z>I@~S1tllxnybwn=-
> > ?$}a+2%X{0n!fjK{e$d^v>F?O24`+m?7s>$<*+(MdTtWuB1q
> > z%j4`I)-
> > 2~7*Ru##R+(S6#PvwUWdHEQW|f)YU>YET(tIru0)bD4#84oESAQW>AIa88
> > zYDp0_=c&xnkh3{Le3#L|l7sj4z5(j`*0p+~0!B#56(5D9<`yT6+A`jaP}aPcZbnD$
> >
> zj6}Cz7HQTTxZJ8rd~YI=A2=ubDrHxKS5KW2C&{98Hd2y*pCvJuS8)$Y23QfwYD
> ?
> > !)
> > z1_i-uuCSHQ*eAy1{wi|ou&$6FI@2p<a=-
> > X=h41bsG7f>16yImr^>f|CJ!*lU%2z1J
> > zOt&;2WS&Yd73c017<3`vG>J(136xhYkUl~Yt80sIqpQuJkY{{8-
> 5ktpWz%K)I*d)L
> >
> z)~ZjVFtsALcBYA02tq04c{J$CpXYl`RTv!QBpaNM&Ie+BSvnL!HAie7f=aFVbWUy
> a
> > z1Jcy$ZfcRLf~YIGU*(!<OPPBl(?nzv>UtH&i)#Bj5;EI_@t)5+XLs|(ayh>jskSlz
> > ziu{1@v#^MVNp1PLZebb$3jf$-BmV09(=>1?-
> > N1r2K`mAl>!e{&D|%c`rq$%`M#QOW
> >
> z#CPw9z3Vb%YQcIJ>Q_xk`Gvclu|8d_N4AoK+uL+$A*gqy(yQqFcp~G4dbdsK{?
> > QSk
> > zoX&l!?S<*=QXyQ?p0RU&E|?}qPAEi6rWvwxu~ZL>5F^moqvT8!+w-
> > O)H4<C@BVE=x
> > zch{j>xmE0X9)(|f*-
> > @D_V!Yo&z8_4^KJ@{cX&UqCOTMHdHL1;}c+JmsivVR^E7W`?
> >
> zUGuFLIIw8}*_p)0fS^X1rM=FhC!Jmh<?u8LORORgQA4$#7k2GAXIdsFMX?ND
> G
> > SQXu
> >
> zbWoxoX1R_TxW5)cqX&)b$#nXHdK(?Fs(;PnJ+98apgGOdm7|w}<WSTjyyp}7!
> 2
> > `Kn
> >
> zjro0+DW6vAT2s87+SXvE%}03kYHYfDgxtD&O=grpwgs)%9BW6oOlne+G^#va
> G
> > C#5>
> >
> z)oWkZi=C;1g0FRq5R~}l8f*wAn=U=5R1UAO#}^`;WMC=%CoXu(A*XX6Y8WY^
> J
> > +3yn
> >
> zQ~P=qM<B|*Bnb}&s)x8`d@zR_2dJbk)i6*p7k1yW>HKruH5*<>^JzAxC++o`?e
> > D8*
> > z1*p1G-;T1>jY{IBLNpNGFpdA3=<a({&GP`Mb)P*|L_r6NQL@$Ny2ZRIN(h+-
> > x7w0v
> >
> z*`%W~HNGJ6S(w3;_0c?_sy1CJ3W)rw7i`v6y?2b0RIaf{645ReDkb|1VF`B#cQu
> > pq
> >
> zX;_GnC+Wz^2rMGCBWtF$UmA6w<hrOeQ&&TTPY!7rLsim&oW&@G3a8Nc7
> > Q^%~7b+YL
> > z*z-
> >
> @G`+C&Z5wVrzW3O1MML3vk&=UwHrb~FcWRee}N22+uw8gA1soZd48E7>!l
> d
> > >Q+
> >
> zsP9>?qB~4s9Ohh!BhrWs<jQ(v925%{BKEGwZBU3$@yh4~f+4$9l(mK5^i(?uR
> G
> > aGM
> > zD$Cfl!4DC8UeE=(v?e)-Uy~Fq^{rwWS*Ab^aV}SYA$8V7T4^0B#0o{p3O-
> > k~#quhn
> >
> z!>{RZf>vopGwJ@osY*$uo6D<EVKJi6<9W6eY$qcyHC$XXmPa55I5YQuS=DW
> @
> > Wx1<7
> > zd8X!b-
> > OL=N#(a9gqrqj%%oKUHS)o!UYZ}kUu3Z0$e{}FFR3&}&oCHj@MmNTkCCYpK
> > z+WR9h>QVTX16AD662@!-5`%|>4Tou6%y?3Y18VKy0qTz^Bo%t%-
> > l+PhDTz#RwB>RI
> >
> zs<3n=2j29qLPf_Rz$BQ)!@tte4iw#D#}%^7j0gu?8(y!Mw_@a+of$!6?rWrS?i)s
> z
> >
> z#06Kzg)C60Xy8wJ!qBXV!b)U3WrIg3K)1iNGSmzDogW3t_&&=ry6V2TwHts42
> g
> > ?N+
> > zPNC$}t3ia-J-
> > aO@0HV5qGxk+2mC?Ii(&(+4O{yO{q)K6toF$b2e4MW=c4eX%G`C<=
> > zor)i7mvk6kL>h+TC(@e-
> xGOf|x56)2Xm)dP+J`*}PtGpy=5izl1pq&4u66Ds*Pe3S
> >
> z;9AGps}`yVGTly8&Pufj@>G!9o@65_qtITme9nZE%2bZ^T$i)DKMx068#p*}FK
> 3
> > hc
> > zyZh-
> > }1}X3%90mI>km~>ZV`J%1u#`?TNvu_(C0W>+WU7bJrxMg|*Xfx^B*yk`{vNOl
> > zLGd2xQ8B~8lejh+rW~x%J|eK;-
> > ~oJ@C=Jq0tcM<*Hmw)X3X4wOXuHYeeK!v9x8#Ct
> >
> zq{NB}DKB1KiE%nhttkt2WKIXb=HcMXnl9PEjCH~DXLU4yrR}QEr1C&~iEH_*5+
> >;
> > K
> > z|E`Jxh#l@rC_Ddlb(9YFzi$%>$Y?+{zok90!lpkFssc#OZMyBtHgjY#sw#jJ{bdFo
> >
> zEl_dN!p1eg>`QgApm9UFcLt<DQqO_nwbMDBFE5EuOycH&O+b5**g2nYif@
> _
> > WU=oCY
> > ztPVM?SE5n-
> > %je^bwGL!$EMTHmlQyX<V6TdF(x|1}83J_40k^RQ{Vk_4feJI)AtGt@
> > zS?_M)x_`d7C2==i&N2{udDXTI5$woRV0X>G`k<!OX`F>4>#o#-
> > FuEgVqE{0iWQVnY
> >
> zhqZ6<W?No0B86NnNY%RKQ|Q%WJTWs8dG^9q3@MgOx?mz!&8c(oP?0$q
> Y
> > Gdfag<R9a
> > z$Cg?^ng-
> > 4i_J(V1p1|Hx@!aq}JkEMuHSl0>nV;*PkXQ#UcN0;(T2%$Za_a6tMMfBa
> > z4yl1(${xf7Q-)}Dq0%i_{-
> hqPiP@hD&ekWXG5IRKn6@=c{eqRfAo{2oFEp8=;*Bcc
> >
> zwC3WGs!#9ozM%0<RJfEaVpoI91MLY3h{)L&q(EK7+rYc+E!94#CLgi4&Ch=t3{i
> G
> > U
> > zYpXR+bykxDWc4RQAzr9Op*-xSQY0Z*z{EX5+UhKoiyE-~$H-!lLq|vF6&)4=-
> > exwc
> >
> z;K<@!w%hmurO+Nqe)v$*q?qzS$XZ*_t}?_0!{?C+XRDj3N|=Dw%Z$XWAl4Snl
> > +HlT
> > zi!n}S?L0sklHc^Dr7{8l1r5U+3x5kfOKIY)XE*6iC+e$`fMjcz)U40lRO23O`*yax
> > z9=LeY6PvX-
> GD|(4b}x**AY4)Sli!_6;Yh4}Nw$I$N=Sdc&B`X7I>FvDzSAo<&=JjV
> >
> zb19cwyLPu4m$!i~%P1`l)#;v^^)But{TyD!{ASqI0RST!DV7N7R`Ny863=k0c4R5o
> >
> z;vMxEyUTvVbn^=Z)4B=T8noNrHtlt;v%9k1@akU7cjWWC(ZJw_nVTn;>nibBw
> V
> > Gnp
> > z-
> >
> %e&0glC<*9;1>1+tUV1c2v|1pt9u>+risd+O+9QYaH3>4==9oCbRisv6#>9Z?Dcz
> >
> zd(v*W>a55cANeQR+_!Wel}pG2{9R)y4Bw@2BSBb!j`ARY9V;=?VsGqyp}QPZIa
> h
> > 0x
> > zTs>*0H#i**&xXUnNiWlS$`vx#Vu`r4YG&K9bVrR)dC<#nv%$$SyG;wqnM-
> > 2w>zanQ
> > z0NAF8`MK_?&5#!GOoht^(w1l1!rAq8tLZkL&6=GX6J<-
> > Se_J#JLLAnb8E&y!!P&Bq
> >
> znZ2+pLpnyX&|2<>qDF3oke~V%7;`Et<JZ~~a=kKgW9q9YpV;i6du^5_5BzI=u6
> w
> > ;3
> > zL%J3_a^bDZ1^%07p-
> > F>vq?PBy%Kb>4RTrDD5^(jWoeMR`g_?X*kgXnI`zKa#e?7B|
> >
> z`UaRiJuL)nkS?c={Lu{)H&meogim9o*5>u=;%eJ1);i_{=^+OE8ybj@_2dC|g~qgY
> > z18UkAJ1Mxn$+D~QEuFHuRWL{{P=hfB3-
> > M%fMWM&ycDpfyJw2M!k7O7WIMglkbKS6f
> >
> zM31~1YD}%cB~VMGQ>J?EeygcfHE#kvhj~0YUD0u5dYZCg4J}F16Dz_F0b>zM
> Y
> > J#!X
> > zGc!no^YyKpkYw_EfWBX<Z(R@6%)Ll4-qaA4^9WNz3{9OL=TPA(W{tI|;i_*-
> > %Ry2j
> >
> z=#~%FK+9vWDcvhVw*?%sR$>u%rq_e4TRT@ClumkF)8!ygNUmb=ZGmi~miY
> > %XAtbzu
> > zKOzJt8g}4IH9PGQX}e{{&{!@95Q-`5xsa8hL&|c0rHu{K`Rrn5-
> Y`+FHO2C}HlLuX
> > z6%4sOD>^@9f<#qa-
> > H8?Z!A2B|7Ne<?Te}U#Oh)tc`U9G&UWXjNueL}AEX5dHd&Q0+
> > z>wJFMYy!F$Go?@ct8zk`<8=5dGr<8-
> Sxq)LTK#L4uIZZq>lg%{nf?T|oNp0tSeJ4`
> > z6GW1vSHmmj#@i05)$Cg2>Bkz<{^iuz+|#|c>mWZu-
> > }cPfFT<fytR@$=hCMyKu`{dT
> > z)fp!eL?E=bTJI8_Q_I)XlDf1;{{mL4`R&Dt4r!(Rv)fr6Hy}}WD_?V4+MDIAe0s-_
> > zb+MdYpBXI4PDb~&+<?hBX*~4UL27;zF?Cbt#=%@USB+-
> > 0!?y;Tb9;Gq(hVWeH0$<<
> >
> zqnoKuS_@_P&vUQ?^LvbFTtF<JPjIn8Cv>bd>kZDX?q;^#z;}w7ib?AERxy@Sgs;
> 1
> > y
> >
> zv#nH+Dm%Ab4Bwt&HJ`$q!R6&>ba{1iKbhAz1YT%kL+eo8=YChMvhdi4HZ13
> py
> > Blo7
> > z<>mG5{d7?)-B7-
> > mO6jn^2F_z0TcB>t6Uj+}?5ts$IkYHWt@6CafXAk99jVx&A<acQ
> > z)|!)u7@p;>4Yo@dOBVOic0l-A&-
> > wCLU^8y)srA9K30dQbh0~$Ape`cW@@)2`jxK8^
> >
> zY#wPvHCrMci{)~$AyCH{a^@pm`xaM5P`XfQ1}C@m3OFL$e3r9?F<W4Gn4+)
> > @Xj9*B
> >
> z#vh+9Z}hn9M6E=J0rMVCi=kTiiV37g?@G($X7p)^l}hzH44vCU8SE|Pi%ah7VB
> O
> > Y4
> >
> z(Y$TKzJ<J=gNJ^gBA_sfu}}9Z=354HEKK*k*S!&$B(%S5KF_V06KimjU+smdwE?
> G
> > g
> >
> zgdpm?(O%cKDWC4sWA<tteL1ZS8q{JQAFM=bj{|J2N93s?wEmXoYT6f&Frpd|
> c-
> > T!u
> >
> ziY5O_c}uj8QS9VyM?+Yct5nP{S?!(6X?_!#tzrwL>F*>WhR1#kQn!PdHjbvEG>E
> g
> > 6
> >
> za&cUBIx7Ui7Nd5UG?cPdOsvfXtY_O>k;TDR=r**Z#iOn{fh_3HFQG@7fUP~|*
> N
> > yv3
> > zm|*nHp<L60_?QgY)~+u%#DO&~N57Ny&1rSc0&-
> > Q%YU02qI}S3}mKsA$V2IT#(%waT
> > zM}Bc>r(PbN=FJskC)cgr_hNEx<?=!Wa<f{;!UIk2=zK+l&cEGIwlV9Sx3Y>kM6-
> 4H
> >
> zw}kS%zn%W5Rj*p!4(paHTDzry@i<V6jSX~=AvXB5dkPaAu0PcM$!Ax?7t0Oo3
> > y|4f
> > zJKYo-
> > wVK#@?yf6Ydzq`?_#U0kPHI`!4dXif)4Hv2U@CNSb=I$u@;y*I@T+O}<m`G<
> > z6OYD42dBN-
> > u!rgB?((s)+BT)uun@ero7#M<PVe;m@)jcOc{wa8^5uMb2MPQAj+n8j
> >
> zt@e2zq%dIviwz*cUbdkqR<P9%%<2r9q`PKPNbF?3U)$2583E1jPa9NXr+0EXJc
> > p@|
> >
> z>+9>Q%hCDS=}GSc;YCTUw9_A)o?VQt$~Fv7s~NVkjQH)^(R(>jA>P{d(sr`!9R@
> k
> > <
> >
> zG|f7lEUQ~N!3)38t2A?MXp!p&{<7(vEo<E3og190wYuK0Ev{;H*3NZ(xG!d>#tu
> b
> > 5
> > zsDrsyku<3hdq<Y!cf(rC7T^B=<E&c~aLKP4)cUTZN$aLLU|{!QSm<3_-
> txV)Uqd1J
> > zz2lbfHWf>4)d(UoIn#47o1p#OJ@1^^`QebEeFW)1^3_TR?9hGkK^yG-
> > J4aSy$f36$
> >
> ziygp_`taxKx_0sD{*8U{5Ympd4AOZ#Ir#$j;oD(5*REpVNDGJX@F=|ih%jC*hrN
> y
> > z
> > z<j)bM!!`WO*dMp7KEES-
> IlllhJrN2u(F;eFV=vrJlA+p?u4D(~=jGGO|KElqo%34R
> >
> zfS7B;zVip_E$Kj~&qt1|^X25yNTfbc<u46PI=GsZ(JexR@^o?NQMuKA2njSMlN
> 7
> > 7P
> > z^ycE^1B+ByE!}Vr6Wtrq!(r*c4y&g()M-Ah37M6>0)F%5Vs>{kIv);TC;D!gA8rEs
> > zFmI-P*!ySRoKvH-d5_iBY&apruQ@I9)nYN5&8E}I-
> AJw(Iu>R}hnse~C&P;?48zyC
> >
> zRGuEIYmw=EOw`hW@gdS0zQAo<Z1jPLR62tTSaEQ5eS0^Vl3AVFHZMj`JLd*#
> 0
> > Bdov
> >
> z9*EC09<#F?1NQ07bcxF*ie{lGTV71mx}0NRMPa6=w`QcjL`nXx)KV1+?PZ^DoB
> z
> > JN
> >
> zc|u)Pk*+(6d)Q0r8`o+Xa0Te4pXiSk7|n~fis>_~gLE_;)GsrQ=v8MQtbp{kQO(8T
> > zw%v{h$LNLdxv`oYjEW2K<RBX-
> > AEOl;U}opB4I9rkE?nPG*}jiE=aUVNU)2P@clN#&
> >
> zKi&K0*ITPru@lHFYu*as39#;5wB!i;?9~$>cBm@UX8;)s$VIWZc@g8R>}=8y#H
> k
> > SG
> > zn`a-2TE~aeYv)H6>f@2eN3E`gba1;_YduA9tq#F`?ziK|>REi;`gV0Lrj237_3GI*
> >
> zYd!LfPr5CFLoYC=BhC7a1CmyoV>c4!nI2}NO6A%o`Q6#ejAmz@{`pPKUP^~p8
> u
> > UyI
> >
> zX;fH{=>C#3k~7#|`{H`C5GxMaeAMxosJ*$`^sFXoRV?l<26bydHp6|Y62Oy_!TIP
> > 4
> > zwqJ2O(J!Xg#`iLw3Y!DelNp=!uI6`Far>eJRB~hxu)$Kd-
> #<ASz|sHE)8(?^UDz%F
> >
> zXLVrB!PUiwm#lwehCeO%9!x@A!K#T1ST+HZo_~i^o=;29{cD3o2Os#diT!Et3g
> M
> > Lk
> > TuM~Ktz$*n_Dey{xHWc`O(cS1K
> >
> > literal 0
> > HcmV?d00001
> >
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> o.id
> > f
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> o.i
> > df
> > new file mode 100644
> > index 0000000000..1f79332020
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> o.i
> > df
> > @@ -0,0 +1,10 @@
> > +// /** @file
> > +// Platform Logo image definition file.
> > +//
> > +// Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
> > +//
> > +// SPDX-License-Identifier: BSD-2-Clause-Patent
> > +//
> > +// **/
> > +
> > +#image IMG_LOGO Logo.bmp
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> o.in
> > f
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> o.i
> > nf
> > new file mode 100644
> > index 0000000000..3380f3c1d5
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> o.i
> > nf
> > @@ -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. <BR>
> > +#
> > +# 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/Log
> o.u
> > ni
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> o.u
> > ni
> > new file mode 100644
> > index 0000000000..9d1bbaffa9
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> o.u
> > ni
> > @@ -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.<BR>
> > +//
> > +// 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/Log
> oD
> > xe.inf
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> oD
> > xe.inf
> > new file mode 100644
> > index 0000000000..01102b138f
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> oD
> > xe.inf
> > @@ -0,0 +1,55 @@
> > +## @file
> > +# The default logo bitmap picture shown on setup screen.
> > +#
> > +# Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved. <BR>
> > +#
> > +# 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/Log
> oD
> > xe.uni
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> oD
> > xe.uni
> > new file mode 100644
> > index 0000000000..9635701b60
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> oD
> > xe.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.<BR>
> > +//
> > +// 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/Log
> oD
> > xeExtra.uni
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> oD
> > xeExtra.uni
> > new file mode 100644
> > index 0000000000..c6ea34b81d
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> oD
> > xeExtra.uni
> > @@ -0,0 +1,14 @@
> > +// /** @file
> > +// Logo Localized Strings and Content
> > +//
> > +// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> > +//
> > +// 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/Log
> oEx
> > tra.uni
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> oEx
> > tra.uni
> > new file mode 100644
> > index 0000000000..041179fb75
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> oEx
> > tra.uni
> > @@ -0,0 +1,14 @@
> > +// /** @file
> > +// Logo Localized Strings and Content
> > +//
> > +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
> > +//
> > +// 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/BasePciLi
> bCf
> > 8/DxePciLibX58Ich10.inf
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLi
> bCf
> > 8/DxePciLibX58Ich10.inf
> > new file mode 100644
> > index 0000000000..e5ca95e20e
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLi
> bCf
> > 8/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. <BR>
> > +#
> > +# 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/Acpi
> Ta
> > bles/AcpiPlatform.h
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/AcpiPlatform.h
> > new file mode 100644
> > index 0000000000..2deb2a88eb
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/AcpiPlatform.h
> > @@ -0,0 +1,45 @@
> > +/** @file
> > + This is an implementation of the ACPI platform driver.
> > +
> > + Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +#ifndef _ACPI_PLATFORM_H_
> > +#define _ACPI_PLATFORM_H_
> > +
> > +//
> > +// Statements that include other header files
> > +//
> > +
> > +#include <Base.h>
> > +#include <Uefi.h>
> > +#include <IndustryStandard/Pci30.h>
> > +#include <IndustryStandard/Acpi.h>
> > +#include <IndustryStandard/HighPrecisionEventTimerTable.h>
> > +#include
> > <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
> > +#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
> > +#include <Register/Hpet.h>
> > +#include <Guid/EventGroup.h>
> > +#include <Guid/GlobalVariable.h>
> > +#include <Library/UefiLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/UefiRuntimeServicesTableLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/BaseLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/IoLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Library/BoardAcpiTableLib.h>
> > +#include <Library/MemoryAllocationLib.h>
> > +#include <Library/AslUpdateLib.h>
> > +#include <Library/PciSegmentInfoLib.h>
> > +
> > +#include <Protocol/AcpiTable.h>
> > +#include <Protocol/MpService.h>
> > +#include <Protocol/PciIo.h>
> > +
> > +#include <Register/Cpuid.h>
> > +
> > +#endif
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/AcpiPlatform.inf
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/AcpiPlatform.inf
> > new file mode 100644
> > index 0000000000..b4b52b6622
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/AcpiPlatform.inf
> > @@ -0,0 +1,105 @@
> > +## @file
> > +# Component information file for AcpiPlatform module
> > +#
> > +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> > +#
> > +# 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/
> Qe
> > mu.h
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Qe
> > mu.h
> > new file mode 100644
> > index 0000000000..f6ef44a14f
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Qe
> > mu.h
> > @@ -0,0 +1,507 @@
> > +/** @file
> > + QEMU Video Controller Driver
> > +
> > + Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +//
> > +// QEMU Video Controller Driver
> > +//
> > +
> > +#ifndef _QEMU_H_
> > +#define _QEMU_H_
> > +
> > +
> > +#include <Uefi.h>
> > +#include <Protocol/GraphicsOutput.h>
> > +#include <Protocol/PciIo.h>
> > +#include <Protocol/DriverSupportedEfiVersion.h>
> > +#include <Protocol/DevicePath.h>
> > +
> > +#include <Library/DebugLib.h>
> > +#include <Library/UefiDriverEntryPoint.h>
> > +#include <Library/UefiLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Library/MemoryAllocationLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/DevicePathLib.h>
> > +#include <Library/TimerLib.h>
> > +#include <Library/FrameBufferBltLib.h>
> > +
> > +#include <IndustryStandard/Pci.h>
> > +#include <IndustryStandard/Acpi.h>
> > +
> > +#include <Library/S3BootScriptLib.h>
> > +
> > +//
> > +// 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/
> Qe
> > muVideoDxe.inf
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Qe
> > muVideoDxe.inf
> > new file mode 100644
> > index 0000000000..8370559016
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Qe
> > muVideoDxe.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. <BR>
> > +#
> > +# 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/
> Vb
> > eShim.asm
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Vb
> > eShim.asm
> > new file mode 100644
> > index 0000000000..cb2a60d827
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Vb
> > eShim.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.<BR>
> > +;
> > +; 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/
> Vb
> > eShim.h
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Vb
> > eShim.h
> > new file mode 100644
> > index 0000000000..cc9b6e14cd
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Vb
> > eShim.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/
> Vb
> > eShim.sh
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Vb
> > eShim.sh
> > new file mode 100644
> > index 0000000000..7669f8a219
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Vb
> > eShim.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.<BR>
> > +#
> > +# 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/8259Interr
> u
> > ptControllerDxe/8259.h
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Inter
> ru
> > ptControllerDxe/8259.h
> > new file mode 100644
> > index 0000000000..a9673f9c87
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Inter
> ru
> > ptControllerDxe/8259.h
> > @@ -0,0 +1,218 @@
> > +/** @file
> > + Driver implementing the Tiano Legacy 8259 Protocol
> > +
> > +Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR>
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef _8259_H__
> > +#define _8259_H__
> > +
> > +#include <Protocol/Legacy8259.h>
> > +#include <Protocol/PciIo.h>
> > +
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/IoLib.h>
> > +#include <Library/BaseLib.h>
> > +#include <Library/PcdLib.h>
> > +
> > +#include <IndustryStandard/Pci.h>
> > +
> > +// 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/8259Interr
> u
> > ptControllerDxe/8259.inf
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Inter
> ru
> > ptControllerDxe/8259.inf
> > new file mode 100644
> > index 0000000000..e66b21c914
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Inter
> ru
> > ptControllerDxe/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.<BR>
> > +# 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/8259Interr
> u
> > ptControllerDxe/Legacy8259.uni
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Inter
> ru
> > ptControllerDxe/Legacy8259.uni
> > new file mode 100644
> > index 0000000000..d035292419
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Inter
> ru
> > ptControllerDxe/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.<BR>
> > +//
> > +// 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/8259Interr
> u
> > ptControllerDxe/Legacy8259Extra.uni
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Inter
> ru
> > ptControllerDxe/Legacy8259Extra.uni
> > new file mode 100644
> > index 0000000000..ee43f6923c
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Inter
> ru
> > ptControllerDxe/Legacy8259Extra.uni
> > @@ -0,0 +1,14 @@
> > +// /** @file
> > +// Legacy8259 Localized Strings and Content
> > +//
> > +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
> > +//
> > +// 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
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#46381): https://edk2.groups.io/g/devel/message/46381
Mute This Topic: https://groups.io/mt/32816099/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
Hi David,
Here are my comments:
1. All of the copyright years need to be updated to 2019.
2. Please remove " Contributed-under: TianoCore Contribution Agreement 1.0" from your commit message as it is no longer needed.
3. Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib - This library is not an override. It is an alternate and separate implementation. MdeModulePkg does not even have a PciHostBridgeLib implementation other than a stub version. This implementation also appears very similar to the one in OvmfPkg. Please move this to SimicsOpenBoardPkg/Library.
4. Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib - This library is not an override. It is an alternate and separate implementation. MdeModulePkg does not even have a PlatformBootManagerLib implementation other than a stub version. This implementation also appears very similar to the one in OvmfPkg. Please move this to SimicsOpenBoardPkg/Library.
5. Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables - This override is just coding style fixes. Do not add this as an override. Submit a separate patch series for the style cleanup directly on MinPlatformPkg.
6. Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe - Why does this override exist? It does not change anything.
Other than that, looks good! Please send an updated patch.
Thanks,
Nate
-----Original Message-----
From: Wei, David Y
Sent: Friday, August 9, 2019 3:47 PM
To: devel@edk2.groups.io
Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince <prince.agyeman@intel.com>; Kubacki, Michael A <michael.a.kubacki@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform
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 <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Agyeman Prince <prince.agyeman@intel.com>
Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../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.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiDxe.h>
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/X58Ich10.h>
+
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Protocol/PciRootBridgeIo.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PciHostBridgeLib.h>
+#include <Library/PciLib.h>
+#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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BdsPlatform.h"
+#include <Guid/RootBridgesConnectedEventGroup.h>
+#include <Protocol/FirmwareVolume2.h>
+
+#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"<unavailable>" : 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"<failed to convert>";
+ 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. <BR>
+
+ 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/HiiImageEx.h>
+#include <Protocol/PlatformLogo.h>
+#include <Protocol/HiiPackageList.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+
+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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+
+#include <IndustryStandard/X58Ich10.h>
+
+#include <Library/PciLib.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/PciExpressLib.h>
+#include <Library/PcdLib.h>
+
+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. <BR>
+
+ 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; Index<MAX_CPU_NUM; Index++) {
+ DEBUG ((EFI_D_ERROR, " %02d 0x%02X 0x%02X %d 0x%02X %d\n",
+ Index, mCpuApicIdOrderTable[Index].AcpiProcessorId,
+ mCpuApicIdOrderTable[Index].ApicId,
+ mCpuApicIdOrderTable[Index].Flags,
+ mCpuApicIdOrderTable[Index].SwProcApicId,
+ mCpuApicIdOrderTable[Index].SocketNum));
+ }
+}
+
+EFI_STATUS
+AppendCpuMapTableEntry (
+ IN VOID *ApicPtr,
+ IN UINT32 LocalApicCounter
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE *LocalApicPtr;
+ EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE *LocalX2ApicPtr;
+ UINT8 Type;
+
+ Status = EFI_SUCCESS;
+ Type = ((ACPI_APIC_STRUCTURE_PTR *)ApicPtr)->AcpiApicCommon.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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+
+#include <IndustryStandard/Acpi.h>
+
+//
+// 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include <IndustryStandard/Acpi.h>
+
+//
+// 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/HighPrecisionEventTimerTable.h>
+
+//
+// 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
+#include <Library/PcdLib.h>
+
+//
+// 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. <BR>
+
+ 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "Qemu.h"
+#include <IndustryStandard/Acpi.h>
+
+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. <BR>
+
+ 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. <BR>
+
+ 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. <BR>
+
+ 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:
+ <http://www.cs.cmu.edu/~ralf/files.html>
+ <http://www.ctyme.com/rbrown.htm>
+
+ Copyright (C) 2014, Red Hat, Inc.
+ Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <IndustryStandard/LegacyVgaBios.h>
+#include <Library/DebugLib.h>
+#include <Library/PciLib.h>
+#include <Library/PrintLib.h>
+#include <SimicsPlatforms.h>
+
+#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. <BR>
+
+ 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. <BR>
+
+ 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. <BR>
+#
+# 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
+#define _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
+
+
+#include <PiDxe.h>
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/SmBios.h>
+#include <IndustryStandard/PeImage.h>
+
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/UefiBootManagerLib.h>
+#include <Library/BootLogoLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/NvVarsFileLib.h>
+
+#include <Protocol/Decompress.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/SimpleFileSystem.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/S3SaveState.h>
+#include <Protocol/DxeSmmReadyToLock.h>
+#include <Protocol/LoadedImage.h>
+
+#include <Guid/Acpi.h>
+#include <Guid/SmBios.h>
+#include <Guid/Mps.h>
+#include <Guid/HobList.h>
+#include <Guid/GlobalVariable.h>
+#include <Guid/EventGroup.h>
+
+#include <SimicsPlatforms.h>
+
+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. <BR>
+#
+# 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
zcmeHwJ9Hz-kzh@gFoN)Qu|weq&F~F*XbyPdaEHTfE*dKcjU5ohf-&!%BU8pXGG)q?
zD^tc9GS`(UQ>MIoGG)r#cb?2OW$Gd_vnu0Pg~E?y>sT{Q)F&%4G9u%Xk&#)e|2h0&
zn&2`0PLf>1@BjWNN&Xl7`zYzU`~UYcP5w_masS+n@=v#$bm8A8pL~*ZKm9cM6#l(=
z^C_Iaf!{aDCtrS<d<p+Pc?<u(e4D(*e{bKy^(^^xHcMvkZ-xI>tK`$wx5>BPew+N{
zCqGF({r0EHo1gqN`6>SUDV+cGXUUiF?`J>zS@QFr|2+Bf=f6mP@rz$1Z-4R2<d?tv
zW%A`Oeg)^hN`Cb#`2FRtlefS6b@J<9|2p~dSHDSq^PAr!Z-4zC$qfGe$A7@@Z+@Hn
z_P4)H-u~uyaQ?gGcfW(*-~K-N{qKLDtbX^0<PU%NLo)l_AL0Cu$shj+zrX)e@~1!j
zDf#vfe@_1V=RYT_KmKR(E&Th>|AgN^{U!O!U;dK(*MI$2^6j7hn*8;ze@*`Ox4)It
zdHsE*z$*n_Dey{xR|>pR;FSWe6nLe;D+OLD@JfMK3cOO_l>)C6c%=ZLK$`j}9J%#+
z`g{~f-@JKc$n%k3)||b2c=-M+LnK+A>$>;;@$vEfKfY?L=VAb__wxr}$K&JI&mkaS
zw~kS*1G~9@9j0;vimRVfxy_Y(?c(tf7y|!~-77nSYEzvqlcpIQf^ZIl@W;O*3M7fT
z!9kZ0_+7Z-@1+@3FK$(@q_Qx*CNCLHfLrh%DN_M$JaLeE@0@S|JKldEOG8tTLJSzc
zYJ|Dn!`@e*DIXr+U-e-^H5^DwWD+9bE5=`ek8z`XKS_FDqrkua>L0^f)%(?nEBo=A
z_fYpY?}i^&&`AMu>PnMqa+)M3U!$^re1FlY5cqf;0Cy_D)w70^J`w{D#QyQ|9Rf@{
z8kVb`(W3$AHjlEeUB&Ltb>`mu&NuNEoIQM&cK+Snc~b#~A`kH2n~2dD(13?{J;ulG
z|Id&fV>kskN%9G{)3wsUdQ;W(-n%jm@Z%%a^j$>b;a#Vy<Dc-|$FJd0z%bzRz4!P4
z{sCjp0*YfS>J9)L?rr`_zY37>O@Q{_-78}U2meqcS?f20ZdoD)$&5I7LUsP#5!2mA
zEIv!W^NqXXbtyvT1i?FFELrj6Q@p|h8in*2V;#tu|Ax1|Dk=1pD}m+Uwxe4Bj5U1+
zJNV<fsLOyKaN}*L9!@<z9mh8h<ni$wkx9P7lK%h4Z%*B<7Jsrp4EO5e<5xcS!ohMF
zJ_0O6y=;Bij258V7V**nn0p+qQDwP~>Dq?`cmO&E`M9W{0!H{GGAQ{1E-QX`E<5s}
zixRkn@-arZCEI?0@4(@!dEW!@f%90CZ#9t*CtDBKkZs|re|+@#d>x=TP>&8u37Fif
zP;WRXRfWgu@yZqbfd>-qeS<tg%t&h+Aa47}cR8#P>jS!=`3l7Lc);J!$~z?;OIihj
zxJtjk;$;D^S?~^kMG7IeoW6RCcaSk~q(8<IzH0o9OmK=1x&^#M_~DWL3Z%@l%Bx4@
zQb6AQ0u=1$cz8ZPP&8e|HGe+wWG;a{KAZ!dmCOWS0ZA+r)prfR?Qf3}ZHIRt%l`lv
zzO}JApCzUJ@O1P=5WkZCa0l!MTn7vs`QQIzf_!;+1fA~c0XAemf*X$MP!igY&BDW#
zd-rkbYJv*{4EhQVuCL$*Dm%m{luAOUt{}bp7>!hUi69=~R-0q&3OmUD4Bta0ky`-E
zBMCQ&c4z~>MVXJ@dBmalpL?R*f<qBnTQ#X(J_tX?h<1tLTfD%Bj#$v8##j&Vqk}Yl
z@AY!xHNnH@N%pU<a<nu~HUmE#yNG;vNkH|7S}oL&{>V4s^ECYzID`MbpMsHs!vn@!
z&V+3w2Pj#D`tZXJ_M-sGAqlrXPlBcONaEABVz;s4SiqS=@9#jn@OTgGC#?-dgT$2G
z--!^SMEK$C2MRMB*}oyW&Rm32W4K0r<wWA0cjG*hKmZaaM^HJ~Vp3Cse}#_#BI4uv
z?}PKYf)sz2zQKnMuroQOk$1S&{|Qw)?8fju9MHeU6|8@9k`j?5-ef({?Vfmz{NTul
z6~lkvK)7~A<pUsHuchXjkS)~s1>zt017ZiRi1VxPE@+rB{(^ty{I0;Y<X_;P2a4d3
zzTPsx848;6ue=%x{w`7+O9gX_Fu@+d-G_0CQt1Jgj02h4c>L1?!h9HEL8Lugef_t;
zp{PGRq8g8|BDz@ifQQ!rNT?+7E-FwFyj#SjQa(^$Ab&|ne*?-yfnolYlQqW=01AB<
z`2nRtKFVKgL(mTh)C&}X`>xkSc+-}ThiiC5@cGo?>P&AiC2xWXLl_@<ZAS2fn>B~y
zEP9hpAtG3)%foU#Ho^kTkU&H`)PUUf_74!O_alHGC?AjDQv~}Fsb9)RL?Ea%Qe=$y
zhXSsny77dg7WC*bJj9k_&vlFfOrd>PIjS`$P>+v5YSQ(Be8ll!kPo0&7$ISGu3jg5
zXsxgbZ_sH7fPv9?AP+Yl!AUOpf$xFw@~#>p8DWL)(2C0&tEB~kMLm!50Ugba{s5Us
z{jxvCJA`Zj-WP~}DDcsbfH{urt^(i(j^2?UIN(APg@+Rg<Px4DH&KuPFrJR#rf;?B
zU-?Il{bQ^byA-_PT`lAX@&y408LS4N0a^3MwID!3+5?Pt9q;bCP7`5;K~m|xn9z2*
z>AQp%c031C0MSbO0qqHgqY^dWo@^!kv6Qptfgi3X1$_k|p?4zHpiv*AdsRkDKJvp4
zCm;S4$mS{S0Q*XVe}%Ys?dtt2B$q2SM)p<m;qHcx>;OAaaYNG3l=>gnf&eMdp2>%o
z=g?`O9Y^r5u=@fRaNGm>3J*Lli5*cdsZ`zZu8ix(;hvL#HxLPh>lAxe&{qJ{*>j-T
zxp#cZ&g$A6<iop~AV{7GB|qS0Cm%j|=!XJm&x4gg_WNFq-6+ThAcfEZU}xf;_f_Fu
zcj6*&ffzxTI(}$a&VJDDSqF04`;~k^V}kt%@&V){;uxqD?;wMq2+^Qppxxuh6E6KR
zJo^TR`e2}fJ;%pzH=2)NKVbCl)CxWd_5;oku&)D1;=FPgmV0jy`9Z251JJTdy~Wyq
zmtH6;zz^;0#~4uv^5JwTigFn02i=EN5hSti9rSSO-H;DQIAW}^{cyxP!JbD3d3}ZN
zfu3>%iSkkUSMU%B1_L+W2G?fj#&8u}NoPMCO%bpc0?=+K7Y}~e4JT-u0UxXixi*Gh
zIGlXAVJO)1f5UnLVAmAXaT^aO;V4#6*vZF3u;&2GBU!=<_5-pV%C>9--mZXie*!<6
z><6ePY@xE}kwK;20D^trTk6uDd-;H-I6}j3nY4jg4Jiqz_FYR+BAt^PLs>wQ%xgJd
zuaCaq3@Yg#m6nMlC-M;iZzf34d`@{+@&UT97RiyDq}mL)eTmB7g~n9&qa1%k>X+@0
zcN~L|v{hZf8oJ;_91jwI*R>1&c*9b?=T1I#{CK$doA3Fa^Iix*K76-7`y2AZhl_)F
zV)bLZ7vzHj#VZ61{a}RWn-1Rs@HzmhX9EppR<NKCVs~(WK^wdqVOaV=2iI4w0|Ppt
zIwy`^BB_8n5%nFE+Vim|sk0j(?EnkM=Z?wf@8XTm(ykMU(x6w32r*QA!#fI&(Y}s%
z8JG`j{I%nUleUr|jvrWW&@vUk@+4?~he~;`_IK<^?429bS8y4eJNHTn%Lg#9*7CTH
zvy!#I+dZi4ITWwt!;Q9}E-#LbA)Yjk7k)|_=v=X^s>ew?VhMH}q}|yOjAp>C;O~NF
z#yA9O<?1bWQch96hj1!!U7!wN;=4}JIqyD>^5IJP;pZ5tf&&e%Iy_*QiUz=&53jF0
zKcc=W-=nYsIgn-8;)nM=tM>BEEq+lx0HzyEMf>5ZgNm>&-%{+g{t9lO2Z{q^IHbM`
z*G@jd_yb-H_8bRQuKSk*!hmQg9d48mnp*l-*hR;_(GTAb;}3X^lo~rkeG_=gQvmFd
zRszWjhAU^!12IrO0P{*dI4txuT(wvTk9HN9wX&Oa@)6pBRUs9z{jO#B2apT|0W}|?
zx!x77g?xYoeuJO@k^{u}k%mMkCs-KkcTFw*D-<T2)WzyQ13`fw?_VJ%&Lj7|+IvM2
z8$1hu(W3DOHCG4;tHHjGEr9ci9~@Rts;<04<eNba%q?$69fkVJH8<D~#0F79&0O_I
zk1z(LgTN4fcZ_8NKb(9-`vJYjJq1WXJ|dcFIfWix4m}?oH-Gx>AH4AdLyq#{`yxJq
z3oJFpli(sous~4&?4EeHm_DjGuOLB#-H@`94++clDgch~-QR~%4a_ZXoBkCN&DZ3r
zLx0rWDes|tkT7hh()H88A0i*fC8w_dRwW<NBk4eD2*QPbo|mDisQBFJ<GTTtz+&%C
zTsa&|c>Ceh<rrRt|D9JvT91IkL4=qT(5IEYf=6Co1^EcD5MYHQ!UiP2hn@=@IBR%-
zqp}|WtFj-y6GJ`zKja7YM?Bmeln-~qyQKjQ=Picuh?5VeC7b|K`+<O>zAE9u%|Nwq
zC-4Jme0K&9zj*_#et6@sD97h`1Bft&$8hRQV5CTJh>=)ChU0VV%=M_?sZo7pB8il!
zkfcqrAh*6}+mGPgx`sl}189H}BH)j}54=Q-!r@vIu8DjAsi=Ioj$OGsp%+4tO2xaH
zJa;@A@7_U0@B0`S{^0}GNyq2N54<P+-O@J=MybTH`PcQRAZcOR1MP=bT~Gx>5=r5@
zkjrj)I8fd-%17C`VCV#OVn=gIzUr~qh_csK4RSY_d;ndlYaC7aVc!^Gdi&u#13!OW
z>MQpSV(@jC!L0-jJGHO$Jr0n+c2gVgoL7OqjDO^YKdv80eFcF15dl}I*Pe{sD?k7!
z5mH}}AO1Exi?Bk6b&}`ncg|!j<kk<Ue0bheN}kTnmhurr9|(d?*7D&5#s@4=uv}xH
z6kzQ<12?5q%15B;<2Rp2goEuu#RszFDuKTj<+Lo4#qq;+9<1JRT*wE$iSJUtWfh-5
zYAM*GfBm$)QT>Abz&1HcgflqsAMgWu5ZvXkLWgzQ+0_rCbC5_DlMk%bIV!X|kFBR1
zizm7UGkyU6V~nr?kub~3X?K_*a#G{4K2QCisvHlxU<y$KSeL7*Qq4#o_y?`^u`9gt
z@pgFNCD>bGZqHp3qyX$2@~O)q!gn7Ovs_On_5%t5KYXrA)Kw*tfR=0h7;!`leFgjd
z4HR)*!k?qKx;|PdpMU`Nmq`9nK4SH*HHaGG<}M)F)eo&fP{!^FfI#fO3U8GJ@RyE}
zUJ`v%LnnY2z<Wud!}_DLA6|mT?yegpIXKuI+&!Qy1?<kDTYNMA2RQxi7(~crlK3+C
zx3V8_j+PB71bzT4#G1kKt@qI)Yy=cIkbFR$0PF&pTggh$&V>5<j-wS*X-?W5y?t*+
z^5G@uhAy<#pTa%35!!~+t5C{iV1mYWhxhGD`EcN%2$~F^=K(K7`{Cr(QSkxhx?BhK
zP<#d{2aFVlA<0*jrTY9EAUEDEk1=8w^c8p{NE+aW8;x2>9z#AVn*ohM`2ZaJpbbx>
zG*rE|M7_Kb{9C;3I=gES_)5-k0$}byaR^Uc4Q02CNerd@0I7Y~b9FnOBLvs^$Bub$
z75GtN2>0>8QLFd09>41N&W(cPMa8}2T1dwt;EN-y>hPM+OPY`GqI~=aiQ=5P2+JWE
z2sFmp52df1Jr61~%15vt1a~D4;RazD_EY~K`mVuIz_vJ7wtNbx|ELV^1)YHTxPg*j
zsy!2&D!@~uh4<7#HX8a`rGMqPR#6e5xEH<--mY6}Hg>%NeE`ho0)ZI2=pyjqGw39h
zn~hBQ!dK@w>v4lgFvl2l*)@{h-^Kc&-G{LsOg@mB&YlAy@H~1`Wv`9m;EDu^#kN!u
zfb_#~5i}0L0Xv*_!b?0J-bKF#@)@v%Zz?`RQio6-_JvRfYVq>Qm5&$L9mc*MFCPxz
zS1yiN(y#>V6f)of{DAElzd<7gfqW_;6=$IWudgt4>gB_Cni5t((h&&ihvPu@Japq=
z&mCm1ukbWdpK5hL77pyY(0C$3{(k)XJ($dffm~Qa5%0${udguri&VnWpkW+fU^Ltd
zr!GDWmwr~N8V^EoS89we2CYAKr(bpaoSvg~1sDOKrW`-K?*e3}G{0t%czhdxxdkLn
z;X?2E*tzb=TLVe&?_&Md92>l_^-;+Oyb0$38r3JDi}FE~k-J01A>1G$v~}HRWUwuj
zd^mL;>PEofG}s1^I4{6hK6rpw%2Uy6eV>2zwHuBKz$sSeE!q2C$%h}XeqDA>Y)NPz
z*bgDZ6iG)QtRKjBD1C(#@x~DCxj!%M2lfen0D8!+$f0n9h)`Ly{jblz^77$5BIt#o
zZUpS=fNDdy%g;t3nX5-w%2Uxd!9y9la7_@a3NS)OsT*S>AAjW3rn4dy!oEY|>IkRG
zuo&<jWi7}@1&b2M^#PcXs=(}X0tf|}K<@(&CLhofJx@Y+!5LhiVFef=_acLKz`~D#
z(T6EBrvRL*$#XuOmcxYdGVr66U`Iv&LZID+2^b-Jeth$<Ujy!V4n9KZd*c<hC@kJ_
zaRg*3z{J}%NJ9Vdfr>KZumc(BD?Z-tJC{q9a<Wpg->t1h7Wl3TjjrxM;}CgF>)ict
z76H4z?}d)NW!+_^q!MpHoIH_IL2Q6>kf(*DgVtDpOMZL-_5&9^;iw3BN%#?h_>S~r
z2MJvo3szZumimR!dJ1|+q5wj0c;&0)!=nV_xt`b8uA^XaXfa7>-mz+U?F)qU`1r$*
zLq-o0CrAMbUMUbI$$|k9<Bzh`=V|ss*BEf`#s=Whet3TuEQsR=b$Ek+@%YupKCa-S
z&K9gtXGtKab}vI3DHw#^Ig9Zes-p+UqPT+#Ze0l!`rVJ9Aga2ML<Dd+#k=mPB!QI*
zNz{(BjzCb}O(c41Ip7{d@UM^)Fcd)z^VV^tYCz~8;YIktG7U%~*Re4CZ8sxa)l_#<
z8bf>@&p{lqqVhk)-%a3`Hy~Rt6xoj-*darET&u!J5351Izz;k{r^p@OaY+?UUxi1m
z`p}O`P&kOO0GHZn3=RTjZ^OF)1*@zMH{>i4!e4}M!3x!55npYEV+Cus6Q{32Kq;O>
zb@YH<;se;#O}C&BuN*;ks~X>ORXUd7AE!G)-3U0GMpfWOG;Dm1K>SdFLoom&yayO{
zj9n|<V~Bsu$L9$w*z(+PML;~9WE!v{fw03oKK{52IUqj!94He2&}ry+4%Ol9@;@gZ
z)fL`7kbF3|3flu9;c(0ibq9VxWkeNteS&?Fl=2!SLh)VIhbk#xcnc^?I}luoevKY@
zfCN9KZPBm@fe`T+quhrV_^#*u<B*@DVju_F4}ND@-k{Cf1(%Qh8R|g}!~Y&usLAoe
zRf;-19NvI9et3LB_1{DN6QBeNYrqKOpC2D0?I4AxjBJ(_B=I#EqLelv-V{h8jUL{O
zOZ!$q`H)Y(`vns7@yGkM>XWyQK@^G!7$nTke{{y6lNCFFkl*`fr>tq54T5S1LGnXp
z)3I>>)M+HAlfq^($ExWSZaWHiQL^UG+r9r<>Xibo6nLe;D+OLD@JfMK3cOO_l>)C6
zc%{HA1zsueN`Y4jyi(wm0<RR<mI7I)+w1jD`u*-+87A9S`&wR7Ano=C!?V%l_3iEb
z{r%+rW;FOa;0S&Q;lpc2);k$qT;EL>t9)G@`ShHvqL2)H`PbdS`Diq{I6oVn4o>>r
zxL^EBMm_EHPe-@YWl=GrI>|@X8kd*cf*Rb?!Obi$)<sd|tHpeBcRe~Aym+Q``opV<
z#S6!j;_Snd^^!a3`J(Dr;iOnhZ!S(>u4T-+gUcz=P!j+3dj7#q>8Hb*hUL?nGZ2%K
zZ7=6H>z?1&;2aq<{7?m?tE3|~s#xBh^<J1YN&A-#7+1I-Zbz=C?TFb$)dc%wc{6xP
z9O>UIZ9K)@`wvuMbtj@B#^sEBl<H}Fi>$3JH`eP9l^?w}!e1;d53|}v(s#S--u1$8
zZjBBEw{AYrAxLj!w@2J97FYf4h<EVPozZNg6^~fEJy;Ho!|?&Ok`HWVKEHZa85vGi
zt%YN~UOX$Vd$6sI{Rq8oH61;hk?dW~x8TNl?e^Q)gDlVX>PG)6s(|%+dH+0aeR?+8
zLRGET#fNG=pd0k(l;RuCi~034n33M)HaNoI{OZ}{cz?M{&)Qk^z^VNH?1_i$>EN~v
zh8TQX%xAON{q^vPG2EXC6hb=MPBkyC4z>3&#iI7Sb2i;%Ir8Ofa(8n%g7`E9sQVu@
zH-HZ5@NTxs^Ss#9?jRz?-RaXcxqH#9tBNHE#7mBS)^@ap2i@W5>iXv9_I@&*v8kOJ
zb259X37@oo)ugNP<@EMq@PUr}8u;NK!FB>L^?81IGnp-6KBVbbUiP0Newv=#*85e(
zYJPX|Bxr1;+>r}(PR?&&3bctK#qG)Qbyhm453Uuf+11HY^ob+Wx-Iz5>D81@N-O3}
zj&4NK;Y`&UZWQ_S#l$$<QgrWf+3<GJptt77o)bN*4Rz+TW7oYm@s0za*W?Q?jvJIX
ztDWeWyA9Kh)8dy7H9N2OH&>TO#QwaF9m~tVSBI({H5)jxx;~mktz$=i_XLhaJHk9y
zskD1p*H@3mkUC{Gzlb06eJ*-Df4$kDZXB?>IfjI!L%RdycZ1`5+0Rez78rETXZ8s3
z7!r~WY|jd2jgP_o7R`ToMY6$-JwRMt9hyezi9PPvkd~Xdyz29d3zzr$;u9=Q7DGPr
z>F_+X0g^<UNDIENIXqj9n%*+2ZM>QG@2z@@`}zTB+QTr<-DEnSFP6(C#@!*${qp>@
z_u;5FNPxY#gb3nnzVL0BO?~QaEmN|ydsAmE&kx$_-i=jDep?qE>71NhL58~?xk4EJ
z{_1@20XP6@_w?fWex}ori+nM?y*#UNDIxLN)LDx|PEmC(tq|hs+D=f&`e#>@hAg0B
zIlVqVdD#P&&fwy9Y7*A#iDGeoHMD1SdRM07GlMUv9_Yv}tQwYArU-TiqkF43*LSPQ
z<!P<Z9|-N8!KA(6b&EWv#ofh;CFq@z>H6H)DU)sSOox_{T3%ZG?hdYMoIcJExLRDl
zOpc_zv)j!b$~7mSURtU*y)YSab0AOj#E7sL%aOs>&fwa_MDfDkSlygj{mTISbhm&T
zn-le8dy4s`Wk}4hYjK#MQuiiSU!7U(NNY4_^^!hW-B_)8I_j&MI;VG*snnRqJ9BFU
zc53y@<slL@(@VpwEiY9|((IzahDY?p*^3%arYE*@Bybj&#mw-X1{N`9Zi`k$x~*=U
z8OCFEr9h;8L#qkI?aS%&<nyT(z~^pky>FvU?-qC3G?)@{zjvlwZ%Qln=eZ6cXQOS!
zJc3<azl>D5{x*gqqVLXDS`}FgDQ--k)aV;Ex6&I;XCw2oZ;wg^(sh@`^gtg5uW3ZP
z+h>-BsY6-aFK$(*vW)t2uW!>Ni6y~zau}GMZI`{L8na%E+R^NIrLt?oOlm~y?-Wxx
z;4|Ic>FGXg=o{K<B0Doo#aPjlden_4%Y6lTpH{-Vy*+eQXil+^=^WWek7J6vJpvP{
zF~u^I=C`+tPoh|o-%F|6lfv7)o(?wVzbb@{8%vop-Z6x3p9ytiMo<MRo6_S9oNI3t
zlV{uFB(;3VT0|QjtZsz=)VtN1V<z=W>z>oqy{5Pl;x=d&bVyj7+~3|p-s|0DzCo=i
z1>73Z{R%cDBRJY)O#03>;eI-AUJ$mrJ>j?**@MO1u0Gb4_N}BXZ)C@EayvSQ<n~^-
z+l6hHPR~X+O>y7#^Nd8YrtI*10h!^$)05DK!Rh&BW84>}AQ(fe*xzbLAFHpe(Ol@1
zLA{@gLG^(M;ifn*QoqB=diD&fL^}1!QxH_Y9QH+s4fX}OxTz1tL#_>DNH)@b+iWLO
zncXSfw-U2lClgg9XxGL4s3tO%^)K#f-Q%a1ka}g6&u-52u-g&4Gq|jsQ^@bQ4e4Gh
z8Wnmx&3I^Dq^AmwTtHqo3M>|P=W29BD(Rfv){VU;(upUp9pe;+PPTo9Re<$#(SS+s
zqE629Ti*SRF~f?>P^*S@_0VI^E9%<Hs#r}fnz(_r!!)y2hK?`?o3&}x$aJV%>Cjl*
z3eBv+bw@Q?E5BtvkCiAjVI?$deJ4Fv{U+xlkB;HX!8=8}HSsWsrsWS`7violJLDb1
z{lRAE(^k3R{TsUtIiESru5?Q|DO)tDukw3}J2oMhT_Wb{$nQ6HtWbOZPFp$vS3Kb^
zKs{T+7i|NaAYR%9#WwKhVn++%wtImYOW>DG2^sQ(yjjU1Y7^^6=72=>t|kC`KFf??
zDGIpzc5^$}HNlC3cglelkc;gGA$>K!m2<CoV0P}sc5-;Cgb;aZ%{{iG&X%RDnYMMY
z-5f<`Cz&sqsZF)U+HUiZY=nei$CNd;XHs&?T|M@Od0{Jz`Cc(lvm)!JnE{(`t1i=l
zNeXVUQ`NoKqisz3iSh!MEb3y;sju&tMzctu?sZL-G251}3T}%Vh64$*dAXe)!FueO
zQ65;*8!#@m@OeARR_C|Wm}euc5Z7xxBh!W|*5c{iLp&{N3`J5aabdZoTKBN}cTAJ`
zi=4$8Qtdfxk!_-rr{}E4+EbC+2w<dJ$6`o+9Sa=k%&JxeuUppLvludG0&t=<R(k=-
zE@k)U3G>#tytvt3S^3s>tz^`F=QTGH(wItE@5&CG&XN=ZKkbIv^z>SJ#;pb9MET3i
zP+Qr&`A*8pQ>|yjk=F}muQrl*+X9v?U&;BsEr41KSuy3;Q+b<hCqi_t2v4^%LOywu
zlbCgTCvep78*FCJPita%TM((fXwOJa$}e}7aIEJ<&lRmX!IgJiwDcYHT8{~pyq=Ex
z7E`7x2_3p8XP4J^um{Uza({Pyc_t(9zNoGdY$A^W5t#d*n(pDw3fJRfjHL=T&hM#U
zc+0dJmCeouXqn>k8s;rb8g&NeFabsMCaj!*FHeXG1$fo;;oEi}v+Bm1S^)t2XZvou
zqPKVlgG9YjmEF+p69e5_>Af*!WDI|n<|YJgcMk~)V|CX<F--*wv2vAGMj9ri^RD0G
z$V^+lU1Wjc5zaGX-3OzbwlVCn0n*)4=3zA=MU9w`Iizh$bzj^JrK(OZh!~YjoHtB{
zz=ti)&QHzt7X(}DG&MBKIyYBOSg+UL>*^6r&P;?-JS(#!^BOX>H0_=m2gNNjLcVE3
z_r<kbTa>D5fh)C>Apn26DvH(gs%93Fw~1Yy7=wj^4R=}bEiR1d(isi?^wc8E7G9}x
zc5}Kmw4)tu!+3OthW}FbdjC5+6T`<$nL8+0vm%ac`efynH<GY>%@M(?Vk(engi!xb
zn-HF`t1L*1P_i=DEFV#c+}c>m+pFC>f{=ncAJE30F}YLNAJw7pgDtl-%B;~RA4=EL
zd()FlkEG_*)lq)r=9%=4k}0YJjhPiT3Uvru3V|@9I-LrS=G2(N<sM3)2lqI*m%oW*
zx(ma~xh*C<n&B&ggEprDO0^20cA!w!Gn8=_7W`HMx1OtU^gxa7D-MX01)sG^jMSJl
zQ@|d{bjX7f+k7^`vgO8VmXaD<|7t&xF<Z?KZ_FN5@oze&$yBJnU@-wizkUNb!40@v
z3MbP@7Y3UyiPE{^khU<!R%o1uu4QFgUS|R~uub=543etI;C-{@Qp;~vRR3M5NkN&f
zn4Bq=apLi-CC?k^7&cumtWZi}V<#(#YNlYY;6qt*=U=TIn1Gzhi6v%VbggRkk*0fO
zDkQcN9egY4K-MfcLzHs|MR;r(P}ZG%(Qb3P)QYjU3|eSX*>}=&Igl#uNlE41ZJ1e5
zLmH}&^e*O9nPIJ`MpTVUguLR*7tBm^No^$`5bRJ&jnJSvwH6mGSV*HPy8DTq3t7-H
zh>8tN<<OW`-BaR3&9x%-QfxWUS0yC*)io?Lpa@t?Sfou?eGHWJq^VV*f>R?+b!j`)
z6s0ZC)1g%A#VrA$I@7XAw$<>03V=>2;d8`EM@g3=zrIo2vZ=?ev4o|Vup;R>_pcCU
zaYL*oX+Ama8^$T8?IUIPIn}}A1wlW%5Xk40Te4mmN~bA_sfshwdH_<YM?;?cun1%}
zt6lve!e4!f1Hcd&nA(6q5gJ91&BANbmQ(9!y|l}{^i&E+ensF6qzanVi*{F)B@-V#
zS<RZKMJD!!e#H_tSb|R+3}FW*V+0P=UhvGWQzO>GZMqo^mcBC~0iLGTxcoRPfI4bJ
zi#Zt+D)DJhSju1%g_Nq4tQBDvwAfC`THc+Pp+nrL#pH-kM>=E)BNaA;HiI5BVazx~
zRMW5{YzXLc2(7PDrPvFCeR|ejVaf3rO?&L9fdya1kf~mQie`GjnAS1Bs>-K>la3zd
z!1r~S2c^3pRAy|FP|`5f=^fxmZ<Uf(f@<-bsR;5t5fGIbJ+B)QW=dT})t0Ip)D^K(
zpbw1YBI}jT+CQ;AtRtd0U7d@uUh`p_8n*&Jiu&AP%i<g_aa+?WC%v*G1I%p5P1$`S
zhcd)Ks2*9|(N`0TK;}jmR`Nn2G8^?w8jzcR56nss$;I-m3PGi_0o?kC3#>C0!XwjN
zs^``Y2~}`~#QS<O_?nAx12&N#xt(BiqNh;S`85$}AfwJ#1<-V8nk1${kl_N)k<4(A
z*9#F{u9$a#6J;aTGoq8U*Hq)H%hB8-0!hy}tzim>;jQ!G*ZEaVH7bS!pmRQRnVw2f
z#WH;Q*7B~Wqz6U(tk2a6V6pH)&N8)<f;bzQR9HFF{1pNnNdvNn1)p+o1gzeJ6B%-a
z0`*Z>^XqY9NnI+3O#o5Y^u${EuHu`3oa#%69p^u7%R$c7B2J?E(^G5=ISTIZmk11n
zBeo{euhu>j*@5>@q&8cxx%`xMxL=*F4ajkTNouWz<0@Z!d_ZTR_^>{+voM4Xf6<eD
zn=Xjz3Tm;4V}(m9d74M>Dmy3a#8W=XH(K1d-o&)86K+CM6-<U|d3eLJ>BjW2l5J47
zysnA{hdWWh8KOxu8R=MB=%~r2N!0(UNlQ8{l4!!L$Oy=2r0IVWk;Yf7uPTcSGHdcx
zrwC~7^K5+szx{8iusa=ED`U(CSE2H*5V3+pgp|L-I+)f!o95ii-T9@vYQ<mpd`V_a
zXz+kBG)|$nA+)kTGXO$Y&U;VE5Tqw9196AT+S8#>NkwFu^50h1<!kt>Qx-Qaa8eMl
z@+Ehm%$+p(eqPq{D%i}BBBzI{hDzfv9OO#Iy6N~psUkXl54EfH%L}5eq=&|)SoCVC
z7A;oQAw$GCy`v`c!C>?KLDX~tK*@<;=o-iK&_q1>AjCI-sF_wW)1uaQuHwj|1l18?
zRciFrj>v4aqM}LBCgY=H#MKM2)r2)p&siS2nf$pVniiXv(o7<`zew5sL;tF&Ju0>;
zxI~600TJnh<(CmdsmZyzQd5xa7B^XwiMa?t>FfZx<kH-ub-}z1*q$RA{#@s)#C9I^
zOe!q8KCL6?E_mz#@K7-@qVLq|XV%`1^pj;Ys;-r%M(};f*C?ftkf_i6!9T6nQ3;ix
z)P&*#hTJ;}<n!xj73=Ui(0w`ATF}%D846L0UDSRHWPH|>{xX}bR(-ggctEQq#z=0S
z-;iWh>M2hNF$0uJWA;Zk_xE>KL#?O}M1BQE`J}|-O=JXH#oT2SxR}HWB*k+!S*@}P
z`6xPqQD>RN3K=rt9k^%NbY8=WN^v#E>9A~0uLM#!9qxu&;!Ib2$o1$dgw+-1oCbkq
zD3u9-3dFBQt=nX*n1Hw!cUP^&yg7@#r)o+X*ebSkX^qkW3(CO}U81VO<s>%cP>`eH
zRZK%sNsdfkNa0zl@mNC>tyPdKD%bF?m2%6o7qW9{9)TfC5};_n;E0c8Dl|19DjGzy
z))6N;{kM!UU==K3Tlz{PU`6!m8$GmgqIm2zRsI`Ldqs21z{<!0FBI80CauTnFi+GX
zUfR)QxRlWp+$$L{BnCz%WwZ1ZHEqt)RW~<GXUs!fox7`gyb09i@yd>xv4$el;opqN
z;Y+9xHAP6SJP=twGR8wkgHrBT{-){#)M~Y8qiNH{2AoDhB8=r(Otd4X{(&EBdw#M7
zQU@v`J#o5Hg$_{>SDuZKNS&15M4aSOOJ+V)a*h!ii=d1%Su-NXa`fRH#dIvhqau9~
z4Rv4+ottZ*-*iiUcZ&warM+JB*quyAAba+z=|z@&Ao~EVvkBMuOsYeqB=zpFq%j@5
zUi0h)nbw40SePx=_*7?dR)I#$l|kntblG6i5}B~g*1V-M3bjKxLUtphB<T-GJ##*N
z#k!Q4t-6h`cX%!-t48-ali?I<?7_Vf;!b94WH6DDO3KxmgKgEu8h4ewt3o!&G``Bf
z*uNPDGto_C@Sf&Erd&{iE=MO!>!>MzvH)0iU*`SDhdB+>v~6_9bXWPXup?tOzz;Fg
z(UU<TD3b5cKiZ<bxttseP|GXh@oWnv+5M<{C4sVlhICi;^3KgzgS|G0y%rvMSItNx
zwc`{&)MF(Q$=G`vbPiTVuBD`LSUJZ{!@nv8gV<B0msvbRMwfO=;7_e}YH~lBfiZOC
zDY&WZI;hl`I3JAC?Ep!GPJ$kZoF5_ablpM83Q0BKqiF}J4CU>p9#U%uK)HLrlyFCF
zmZEO${U;V+wIk$#N=aY7AcFywQ%W_xoZ=&E61sxq`G_Ffl}Ycrdi;7BBzA4)K*4$+
zBTU6TsGiKw2PiqUq6GIRI8`ZB%)t^d9x|Vs&<!YDw~OH+DRXQkhK#JPSW@pcEzabu
z7NQ~clj$1N7W=&q3@fvuRM-Zm{maUz2z8?5WCK+#(zp;$QifOAeho6zw?_=m*r^7_
z;M~cwQn3ZKr3pp0+WT|uPwmYRq>81!kQ_<Vw#p@MBw0xA06{?}a`ui-6m7<rmgpM^
zi84igXq4egWX*52vpz)YJodTt_-F)6@`}>#ObiD}?xyrvm^PL&$MZS2Y^{u2x~?q@
zlC^}K@9@)+gD?amqNiITwtI0I3!=%Ba_C0p{L>3WIv(`X64HpWbQ>8hp*CszR!C_>
zgyej>M8}n3gK+B`bA^#`wmp8^zae8y#7|OdT*%N(4hLy;SBe00cf};{n)+<pW1q;;
z3=&%e#JX}K2Z|JYQx@X`LF<B|y#r=Dz9Jo7I+rcizmgsD<?IKUagwXfX^b+F8UJ+s
z=PoTUZMsN>v9cFv|ABf3BA*}Gx@Oy{?}FSe@5tDAaTTG+y~Oh9)5-}SG8~lqljSsV
zT_z2SNtIZ4+cW8RBO&EFD`_KL8MdOuOb%8V9Bpyhr<_bZpt12xtlJ~g>oOysY`81)
zPS|2l6{Y9y=?*PX(_27omd*mPcbV>j4B-PGDeqWfEhZgzKyHUu<Xj#Vc4>TL+JH1W
zWJXp7)XBsMC<c*Kzkicc8K88O<n!qr>uVPa7Fq0C^XV-%^W1^r&9BJJ7djx6)-pOn
zGF(F3G8yS3UI6R`ClocyTWm(O?y2Rj7AzJG(Kc)A0dCV}v<}%?Ji~mt9KF#&hIGs$
zdUDE%#6;!V4&o)lnq$Eam8Drn^@jU>Bla#o8ZPm5)aEM(Et@U_lnq!M>X95%(XBz`
z06k6~NFgA@NI7a@!*eN(2hj*}428tz3H6ZtZKRX%&pRY)!5DxM0m?%Wy#bDlHqq`Z
zRdXCn%N#=zzLNZ4={$0y5thc;fMw$&bB{PWkb<{U8Bjo`@sGQii9}*B(}>4G9!kp6
z8A2KPh`m{MH^N1k@Xx{}GL`x;fmAyL#UsaNM&g96YUxV<1z5(vS#uDIHv>_cCk`?a
zN!mEkr}z;A5cMwsBFEuJ(v_ADdp`+rA_=VJRqNOyEYc=97|R{=kfT>(nG<R2<J_v8
zog-F93Ka`qDT{QV)fLkJMt;c8x0%@sm(1&xx)z}<c%IWSd4aH%=Sp06iC#1XiXU-Y
zS8sHnHYp!;N@cH>TI2LWY*%G&PsylVGnk3%RQJNM)ywizcw{7@(l4SED1O9l*2oVz
zQfAa>g>OwE>l@YUl?Xve(Z%l1!@(UH48<a`*)^3P^0t(8nr$w9ujsnU<X$qalOn)O
zwuqPP8%`vINaai?QgY6hbfm^sq+<1n@vSS^>Ld0xQscg-S+@`0EbFi=Zy36YKmp}P
z{m`y~AI&C$Cq0rRx_w)h*xzU2dscO<9ey~q&B4qOV()3^0=|^Bn%@c;mYHQF5~a3L
zh+b_&+(XV0aTCEDvx29C?8%bU$TnOvZvw2P+J_Cp!K{l)qlt1R1~Ypi>Rvx7Cz5kI
z4XzWZ+VNu>`QXA%=1*yI(IJ{B7sMka<@Z@kYL95`sT{L9hVV6`wES-8{g{cwx60m4
zKAQL;LR4HnAcR#$F4}yXYP-hDBnwB$xUA6uvurx`@y*?@z!DwEF%J!5tAW^7R9o?*
z8uB*qL)mjKA4%G~m@HSz*(F!)+flxzw5%H$BEHXJd?5&ij&V2(kj(%k{pLVT?d@-i
z^aHkzb~k%2<}t|Ls*V1xLpkg8dOhh^v~Ns9N#omkFjvlXjqHHPGclhoV@Oy;PC7PV
zvH6kM`h_GvCr#sz2LGy5I*2M9gdb8N2#dNI*?mfM#gr!ECO;%S5c#ZFhEfC<^N8-|
zitL$sL7OEOlhdsfn#Skt`9TC;W^M5h5yk2l=T_HVaR(~3GZHB_nH77NAFrY>Y<VvC
zEuO^)KvVpxemuzBR_HyHAEIwPEkDfI`<x{&Bz8EM#8GQ(I#B{!(q9%o;hE6|<%h_K
zqUKK~X2igOlpHeuQTb0O<Z#5Gm&EEQ*O?suAP%%qP^&e?3)u^?lj>nILXnDZcl-rE
z)`TBY!0G&lbk-wjRg}K+yb}3RWa94lZ}X=4eU^y117+ECSYAaLVg)F35un@#Eml_U
zZ842COPv(Q;AE(Py#tQeDmfob@{gMUGNg`m(c=3oFw@~%ME{EARWbyDMHhU<^sX&P
z2ee)gylI5g)Sc_6mKwYO*|EsfdaU)RXQu|S`FE3(RHh9efyC#!?ZHg!$-B2f?l(>S
zD>>&x^Gl@b8Y6Ei3K>ViGDO7kuXb<47H`&k4TnK6qar+eA(iP)$TKmRVK7@?$i>NY
zF|3@Cp!rvFXcvbPGVPaS1j_ux?e|}3-LATVnbo!Bx2vq>RdGTAL0b!S)klr%aA>+O
zH}9rj;%LfGl%exDm9cC7ZWERVeAcyyExy}ley*FxS_fqe79}GbE4lB~4rphi5}N-d
z+1)aKcTIQJlUV{WA5QMSPV(F3UgO99Fn~!9zJYFNy+|(V8oOhPDc&=q$N|0w*+f0D
zaWNrmqE=VLe9`PuaQHfsMfS}Dbf^ft?U|T}^w^5oVHp&~LgI7XQbS-7F_>wK5h*9N
zJz3--H#5vf<UP5PCFWC$03~ch5&aG+RWXZ>fIjxA+Km<|DL<)VnHl1_1CH4ZA4ww=
z8m!x`8Op>)Z%8^y#4slf>kZU`39`IPdI3)xFexb{dyJzb|K^%j0FK%$9Be7R;+9P)
zmNmBjmATu?7^{&3J34)?*5i;=AUX9zjHMj4aHpj`)_ayz+e9F-<A~Nlx0Y9l&vncA
z1wz^Pd-P;-5W&Hhsj9Zh(KJ<#awP{@uclUbk#*!vAgg+x;Kckkx=^0hIGu-s%>X5x
z)ZV@&ayUpQALVe6c4oO>GTl%{j>3uBm2G7EGi;Cj?r-#s{bWQ4%BD682WQrNI$PAT
zEryv`oV+IAv5}S0>}MI?rJ*gkDF)GVQsw5+T5XH@p5^6g6Q>*a`t(d%J1j$$1PlwM
z!w4k`qMx@$Qts?c=Fio4C8&=sXO^h)l@U_1fKU!V<X42Z#((D*GRs}%-)BiWMvh!T
zwFJzkiz#hn**-R1c35JL<R)qb{RE(#Nr>Sq>@<i~JjjHn=CR0V*qOdtzu38nX*DIT
z;`=O+y`WuM{<-edvgtY53295b<fm~-c9)FPvaJqfE^AyK1&+BG^0N?(AOi1gTOz+-
zaeFU!-ao92M4r811}Il@1NF9;rt&j^#286mh?s#Sk;_x!@EoT6&&&Q6e#r(V(nsLx
zxGma;DR*ilEiPl+2P-jcI(I_M0OgD)2e-yo#x~Z(7Rj*!Rj!$s$>n=n$nTTR<B9_*
z-gJ!F8tX$9lr6;W!@s%K?sMH*sloS!V^CrXbmb77s+LQ!O%F5KVk<YYJp<G(l_1IK
zQWfs5YPV=+O;OXPlj(kZt;O;x8RBqSK@4VUFp#%pE(kH_$`zvSm0Y{O<bediEn<{p
zOiV6Rk_aC6+Wf*DSs#J5%O2#Y9cO#6i0pq@B<J5s!eX0`RDL^}*a*4JIotb1dhdKM
z1-YRCU0^JiVmzZk2l|{yJBXCzd$}jp2c6fP+QXGrS-X5EQhKH|S4x_5_R&(gaTFaY
z>I@~S1tllxnybwn=-?$}a+2%X{0n!fjK{e$d^v>F?O24`+m?7s>$<*+(MdTtWuB1q
z%j4`I)-2~7*Ru##R+(S6#PvwUWdHEQW|f)YU>YET(tIru0)bD4#84oESAQW>AIa88
zYDp0_=c&xnkh3{Le3#L|l7sj4z5(j`*0p+~0!B#56(5D9<`yT6+A`jaP}aPcZbnD$
zj6}Cz7HQTTxZJ8rd~YI=A2=ubDrHxKS5KW2C&{98Hd2y*pCvJuS8)$Y23QfwYD?!)
z1_i-uuCSHQ*eAy1{wi|ou&$6FI@2p<a=-X=h41bsG7f>16yImr^>f|CJ!*lU%2z1J
zOt&;2WS&Yd73c017<3`vG>J(136xhYkUl~Yt80sIqpQuJkY{{8-5ktpWz%K)I*d)L
z)~ZjVFtsALcBYA02tq04c{J$CpXYl`RTv!QBpaNM&Ie+BSvnL!HAie7f=aFVbWUya
z1Jcy$ZfcRLf~YIGU*(!<OPPBl(?nzv>UtH&i)#Bj5;EI_@t)5+XLs|(ayh>jskSlz
ziu{1@v#^MVNp1PLZebb$3jf$-BmV09(=>1?-N1r2K`mAl>!e{&D|%c`rq$%`M#QOW
z#CPw9z3Vb%YQcIJ>Q_xk`Gvclu|8d_N4AoK+uL+$A*gqy(yQqFcp~G4dbdsK{?QSk
zoX&l!?S<*=QXyQ?p0RU&E|?}qPAEi6rWvwxu~ZL>5F^moqvT8!+w-O)H4<C@BVE=x
zch{j>xmE0X9)(|f*-@D_V!Yo&z8_4^KJ@{cX&UqCOTMHdHL1;}c+JmsivVR^E7W`?
zUGuFLIIw8}*_p)0fS^X1rM=FhC!Jmh<?u8LORORgQA4$#7k2GAXIdsFMX?NDGSQXu
zbWoxoX1R_TxW5)cqX&)b$#nXHdK(?Fs(;PnJ+98apgGOdm7|w}<WSTjyyp}7!2`Kn
zjro0+DW6vAT2s87+SXvE%}03kYHYfDgxtD&O=grpwgs)%9BW6oOlne+G^#vaGC#5>
z)oWkZi=C;1g0FRq5R~}l8f*wAn=U=5R1UAO#}^`;WMC=%CoXu(A*XX6Y8WY^J+3yn
zQ~P=qM<B|*Bnb}&s)x8`d@zR_2dJbk)i6*p7k1yW>HKruH5*<>^JzAxC++o`?eD8*
z1*p1G-;T1>jY{IBLNpNGFpdA3=<a({&GP`Mb)P*|L_r6NQL@$Ny2ZRIN(h+-x7w0v
z*`%W~HNGJ6S(w3;_0c?_sy1CJ3W)rw7i`v6y?2b0RIaf{645ReDkb|1VF`B#cQupq
zX;_GnC+Wz^2rMGCBWtF$UmA6w<hrOeQ&&TTPY!7rLsim&oW&@G3a8Nc7Q^%~7b+YL
z*z-@G`+C&Z5wVrzW3O1MML3vk&=UwHrb~FcWRee}N22+uw8gA1soZd48E7>!ld>Q+
zsP9>?qB~4s9Ohh!BhrWs<jQ(v925%{BKEGwZBU3$@yh4~f+4$9l(mK5^i(?uRGaGM
zD$Cfl!4DC8UeE=(v?e)-Uy~Fq^{rwWS*Ab^aV}SYA$8V7T4^0B#0o{p3O-k~#quhn
z!>{RZf>vopGwJ@osY*$uo6D<EVKJi6<9W6eY$qcyHC$XXmPa55I5YQuS=DW@Wx1<7
zd8X!b-OL=N#(a9gqrqj%%oKUHS)o!UYZ}kUu3Z0$e{}FFR3&}&oCHj@MmNTkCCYpK
z+WR9h>QVTX16AD662@!-5`%|>4Tou6%y?3Y18VKy0qTz^Bo%t%-l+PhDTz#RwB>RI
zs<3n=2j29qLPf_Rz$BQ)!@tte4iw#D#}%^7j0gu?8(y!Mw_@a+of$!6?rWrS?i)sz
z#06Kzg)C60Xy8wJ!qBXV!b)U3WrIg3K)1iNGSmzDogW3t_&&=ry6V2TwHts42g?N+
zPNC$}t3ia-J-aO@0HV5qGxk+2mC?Ii(&(+4O{yO{q)K6toF$b2e4MW=c4eX%G`C<=
zor)i7mvk6kL>h+TC(@e-xGOf|x56)2Xm)dP+J`*}PtGpy=5izl1pq&4u66Ds*Pe3S
z;9AGps}`yVGTly8&Pufj@>G!9o@65_qtITme9nZE%2bZ^T$i)DKMx068#p*}FK3hc
zyZh-}1}X3%90mI>km~>ZV`J%1u#`?TNvu_(C0W>+WU7bJrxMg|*Xfx^B*yk`{vNOl
zLGd2xQ8B~8lejh+rW~x%J|eK;-~oJ@C=Jq0tcM<*Hmw)X3X4wOXuHYeeK!v9x8#Ct
zq{NB}DKB1KiE%nhttkt2WKIXb=HcMXnl9PEjCH~DXLU4yrR}QEr1C&~iEH_*5+>;K
z|E`Jxh#l@rC_Ddlb(9YFzi$%>$Y?+{zok90!lpkFssc#OZMyBtHgjY#sw#jJ{bdFo
zEl_dN!p1eg>`QgApm9UFcLt<DQqO_nwbMDBFE5EuOycH&O+b5**g2nYif@_WU=oCY
ztPVM?SE5n-%je^bwGL!$EMTHmlQyX<V6TdF(x|1}83J_40k^RQ{Vk_4feJI)AtGt@
zS?_M)x_`d7C2==i&N2{udDXTI5$woRV0X>G`k<!OX`F>4>#o#-FuEgVqE{0iWQVnY
zhqZ6<W?No0B86NnNY%RKQ|Q%WJTWs8dG^9q3@MgOx?mz!&8c(oP?0$qYGdfag<R9a
z$Cg?^ng-4i_J(V1p1|Hx@!aq}JkEMuHSl0>nV;*PkXQ#UcN0;(T2%$Za_a6tMMfBa
z4yl1(${xf7Q-)}Dq0%i_{-hqPiP@hD&ekWXG5IRKn6@=c{eqRfAo{2oFEp8=;*Bcc
zwC3WGs!#9ozM%0<RJfEaVpoI91MLY3h{)L&q(EK7+rYc+E!94#CLgi4&Ch=t3{iGU
zYpXR+bykxDWc4RQAzr9Op*-xSQY0Z*z{EX5+UhKoiyE-~$H-!lLq|vF6&)4=-exwc
z;K<@!w%hmurO+Nqe)v$*q?qzS$XZ*_t}?_0!{?C+XRDj3N|=Dw%Z$XWAl4Snl+HlT
zi!n}S?L0sklHc^Dr7{8l1r5U+3x5kfOKIY)XE*6iC+e$`fMjcz)U40lRO23O`*yax
z9=LeY6PvX-GD|(4b}x**AY4)Sli!_6;Yh4}Nw$I$N=Sdc&B`X7I>FvDzSAo<&=JjV
zb19cwyLPu4m$!i~%P1`l)#;v^^)But{TyD!{ASqI0RST!DV7N7R`Ny863=k0c4R5o
z;vMxEyUTvVbn^=Z)4B=T8noNrHtlt;v%9k1@akU7cjWWC(ZJw_nVTn;>nibBwVGnp
z-%e&0glC<*9;1>1+tUV1c2v|1pt9u>+risd+O+9QYaH3>4==9oCbRisv6#>9Z?Dcz
zd(v*W>a55cANeQR+_!Wel}pG2{9R)y4Bw@2BSBb!j`ARY9V;=?VsGqyp}QPZIah0x
zTs>*0H#i**&xXUnNiWlS$`vx#Vu`r4YG&K9bVrR)dC<#nv%$$SyG;wqnM-2w>zanQ
z0NAF8`MK_?&5#!GOoht^(w1l1!rAq8tLZkL&6=GX6J<-Se_J#JLLAnb8E&y!!P&Bq
znZ2+pLpnyX&|2<>qDF3oke~V%7;`Et<JZ~~a=kKgW9q9YpV;i6du^5_5BzI=u6w;3
zL%J3_a^bDZ1^%07p-F>vq?PBy%Kb>4RTrDD5^(jWoeMR`g_?X*kgXnI`zKa#e?7B|
z`UaRiJuL)nkS?c={Lu{)H&meogim9o*5>u=;%eJ1);i_{=^+OE8ybj@_2dC|g~qgY
z18UkAJ1Mxn$+D~QEuFHuRWL{{P=hfB3-M%fMWM&ycDpfyJw2M!k7O7WIMglkbKS6f
zM31~1YD}%cB~VMGQ>J?EeygcfHE#kvhj~0YUD0u5dYZCg4J}F16Dz_F0b>zMYJ#!X
zGc!no^YyKpkYw_EfWBX<Z(R@6%)Ll4-qaA4^9WNz3{9OL=TPA(W{tI|;i_*-%Ry2j
z=#~%FK+9vWDcvhVw*?%sR$>u%rq_e4TRT@ClumkF)8!ygNUmb=ZGmi~miY%XAtbzu
zKOzJt8g}4IH9PGQX}e{{&{!@95Q-`5xsa8hL&|c0rHu{K`Rrn5-Y`+FHO2C}HlLuX
z6%4sOD>^@9f<#qa-H8?Z!A2B|7Ne<?Te}U#Oh)tc`U9G&UWXjNueL}AEX5dHd&Q0+
z>wJFMYy!F$Go?@ct8zk`<8=5dGr<8-Sxq)LTK#L4uIZZq>lg%{nf?T|oNp0tSeJ4`
z6GW1vSHmmj#@i05)$Cg2>Bkz<{^iuz+|#|c>mWZu-}cPfFT<fytR@$=hCMyKu`{dT
z)fp!eL?E=bTJI8_Q_I)XlDf1;{{mL4`R&Dt4r!(Rv)fr6Hy}}WD_?V4+MDIAe0s-_
zb+MdYpBXI4PDb~&+<?hBX*~4UL27;zF?Cbt#=%@USB+-0!?y;Tb9;Gq(hVWeH0$<<
zqnoKuS_@_P&vUQ?^LvbFTtF<JPjIn8Cv>bd>kZDX?q;^#z;}w7ib?AERxy@Sgs;1y
zv#nH+Dm%Ab4Bwt&HJ`$q!R6&>ba{1iKbhAz1YT%kL+eo8=YChMvhdi4HZ13pyBlo7
z<>mG5{d7?)-B7-mO6jn^2F_z0TcB>t6Uj+}?5ts$IkYHWt@6CafXAk99jVx&A<acQ
z)|!)u7@p;>4Yo@dOBVOic0l-A&-wCLU^8y)srA9K30dQbh0~$Ape`cW@@)2`jxK8^
zY#wPvHCrMci{)~$AyCH{a^@pm`xaM5P`XfQ1}C@m3OFL$e3r9?F<W4Gn4+)@Xj9*B
z#vh+9Z}hn9M6E=J0rMVCi=kTiiV37g?@G($X7p)^l}hzH44vCU8SE|Pi%ah7VBOY4
z(Y$TKzJ<J=gNJ^gBA_sfu}}9Z=354HEKK*k*S!&$B(%S5KF_V06KimjU+smdwE?Gg
zgdpm?(O%cKDWC4sWA<tteL1ZS8q{JQAFM=bj{|J2N93s?wEmXoYT6f&Frpd|c-T!u
ziY5O_c}uj8QS9VyM?+Yct5nP{S?!(6X?_!#tzrwL>F*>WhR1#kQn!PdHjbvEG>Eg6
za&cUBIx7Ui7Nd5UG?cPdOsvfXtY_O>k;TDR=r**Z#iOn{fh_3HFQG@7fUP~|*Nyv3
zm|*nHp<L60_?QgY)~+u%#DO&~N57Ny&1rSc0&-Q%YU02qI}S3}mKsA$V2IT#(%waT
zM}Bc>r(PbN=FJskC)cgr_hNEx<?=!Wa<f{;!UIk2=zK+l&cEGIwlV9Sx3Y>kM6-4H
zw}kS%zn%W5Rj*p!4(paHTDzry@i<V6jSX~=AvXB5dkPaAu0PcM$!Ax?7t0Oo3y|4f
zJKYo-wVK#@?yf6Ydzq`?_#U0kPHI`!4dXif)4Hv2U@CNSb=I$u@;y*I@T+O}<m`G<
z6OYD42dBN-u!rgB?((s)+BT)uun@ero7#M<PVe;m@)jcOc{wa8^5uMb2MPQAj+n8j
zt@e2zq%dIviwz*cUbdkqR<P9%%<2r9q`PKPNbF?3U)$2583E1jPa9NXr+0EXJcp@|
z>+9>Q%hCDS=}GSc;YCTUw9_A)o?VQt$~Fv7s~NVkjQH)^(R(>jA>P{d(sr`!9R@k<
zG|f7lEUQ~N!3)38t2A?MXp!p&{<7(vEo<E3og190wYuK0Ev{;H*3NZ(xG!d>#tub5
zsDrsyku<3hdq<Y!cf(rC7T^B=<E&c~aLKP4)cUTZN$aLLU|{!QSm<3_-txV)Uqd1J
zz2lbfHWf>4)d(UoIn#47o1p#OJ@1^^`QebEeFW)1^3_TR?9hGkK^yG-J4aSy$f36$
ziygp_`taxKx_0sD{*8U{5Ympd4AOZ#Ir#$j;oD(5*REpVNDGJX@F=|ih%jC*hrNyz
z<j)bM!!`WO*dMp7KEES-IlllhJrN2u(F;eFV=vrJlA+p?u4D(~=jGGO|KElqo%34R
zfS7B;zVip_E$Kj~&qt1|^X25yNTfbc<u46PI=GsZ(JexR@^o?NQMuKA2njSMlN77P
z^ycE^1B+ByE!}Vr6Wtrq!(r*c4y&g()M-Ah37M6>0)F%5Vs>{kIv);TC;D!gA8rEs
zFmI-P*!ySRoKvH-d5_iBY&apruQ@I9)nYN5&8E}I-AJw(Iu>R}hnse~C&P;?48zyC
zRGuEIYmw=EOw`hW@gdS0zQAo<Z1jPLR62tTSaEQ5eS0^Vl3AVFHZMj`JLd*#0Bdov
z9*EC09<#F?1NQ07bcxF*ie{lGTV71mx}0NRMPa6=w`QcjL`nXx)KV1+?PZ^DoBzJN
zc|u)Pk*+(6d)Q0r8`o+Xa0Te4pXiSk7|n~fis>_~gLE_;)GsrQ=v8MQtbp{kQO(8T
zw%v{h$LNLdxv`oYjEW2K<RBX-AEOl;U}opB4I9rkE?nPG*}jiE=aUVNU)2P@clN#&
zKi&K0*ITPru@lHFYu*as39#;5wB!i;?9~$>cBm@UX8;)s$VIWZc@g8R>}=8y#HkSG
zn`a-2TE~aeYv)H6>f@2eN3E`gba1;_YduA9tq#F`?ziK|>REi;`gV0Lrj237_3GI*
zYd!LfPr5CFLoYC=BhC7a1CmyoV>c4!nI2}NO6A%o`Q6#ejAmz@{`pPKUP^~p8uUyI
zX;fH{=>C#3k~7#|`{H`C5GxMaeAMxosJ*$`^sFXoRV?l<26bydHp6|Y62Oy_!TIP4
zwqJ2O(J!Xg#`iLw3Y!DelNp=!uI6`Far>eJRB~hxu)$Kd-#<ASz|sHE)8(?^UDz%F
zXLVrB!PUiwm#lwehCeO%9!x@A!K#T1ST+HZo_~i^o=;29{cD3o2Os#diT!Et3gMLk
TuM~Ktz$*n_Dey{xHWc`O(cS1K
literal 0
HcmV?d00001
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf
new file mode 100644
index 0000000000..1f79332020
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf
@@ -0,0 +1,10 @@
+// /** @file
+// Platform Logo image definition file.
+//
+// Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// 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. <BR>
+#
+# 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.<BR>
+//
+// 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. <BR>
+#
+# 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.<BR>
+//
+// 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.<BR>
+//
+// 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.<BR>
+//
+// 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. <BR>
+#
+# 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ACPI_PLATFORM_H_
+#define _ACPI_PLATFORM_H_
+
+//
+// Statements that include other header files
+//
+
+#include <Base.h>
+#include <Uefi.h>
+#include <IndustryStandard/Pci30.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/HighPrecisionEventTimerTable.h>
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
+#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
+#include <Register/Hpet.h>
+#include <Guid/EventGroup.h>
+#include <Guid/GlobalVariable.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BoardAcpiTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/AslUpdateLib.h>
+#include <Library/PciSegmentInfoLib.h>
+
+#include <Protocol/AcpiTable.h>
+#include <Protocol/MpService.h>
+#include <Protocol/PciIo.h>
+
+#include <Register/Cpuid.h>
+
+#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. <BR>
+#
+# 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. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// QEMU Video Controller Driver
+//
+
+#ifndef _QEMU_H_
+#define _QEMU_H_
+
+
+#include <Uefi.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/DriverSupportedEfiVersion.h>
+#include <Protocol/DevicePath.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/TimerLib.h>
+#include <Library/FrameBufferBltLib.h>
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/Acpi.h>
+
+#include <Library/S3BootScriptLib.h>
+
+//
+// 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. <BR>
+#
+# 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.<BR>
+;
+; 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.<BR>
+#
+# 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.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _8259_H__
+#define _8259_H__
+
+#include <Protocol/Legacy8259.h>
+#include <Protocol/PciIo.h>
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+
+#include <IndustryStandard/Pci.h>
+
+// 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.<BR>
+# 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.<BR>
+//
+// 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.<BR>
+//
+// 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
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#45752): https://edk2.groups.io/g/devel/message/45752
Mute This Topic: https://groups.io/mt/32816099/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
© 2016 - 2025 Red Hat, Inc.