From: "Liming Gao" <liming.gao@intel.com>
To: "Wei, David Y" <david.y.wei@intel.com>,
"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Wu, Hao A" <hao.a.wu@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: Re: [edk2-platforms PATCH v2 5/7] SimicsOpenBoardPkg: Add Overrides modules and Logo image for SIMICS QSP Platform
Date: Wed, 28 Aug 2019 03:01:09 +0000 [thread overview]
Message-ID: <4A89E2EF3DFEDB4C8BFDE51014F606A14E4DD4D6@SHSMSX104.ccr.corp.intel.com> (raw)
In-Reply-To: <d442370841662a71de75909e135ac402f83223f9.1566950706.git.david.y.wei@intel.com>
David:
Thanks for your update. I don't think Overrides directory is necessary.
I suggest you directly add AcpiTables and QemuVideoDxe (maybe rename to VideoDxe) in edk2-platforms\Platform\Intel\SimicsOpenBoardPkg.
Thanks
Liming
>-----Original Message-----
>From: Wei, David Y
>Sent: Wednesday, August 28, 2019 8:40 AM
>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-platforms PATCH v2 5/7] SimicsOpenBoardPkg: Add Overrides
>modules and Logo image for SIMICS QSP Platform
>
>Add overridden modules specific for SIMICS support.
>Add SIMICS customized Logo image
>
>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>
>
>Signed-off-by: David Wei <david.y.wei@intel.com>
>---
> .../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 | 416 ++++++
> .../Overrides/OvmfPkg/QemuVideoDxe/Initialize.c | 341 +++++
> .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c | 302 ++++
> Platform/Intel/SimicsOpenBoardPkg/Logo/Logo.bmp | Bin 0 -> 141078
>bytes
> Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec | 152 ++
> .../MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h | 45 +
> .../Acpi/AcpiTables/AcpiPlatform.inf | 105 ++
> .../Overrides/OvmfPkg/QemuVideoDxe/Qemu.h | 507 +++++++
> .../OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf | 74 +
> .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm | 279 ++++
> .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h | 701 +++++++++
> .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh | 79 +
> 20 files changed, 6378 insertions(+)
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
>bles/AcpiPlatform.c
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
>bles/Facs/Facs.c
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
>bles/Fadt/Fadt.c
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
>bles/Hpet/Hpet.c
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
>bles/Wsmt/Wsmt.c
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Co
>mponentName.c
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dr
>iver.c
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dr
>iverSupportedEfiVersion.c
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/G
>op.c
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Ini
>tialize.c
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/V
>beShim.c
> create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Logo/Logo.bmp
> create mode 100644 Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
>bles/AcpiPlatform.h
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
>bles/AcpiPlatform.inf
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Q
>emu.h
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Q
>emuVideoDxe.inf
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/V
>beShim.asm
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/V
>beShim.h
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/V
>beShim.sh
>
>diff --git
>a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/AcpiPlatform.c
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/AcpiPlatform.c
>new file mode 100644
>index 0000000000..f050d8afc0
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/AcpiPlatform.c
>@@ -0,0 +1,1579 @@
>+/** @file
>+ ACPI Platform Driver
>+
>+ Copyright (c) 2019 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
>ADER *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_TAB
>LE_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_REV
>ISION,
>+ 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_HE
>ADER) +
>+ 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/Acpi
>Tables/Facs/Facs.c
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/Facs/Facs.c
>new file mode 100644
>index 0000000000..e649b5b89c
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/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) 2019 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
>Tables/Fadt/Fadt.c
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/Fadt/Fadt.c
>new file mode 100644
>index 0000000000..d1fe98e24b
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/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) 2019 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
>Tables/Hpet/Hpet.c
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/Hpet/Hpet.c
>new file mode 100644
>index 0000000000..e9528b0ec3
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/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) 2019 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
>Tables/Wsmt/Wsmt.c
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/Wsmt/Wsmt.c
>new file mode 100644
>index 0000000000..625b7560bb
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/Wsmt/Wsmt.c
>@@ -0,0 +1,46 @@
>+/** @file
>+ ACPI WSMT table
>+
>+ Copyright (c) 2019 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..d6d1d451df
>--- /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 - 2019 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..af658f9f60
>--- /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 - 2019 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..5158e4851e
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>Gop.c
>@@ -0,0 +1,416 @@
>+/** @file
>+ Graphics Output Protocol functions for the QEMU video controller.
>+
>+ Copyright (c) 2007 - 2019 Intel Corporation. All rights reserved. <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..543d360861
>--- /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 - 2019 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/Logo/Logo.bmp
>b/Platform/Intel/SimicsOpenBoardPkg/Logo/Logo.bmp
>new file mode 100644
>index
>0000000000000000000000000000000000000000..86d7030833a096f545393735d9
>31d9f4f2fbf8c0
>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|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&B
>DW#
>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`MbpM
>sHs!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{
>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*AdsRkD
>KJvp4
>zCm;S4$mS{S0Q*XVe}%Ys?dtt2B$q2SM)p<m;qHcx>;OAaaYNG3l=>gnf&eMdp
>2>%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&0
>O_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`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@
>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`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_XLhaJ
>Hk9y
>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{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
>WLO
>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#;pb9ME
>T3i
>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^)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(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>_p
>cCU
>zaYL*oX+Ama8^$T8?IUIPIn}}A1wlW%5Xk40Te4mmN~bA_sfshwdH_<YM?;?c
>un1%}
>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
>RPfI4bJ
>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_^>{+voM4
>Xf6<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=&|)So
>CVC
>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;o
>pqN
>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
>zz;Fg
>z(UU<TD3b5cKiZ<bxttseP|GXh@oWnv+5M<{C4sVlhICi;^3KgzgS|G0y%rvMSIt
>Nx
>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@pc
>Ezabu
>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_
>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;mYHQF
>5~a3L
>zh+b_&+(XV0aTCEDvx29C?8%bU$TnOvZvw2P+J_Cp!K{l)qlt1R1~Ypi>Rvx7Cz5k
>I
>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
>7PV
>zvH6kM`h_GvCr#sz2LGy5I*2M9gdb8N2#dNI*?mfM#gr!ECO;%S5c#ZFhEfC<^
>N8-|
>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
>cl-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
>HhU<^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?ND
>GSQXu
>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#cQup
>q
>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}QPZIa
>h0x
>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=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%ah7VBOY
>4
>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>Eg
>6
>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>#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!Et3g
>MLk
>TuM~Ktz$*n_Dey{xHWc`O(cS1K
>
>literal 0
>HcmV?d00001
>
>diff --git a/Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec
>b/Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec
>new file mode 100644
>index 0000000000..ea070a10cd
>--- /dev/null
>+++ b/Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec
>@@ -0,0 +1,152 @@
>+## @file
>+# EFI/Framework Simics platform
>+#
>+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
>+#
>+# SPDX-License-Identifier: BSD-2-Clause-Patent
>+#
>+##
>+
>+[Defines]
>+ DEC_SPECIFICATION = 0x00010005
>+ PACKAGE_NAME = SimicsOpenBoardPkg
>+ PACKAGE_GUID = E6A03E0D-5944-4dc6-9292-090D609EDD3A
>+ PACKAGE_VERSION = 0.1
>+
>+[Includes]
>+ Include
>+
>+[Guids]
>+ gBoardModuleTokenSpaceGuid = {0xeed35f57, 0x4ff2, 0x4244, {0xb8, 0x3a,
>0xea, 0x71, 0x5f, 0xd3, 0x59, 0xa5}}
>+ gSimicsBoardConfigGuid = {0xeed35f57, 0x4ff2, 0x4244, {0xb8, 0x3a, 0xea,
>0x71, 0x5f, 0xd3, 0x59, 0xa5}}
>+
>+[PcdsFixedAtBuild]
>+ gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvBase|0x0|UINT32|0
>+ gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvSize|0x0|UINT32|1
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvBase|0x0|UINT32|0x15
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvSize|0x0|UINT32|0x16
>+
>+ #TODO: Remove these two when we integrate new PlatformPei
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsMemFvBase|0x00800000|UINT32|2
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsMemFvSize|0x00500000|UINT32|3
>+
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase|0x0|
>UINT32|0x8
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize|0x0|
>UINT32|0x9
>+ gBoardModuleTokenSpaceGuid.PcdSimicsFirmwareFdSize|0x0|UINT32|0xa
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsFirmwareBlockSize|0|UINT32|0xb
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase|0x0|U
>INT32|0xc
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageFtwSpareBase|0x0|
>UINT32|0xd
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase|0x
>0|UINT32|0xe
>+ gBoardModuleTokenSpaceGuid.PcdSimicsFdBaseAddress|0x0|UINT32|0xf
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsSecPageTablesBase|0x0|UINT32|0
>x11
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsSecPageTablesSize|0x0|UINT32|0x
>12
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamBase|0x0|UINT32|
>0x13
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamSize|0x0|UINT32|
>0x14
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsLockBoxStorageBase|0x0|UINT32|
>0x18
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsLockBoxStorageSize|0x0|UINT32|0
>x19
>+
>gBoardModuleTokenSpaceGuid.PcdGuidedExtractHandlerTableSize|0x0|UIN
>T32|0x1a
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsDecompressionScratchEnd|0x0|UI
>NT32|0x1f
>+
>+[PcdsDynamic, PcdsDynamicEx]
>+
>+ # TODO: investigate whether next two Pcds are needed
>+ gBoardModuleTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|0x28
>+
>gBoardModuleTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLE
>AN|0x10
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId|0|UINT16|
>0x1b
>+
>+ ## The IO port aperture shared by all PCI root bridges.
>+ #
>+ gBoardModuleTokenSpaceGuid.PcdPciIoBase|0x0|UINT64|0x22
>+ gBoardModuleTokenSpaceGuid.PcdPciIoSize|0x0|UINT64|0x23
>+
>+ ## The 32-bit MMIO aperture shared by all PCI root bridges.
>+ #
>+ gBoardModuleTokenSpaceGuid.PcdPciMmio32Base|0x0|UINT64|0x24
>+ gBoardModuleTokenSpaceGuid.PcdPciMmio32Size|0x0|UINT64|0x25
>+
>+ ## The 64-bit MMIO aperture shared by all PCI root bridges.
>+ #
>+ gBoardModuleTokenSpaceGuid.PcdPciMmio64Base|0x0|UINT64|0x26
>+ gBoardModuleTokenSpaceGuid.PcdPciMmio64Size|0x0|UINT64|0x27
>+
>+[PcdsFixedAtBuild, PcdsDynamic, PcdsDynamicEx, PcdsPatchableInModule]
>+ ## Pcd8259LegacyModeMask defines the default mask value for platform.
>This value is determined<BR><BR>
>+ # 1) If platform only support pure UEFI, value should be set to 0xFFFF or
>0xFFFE;
>+ # Because only clock interrupt is allowed in legacy mode in pure UEFI
>platform.<BR>
>+ # 2) If platform install CSM and use thunk module:<BR>
>+ # a) If thunk call provided by CSM binary requires some legacy interrupt
>support, the corresponding bit
>+ # should be opened as 0.<BR>
>+ # For example, if keyboard interfaces provided CSM binary use legacy
>keyboard interrupt in 8259 bit 1, then
>+ # the value should be set to 0xFFFC.<BR>
>+ # b) If all thunk call provied by CSM binary do not require legacy interrupt
>support, value should be set
>+ # to 0xFFFF or 0xFFFE.<BR>
>+ #
>+ # The default value of legacy mode mask could be changed by
>EFI_LEGACY_8259_PROTOCOL->SetMask(). But it is rarely
>+ # need change it except some special cases such as when initializing the
>CSM binary, it should be set to 0xFFFF to
>+ # mask all legacy interrupt. Please restore the original legacy mask value if
>changing is made for these special case.<BR>
>+ # @Prompt 8259 Legacy Mode mask.
>+
>gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeMask|0xFFFF|UINT16
>|0x00000001
>+
>+ ## Pcd8259LegacyModeEdgeLevel defines the default edge level for legacy
>mode's interrrupt controller.
>+ # For the corresponding bits, 0 = Edge triggered and 1 = Level triggered.
>+ # @Prompt 8259 Legacy Mode edge level.
>+
>gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel|0x0000|UI
>NT16|0x00000002
>+
>+ ## Indicates if we need enable IsaAcpiCom1 device.<BR><BR>
>+ # TRUE - Enables IsaAcpiCom1 device.<BR>
>+ # FALSE - Doesn't enable IsaAcpiCom1 device.<BR>
>+ # @Prompt Enable IsaAcpiCom1 device.
>+
>gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiCom1Enable|TRUE|BOOLEAN|0
>x00000003
>+
>+ ## Indicates if we need enable IsaAcpiCom2 device.<BR><BR>
>+ # TRUE - Enables IsaAcpiCom2 device.<BR>
>+ # FALSE - Doesn't enable IsaAcpiCom2 device.<BR>
>+ # @Prompt Enable IsaAcpiCom12 device.
>+
>gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiCom2Enable|TRUE|BOOLEAN|0
>x00000004
>+
>+ ## Indicates if we need enable IsaAcpiPs2Keyboard device.<BR><BR>
>+ # TRUE - Enables IsaAcpiPs2Keyboard device.<BR>
>+ # FALSE - Doesn't enable IsaAcpiPs2Keyboard device.<BR>
>+ # @Prompt Enable IsaAcpiPs2Keyboard device.
>+
>gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiPs2KeyboardEnable|TRUE|BOOL
>EAN|0x00000005
>+
>+ ## Indicates if we need enable IsaAcpiPs2Mouse device.<BR><BR>
>+ # TRUE - Enables IsaAcpiPs2Mouse device.<BR>
>+ # FALSE - Doesn't enable IsaAcpiPs2Mouse device.<BR>
>+ # @Prompt Enable IsaAcpiPs2Mouse device.
>+
>gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiPs2MouseEnable|TRUE|BOOLEA
>N|0x00000006
>+
>+ ## Indicates if we need enable IsaAcpiFloppyA device.<BR><BR>
>+ # TRUE - Enables IsaAcpiFloppyA device.<BR>
>+ # FALSE - Doesn't enable IsaAcpiFloppyA device.<BR>
>+ # @Prompt Enable IsaAcpiFloppyA device.
>+
>gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiFloppyAEnable|TRUE|BOOLEAN
>|0x00000007
>+
>+ ## Indicates if we need enable IsaAcpiFloppyB device.<BR><BR>
>+ # TRUE - Enables IsaAcpiFloppyB device.<BR>
>+ # FALSE - Doesn't enable IsaAcpiFloppyB device.<BR>
>+ # @Prompt Enable IsaAcpiFloppyB device.
>+
>gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiFloppyBEnable|TRUE|BOOLEAN
>|0x00000008
>+
>+[PcdsFixedAtBuild, PcdsPatchableInModule]
>+ ## FFS filename to find the shell application.
>+ # @Prompt FFS Name of Shell Application
>+ gBoardModuleTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E,
>0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4,
>0xD1 }|VOID*|0x40000004
>+
>+ ## ISA Bus features to support DMA, SlaveDMA and ISA Memory. <BR><BR>
>+ # BIT0 indicates if DMA is supported<BR>
>+ # BIT1 indicates if only slave DMA is supported<BR>
>+ # BIT2 indicates if ISA memory is supported<BR>
>+ # Other BITs are reseved and must be zero.
>+ # If more than one features are supported, the different BIT will be
>enabled at the same time.
>+ # @Prompt ISA Bus Features
>+ # @Expression 0x80000002 |
>(gBoardModuleTokenSpaceGuid.PcdIsaBusSupportedFeatures & 0xF8) == 0
>+
>gBoardModuleTokenSpaceGuid.PcdIsaBusSupportedFeatures|0x05|UINT8|0
>x00010040
>+
>+ gBoardModuleTokenSpaceGuid.PcdLogoFile |{ 0x99, 0x8b, 0xB2, 0x7B, 0xBB,
>0x61, 0xD5, 0x11, 0x9A, 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1,
>0x4D }|VOID*|0x00010037
>+
>+[Protocols]
>+ ##
>+ ## IntelFrameworkModulePkg
>+ ##
>+ gEfiOEMBadgingProtocolGuid = { 0x170E13C0, 0xBF1B, 0x4218,
>{ 0x87, 0x1D, 0x2A, 0xBD, 0xC6, 0xF8, 0x87, 0xBC }}
>diff --git
>a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/AcpiPlatform.h
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/AcpiPlatform.h
>new file mode 100644
>index 0000000000..e98aac4676
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/AcpiPlatform.h
>@@ -0,0 +1,45 @@
>+/** @file
>+ This is an implementation of the ACPI platform driver.
>+
>+ Copyright (c) 2019 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
>Tables/AcpiPlatform.inf
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/AcpiPlatform.inf
>new file mode 100644
>index 0000000000..7dfd0832a3
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/AcpiPlatform.inf
>@@ -0,0 +1,105 @@
>+## @file
>+# Component information file for AcpiPlatform module
>+#
>+# Copyright (c) 2019 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..4143487366
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>QemuVideoDxe.inf
>@@ -0,0 +1,74 @@
>+## @file
>+# This driver is a sample implementation of the Graphics Output Protocol for
>+# the QEMU (Cirrus Logic 5446) video controller.
>+#
>+# Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <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/OpenBoardPkg.dec
>+ SimicsIch10Pkg/Ich10Pkg.dec
>+
>+[LibraryClasses]
>+ BaseMemoryLib
>+ FrameBufferBltLib
>+ DebugLib
>+ DevicePathLib
>+ MemoryAllocationLib
>+ PcdLib
>+ PciLib
>+ PrintLib
>+ TimerLib
>+ UefiBootServicesTableLib
>+ UefiDriverEntryPoint
>+ UefiLib
>+ S3BootScriptLib
>+
>+[Protocols]
>+ gEfiDriverSupportedEfiVersionProtocolGuid # PROTOCOL
>ALWAYS_PRODUCED
>+ gEfiGraphicsOutputProtocolGuid # PROTOCOL BY_START
>+ gEfiDevicePathProtocolGuid # PROTOCOL BY_START
>+ gEfiPciIoProtocolGuid # PROTOCOL TO_START
>+ gEfiDxeSmmReadyToLockProtocolGuid
>+
>+[Pcd]
>+ gOptionRomPkgTokenSpaceGuid.PcdDriverSupportedEfiVersion
>+ gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
>+
>gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask
>diff --git
>a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>VbeShim.asm
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>VbeShim.asm
>new file mode 100644
>index 0000000000..a82077e2d9
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>VbeShim.asm
>@@ -0,0 +1,279 @@
>+; @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
>--
>2.16.2.windows.1
next prev parent reply other threads:[~2019-08-28 3:01 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-28 0:40 [edk2-platforms PATCH v2 0/7] Add Initial QSP MinPlatform Pkg for SIMICS David Wei
2019-08-28 0:40 ` [edk2-platforms PATCH v2 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58 David Wei
2019-08-28 22:02 ` Nate DeSimone
2019-08-28 0:40 ` [edk2-platforms PATCH v2 2/7] SimicsICH10Pkg: Add PCH Pkg for SimicsICH10 David Wei
2019-08-28 22:02 ` Nate DeSimone
2019-08-28 0:40 ` [edk2-platforms PATCH v2 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules David Wei
2019-08-28 22:02 ` Nate DeSimone
2019-08-28 0:40 ` [edk2-platforms PATCH v2 4/7] SimicsOpenBoardPkg: Add DXE driver for Legacy Sio David Wei
2019-08-28 22:56 ` Nate DeSimone
2019-08-28 0:40 ` [edk2-platforms PATCH v2 5/7] SimicsOpenBoardPkg: Add Overrides modules and Logo image for SIMICS QSP Platform David Wei
2019-08-28 3:01 ` Liming Gao [this message]
2019-08-28 23:02 ` Nate DeSimone
2019-08-28 0:40 ` [edk2-platforms PATCH v2 6/7] SimicsOpenBoardPkg/BoardX58Ich10: Add board module for QSP Build tip David Wei
2019-08-28 23:13 ` Nate DeSimone
2019-08-28 0:40 ` [edk2-platforms PATCH v2 7/7] Platform/Intel: Add build option for SIMICS QSP Platform David Wei
2019-08-28 23:15 ` Nate DeSimone
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4A89E2EF3DFEDB4C8BFDE51014F606A14E4DD4D6@SHSMSX104.ccr.corp.intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox