From: "David Wei" <david.y.wei@intel.com>
To: "Kubacki, Michael A" <michael.a.kubacki@intel.com>,
"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Wu, Hao A" <hao.a.wu@intel.com>,
"Gao, Liming" <liming.gao@intel.com>,
"Sinha, Ankit" <ankit.sinha@intel.com>,
"Agyeman, Prince" <prince.agyeman@intel.com>,
"Desimone, Nathaniel L" <nathaniel.l.desimone@intel.com>,
"Kinney, Michael D" <michael.d.kinney@intel.com>
Subject: Re: [edk2-platform patch 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules
Date: Fri, 23 Aug 2019 16:57:59 +0000 [thread overview]
Message-ID: <BB06729C0DFAF049B2572591F2D0B0F5095D9908@fmsmsx121.amr.corp.intel.com> (raw)
In-Reply-To: <49AB4ACB9627B8468F29D589A27B745588A5001E@ORSMSX122.amr.corp.intel.com>
Hi Mike,
Please see the updates online below. Please let me know if you have any more comments.
Thanks
David
-----Original Message-----
From: Kubacki, Michael A
Sent: Monday, August 19, 2019 6:04 PM
To: Wei, David Y <david.y.wei@intel.com>; devel@edk2.groups.io
Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince <prince.agyeman@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: RE: [edk2-platform patch 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules
Feedback I could not find already covered elsewhere:
1. Dsdt.asl: Change "OVMF" in the following line to something else unique to this implementation:
"DefinitionBlock ("Dsdt.aml", "DSDT", 1, "INTEL ", "OVMF ", 4) {"
Ydwei: done
2. BasePchSpiCommonLib.inf: This silicon package should not have a dependency on SimicsOpenBoardPkg.dec.
Ydwei: done
3. Platform.h: This header guard definition is unusual in style and convention, please correct: "_Platform_h_INCLUDED_"
Ydwei: done
4. Platform.h: Please update usage of "OVMF" in various signatures throughout the file to something package unique.
Ydwei: done
5. SimicsX58PlatformConfig.h: Why is this file not in SimicsX58SktPkg?
Ydwei: done
6. SimicsX58PlatformConfig.h: Change "OVMF" in copyright header to "Simics X58"
Ydwei: done
7. SimicsPlatforms.h: Change "OVMF" in copyright header to "Simics"
Ydwei: done
8. SimicsPlatforms.h - Line 16: Follow up on TODO
Ydwei: done
9. X58Ich10.h: Why is this file in the Simics board package? It should be in the silicon package.
Ydwei: done
10. LoadLinuxLib.inf: This package should avoid a depdency on OvmfPkg.dec
Ydwei: done
11. LoadLinuxLib.inf: Library name does not following naming convention. I.e. should be BaseLoadLinuxLib.inf.
Ydwei: This driver is from edk2\OvmfPkg\Library\LoadLinuxLib. I didn't make change.
12. LoadLinuxLib.inf: This is not truly a BASE library. For example, gBS (boot services) are unavailable in Runtime DXE.
Ydwei: This driver is from edk2\OvmfPkg\Library\LoadLinuxLib. I think it is just used by Linux Loader.
13. Platform.c: Change "OVMF" reference in copyright header.
Ydwei: done
14. Platform.h: Change "OVMF" reference in copyright header.
Ydwei: done
15. Cmos.c: It seems CmosAccessLib in BoardModulePkg could be used here to avoid duplication.
Ydwei: I tried CmosAccessLib in BoardModulePkg and it cause build error. I didn't make change.
16. Fv.c: In MinPlatform, a more intuitive place to manage FVs is in a board-specific instance of PeiReportFvLib
Ydwei: It is used for SIMICS S3 resume. Different purpose.
17. General comment: The modules "PlatformPei" and "PlatformDxe" should be avoided in a MinPlatform.
MinPlatformPkg is considered the "platform" and SimicsOpenBoardPkg is considered the "board", therefore this
code should likely be in a board library linked against a PlatformInit module in MinPlatformPkg. Such as BoardInitLib
which is very empty at the moment. At a minimum, if kept as a module for dispatch, the name should not lead to confusion
with platform modules in MinPlatformPkg.
Ydwei: They are SIMICS specifical. So I change their name as SimicsPei and SimicsDxe
18. PlatformPei.inf: This package should avoid a depdency on OvmfPkg.dec
Ydwei: done
19. X58SmamSaveStateMap.h: If X58-specific, it should go to SimicsX58SktPkg.
Ydwei: done
20. SerializeVariablesLib.inf: This package should avoid a depdency on OvmfPkg.dec
Ydwei: done
21. SimicsOpenBoardPkg.dec: Pcds in the gSimicsX58PkgTokenSpaceGuid token space should be declared in a DEC file
in the SimicsX58SktPkg. SimicsOpenBoardPkg should not be hardcoded to this particular silicon design.
Ydwei: done
22. SimicsOpenBoardPkg.dec: "X58" should be removed from the copyright header as the DEC is at the package-level
and not the board level.
Ydwei: done
23. SimicsOpenBoardPkg.dec: The PACKAGE_NAME should not be " SimicsX58Pkg" as the DEC is at package-level and
not Simics board-specific.
Ydwei: done
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 9, 2019 3:47 PM
> To: devel@edk2.groups.io
> Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince
> <prince.agyeman@intel.com>; Kubacki, Michael A
> <michael.a.kubacki@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: [edk2-platform patch 3/7] SimicsOpenBoardPkg: Add
> SimicsOpenBoardPkg and its modules
>
> Add modules AcpiTables, Include, Library, PlatformDxe, PlatformPei, Policy,
> SmbiosPlatformDxe
> for Simics QSP platform support
>
> Cc: Hao Wu <hao.a.wu@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Cc: Agyeman Prince <prince.agyeman@intel.com>
> Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
>
> Signed-off-by: David Wei <david.y.wei@intel.com>
> ---
> .../Library/LoadLinuxLib/Linux.c | 662 ++++++++++++++++
> .../Library/LoadLinuxLib/LinuxGdt.c | 175 +++++
> .../Library/NvVarsFileLib/FsAccess.c | 507 ++++++++++++
> .../Library/NvVarsFileLib/NvVarsFileLib.c | 77 ++
> .../SerializeVariablesLib/SerializeVariablesLib.c | 869
> +++++++++++++++++++++
> .../SimicsOpenBoardPkg/PlatformDxe/Platform.c | 865
> ++++++++++++++++++++
> .../PlatformDxe/PlatformConfig.c | 123 +++
> .../Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c | 57 ++
> .../PlatformPei/FeatureControl.c | 114 +++
> Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c | 100 +++
> .../SimicsOpenBoardPkg/PlatformPei/MemDetect.c | 568 ++++++++++++++
> .../SimicsOpenBoardPkg/PlatformPei/Platform.c | 631 +++++++++++++++
> .../SiliconPolicyInitLib/SiliconPolicyInitLib.c | 108 +++
> .../SiliconPolicyUpdateLib.c | 70 ++
> .../SmbiosPlatformDxe/SmbiosPlatformDxe.c | 148 ++++
> .../SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf | 31 +
> .../Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl | 821
> +++++++++++++++++++
> .../Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h | 75 ++
> .../Include/Guid/SimicsX58PlatformConfig.h | 17 +
> .../Include/IndustryStandard/X58Ich10.h | 106 +++
> .../SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h | 298 +++++++
> .../SimicsOpenBoardPkg/Include/Protocol/IsaIo.h | 356 +++++++++
> .../Include/Protocol/Legacy8259.h | 291 +++++++
> .../Include/Register/X58SmramSaveStateMap.h | 178 +++++
> .../SimicsOpenBoardPkg/Include/SimicsPlatforms.h | 54 ++
> .../Library/LoadLinuxLib/Ia32/JumpToKernel.nasm | 41 +
> .../Library/LoadLinuxLib/LoadLinuxLib.h | 52 ++
> .../Library/LoadLinuxLib/LoadLinuxLib.inf | 42 +
> .../Library/LoadLinuxLib/X64/JumpToKernel.nasm | 85 ++
> .../Library/NvVarsFileLib/NvVarsFileLib.h | 55 ++
> .../Library/NvVarsFileLib/NvVarsFileLib.inf | 53 ++
> .../SerializeVariablesLib/SerializeVariablesLib.h | 33 +
> .../SerializeVariablesLib.inf | 36 +
> .../SimicsOpenBoardPkg/PlatformDxe/Platform.h | 37 +
> .../SimicsOpenBoardPkg/PlatformDxe/Platform.inf | 65 ++
> .../SimicsOpenBoardPkg/PlatformDxe/Platform.uni | 31 +
> .../PlatformDxe/PlatformConfig.h | 51 ++
> .../PlatformDxe/PlatformForms.vfr | 67 ++
> .../Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h | 50 ++
> .../SimicsOpenBoardPkg/PlatformPei/Platform.h | 93 +++
> .../SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf | 109 +++
> .../SiliconPolicyInitLib/SiliconPolicyInitLib.inf | 38 +
> .../SiliconPolicyUpdateLib.inf | 35 +
> .../SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec | 168 ++++
> .../SmbiosPlatformDxe/SmbiosPlatformDxe.h | 38 +
> .../SmbiosPlatformDxe/SmbiosPlatformDxe.inf | 51 ++
> 46 files changed, 8531 insertions(+)
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVaria
> blesLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c
> create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformPei/FeatureControl.c
> create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconP
> olicyInitLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Silic
> onPolicyUpdateLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf
> create mode 100644 Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsX58PlatformConfig.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateMap
> .h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.
> nasm
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKernel.
> nasm
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVaria
> blesLib.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVaria
> blesLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformForms.vfr
> create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconP
> olicyInitLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Silic
> onPolicyUpdateLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.i
> nf
>
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
> new file mode 100644
> index 0000000000..43a2dee9f6
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
> @@ -0,0 +1,662 @@
> +/** @file
> + Copyright (c) 2011 - 2014 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "LoadLinuxLib.h"
> +
> +
> +/**
> + A simple check of the kernel setup image
> +
> + An assumption is made that the size of the data is at least the
> + size of struct boot_params.
> +
> + @param[in] KernelSetup - The kernel setup image
> +
> + @retval EFI_SUCCESS - The kernel setup looks valid and supported
> + @retval EFI_INVALID_PARAMETER - KernelSetup was NULL
> + @retval EFI_UNSUPPORTED - The kernel setup is not valid or supported
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +BasicKernelSetupCheck (
> + IN VOID *KernelSetup
> + )
> +{
> + return LoadLinuxCheckKernelSetup(KernelSetup, sizeof (struct
> boot_params));
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +LoadLinuxCheckKernelSetup (
> + IN VOID *KernelSetup,
> + IN UINTN KernelSetupSize
> + )
> +{
> + struct boot_params *Bp;
> +
> + if (KernelSetup == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (KernelSetupSize < sizeof (*Bp)) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + Bp = (struct boot_params*) KernelSetup;
> +
> + if ((Bp->hdr.signature != 0xAA55) || // Check boot sector signature
> + (Bp->hdr.header != SETUP_HDR) ||
> + (Bp->hdr.version < 0x205) || // We only support relocatable kernels
> + (!Bp->hdr.relocatable_kernel)
> + ) {
> + return EFI_UNSUPPORTED;
> + } else {
> + return EFI_SUCCESS;
> + }
> +}
> +
> +
> +UINTN
> +EFIAPI
> +LoadLinuxGetKernelSize (
> + IN VOID *KernelSetup,
> + IN UINTN KernelSize
> + )
> +{
> + struct boot_params *Bp;
> +
> + if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) {
> + return 0;
> + }
> +
> + Bp = (struct boot_params*) KernelSetup;
> +
> + if (Bp->hdr.version > 0x20a) {
> + return Bp->hdr.init_size;
> + } else {
> + //
> + // Add extra size for kernel decompression
> + //
> + return 3 * KernelSize;
> + }
> +}
> +
> +
> +VOID*
> +EFIAPI
> +LoadLinuxAllocateKernelSetupPages (
> + IN UINTN Pages
> + )
> +{
> + EFI_STATUS Status;
> + EFI_PHYSICAL_ADDRESS Address;
> +
> + Address = BASE_1GB;
> + Status = gBS->AllocatePages (
> + AllocateMaxAddress,
> + EfiLoaderData,
> + Pages,
> + &Address
> + );
> + if (!EFI_ERROR (Status)) {
> + return (VOID*)(UINTN) Address;
> + } else {
> + return NULL;
> + }
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +LoadLinuxInitializeKernelSetup (
> + IN VOID *KernelSetup
> + )
> +{
> + EFI_STATUS Status;
> + UINTN SetupEnd;
> + struct boot_params *Bp;
> +
> + Status = BasicKernelSetupCheck (KernelSetup);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Bp = (struct boot_params*) KernelSetup;
> +
> + SetupEnd = 0x202 + (Bp->hdr.jump & 0xff);
> +
> + //
> + // Clear all but the setup_header
> + //
> + ZeroMem (KernelSetup, 0x1f1);
> + ZeroMem (((UINT8 *)KernelSetup) + SetupEnd, 4096 - SetupEnd);
> + DEBUG ((EFI_D_INFO, "Cleared kernel setup 0-0x1f1, 0x%Lx-0x1000\n",
> + (UINT64)SetupEnd));
> +
> + return EFI_SUCCESS;
> +}
> +
> +VOID*
> +EFIAPI
> +LoadLinuxAllocateKernelPages (
> + IN VOID *KernelSetup,
> + IN UINTN Pages
> + )
> +{
> + EFI_STATUS Status;
> + EFI_PHYSICAL_ADDRESS KernelAddress;
> + UINT32 Loop;
> + struct boot_params *Bp;
> +
> + if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) {
> + return NULL;
> + }
> +
> + Bp = (struct boot_params*) KernelSetup;
> +
> + for (Loop = 1; Loop < 512; Loop++) {
> + KernelAddress = MultU64x32 (
> + 2 * Bp->hdr.kernel_alignment,
> + Loop
> + );
> + Status = gBS->AllocatePages (
> + AllocateAddress,
> + EfiLoaderData,
> + Pages,
> + &KernelAddress
> + );
> + if (!EFI_ERROR (Status)) {
> + return (VOID*)(UINTN) KernelAddress;
> + }
> + }
> +
> + return NULL;
> +}
> +
> +
> +VOID*
> +EFIAPI
> +LoadLinuxAllocateCommandLinePages (
> + IN UINTN Pages
> + )
> +{
> + EFI_STATUS Status;
> + EFI_PHYSICAL_ADDRESS Address;
> +
> + Address = 0xa0000;
> + Status = gBS->AllocatePages (
> + AllocateMaxAddress,
> + EfiLoaderData,
> + Pages,
> + &Address
> + );
> + if (!EFI_ERROR (Status)) {
> + return (VOID*)(UINTN) Address;
> + } else {
> + return NULL;
> + }
> +}
> +
> +
> +VOID*
> +EFIAPI
> +LoadLinuxAllocateInitrdPages (
> + IN VOID *KernelSetup,
> + IN UINTN Pages
> + )
> +{
> + EFI_STATUS Status;
> + EFI_PHYSICAL_ADDRESS Address;
> +
> + struct boot_params *Bp;
> +
> + if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) {
> + return NULL;
> + }
> +
> + Bp = (struct boot_params*) KernelSetup;
> +
> + Address = (EFI_PHYSICAL_ADDRESS)(UINTN) Bp->hdr.ramdisk_max;
> + Status = gBS->AllocatePages (
> + AllocateMaxAddress,
> + EfiLoaderData,
> + Pages,
> + &Address
> + );
> + if (!EFI_ERROR (Status)) {
> + return (VOID*)(UINTN) Address;
> + } else {
> + return NULL;
> + }
> +}
> +
> +
> +STATIC
> +VOID
> +SetupLinuxMemmap (
> + IN OUT struct boot_params *Bp
> + )
> +{
> + EFI_STATUS Status;
> + UINT8 TmpMemoryMap[1];
> + UINTN MapKey;
> + UINTN DescriptorSize;
> + UINT32 DescriptorVersion;
> + UINTN MemoryMapSize;
> + EFI_MEMORY_DESCRIPTOR *MemoryMap;
> + EFI_MEMORY_DESCRIPTOR *MemoryMapPtr;
> + UINTN Index;
> + struct efi_info *Efi;
> + struct e820_entry *LastE820;
> + struct e820_entry *E820;
> + UINTN E820EntryCount;
> + EFI_PHYSICAL_ADDRESS LastEndAddr;
> +
> + //
> + // Get System MemoryMapSize
> + //
> + MemoryMapSize = sizeof (TmpMemoryMap);
> + Status = gBS->GetMemoryMap (
> + &MemoryMapSize,
> + (EFI_MEMORY_DESCRIPTOR *)TmpMemoryMap,
> + &MapKey,
> + &DescriptorSize,
> + &DescriptorVersion
> + );
> + ASSERT (Status == EFI_BUFFER_TOO_SMALL);
> + //
> + // Enlarge space here, because we will allocate pool now.
> + //
> + MemoryMapSize += EFI_PAGE_SIZE;
> + Status = gBS->AllocatePool (
> + EfiLoaderData,
> + MemoryMapSize,
> + (VOID **) &MemoryMap
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + //
> + // Get System MemoryMap
> + //
> + Status = gBS->GetMemoryMap (
> + &MemoryMapSize,
> + MemoryMap,
> + &MapKey,
> + &DescriptorSize,
> + &DescriptorVersion
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + LastE820 = NULL;
> + E820 = &Bp->e820_map[0];
> + E820EntryCount = 0;
> + LastEndAddr = 0;
> + MemoryMapPtr = MemoryMap;
> + for (Index = 0; Index < (MemoryMapSize / DescriptorSize); Index++) {
> + UINTN E820Type = 0;
> +
> + if (MemoryMap->NumberOfPages == 0) {
> + continue;
> + }
> +
> + switch(MemoryMap->Type) {
> + case EfiReservedMemoryType:
> + case EfiRuntimeServicesCode:
> + case EfiRuntimeServicesData:
> + case EfiMemoryMappedIO:
> + case EfiMemoryMappedIOPortSpace:
> + case EfiPalCode:
> + E820Type = E820_RESERVED;
> + break;
> +
> + case EfiUnusableMemory:
> + E820Type = E820_UNUSABLE;
> + break;
> +
> + case EfiACPIReclaimMemory:
> + E820Type = E820_ACPI;
> + break;
> +
> + case EfiLoaderCode:
> + case EfiLoaderData:
> + case EfiBootServicesCode:
> + case EfiBootServicesData:
> + case EfiConventionalMemory:
> + E820Type = E820_RAM;
> + break;
> +
> + case EfiACPIMemoryNVS:
> + E820Type = E820_NVS;
> + break;
> +
> + default:
> + DEBUG ((
> + EFI_D_ERROR,
> + "Invalid EFI memory descriptor type (0x%x)!\n",
> + MemoryMap->Type
> + ));
> + continue;
> + }
> +
> + if ((LastE820 != NULL) &&
> + (LastE820->type == (UINT32) E820Type) &&
> + (MemoryMap->PhysicalStart == LastEndAddr)) {
> + LastE820->size += EFI_PAGES_TO_SIZE ((UINTN) MemoryMap-
> >NumberOfPages);
> + LastEndAddr += EFI_PAGES_TO_SIZE ((UINTN) MemoryMap-
> >NumberOfPages);
> + } else {
> + if (E820EntryCount >= (sizeof (Bp->e820_map) / sizeof (Bp-
> >e820_map[0]))) {
> + break;
> + }
> + E820->type = (UINT32) E820Type;
> + E820->addr = MemoryMap->PhysicalStart;
> + E820->size = EFI_PAGES_TO_SIZE ((UINTN) MemoryMap-
> >NumberOfPages);
> + LastE820 = E820;
> + LastEndAddr = E820->addr + E820->size;
> + E820++;
> + E820EntryCount++;
> + }
> +
> + //
> + // Get next item
> + //
> + MemoryMap = (EFI_MEMORY_DESCRIPTOR *)((UINTN)MemoryMap +
> DescriptorSize);
> + }
> + Bp->e820_entries = (UINT8) E820EntryCount;
> +
> + Efi = &Bp->efi_info;
> + Efi->efi_systab = (UINT32)(UINTN) gST;
> + Efi->efi_memdesc_size = (UINT32) DescriptorSize;
> + Efi->efi_memdesc_version = DescriptorVersion;
> + Efi->efi_memmap = (UINT32)(UINTN) MemoryMapPtr;
> + Efi->efi_memmap_size = (UINT32) MemoryMapSize;
> +#ifdef MDE_CPU_IA32
> + Efi->efi_loader_signature = SIGNATURE_32 ('E', 'L', '3', '2');
> +#else
> + Efi->efi_systab_hi = (UINT32) (((UINT64)(UINTN) gST) >> 32);
> + Efi->efi_memmap_hi = (UINT32) (((UINT64)(UINTN) MemoryMapPtr) >> 32);
> + Efi->efi_loader_signature = SIGNATURE_32 ('E', 'L', '6', '4');
> +#endif
> +
> + gBS->ExitBootServices (gImageHandle, MapKey);
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +LoadLinuxSetCommandLine (
> + IN OUT VOID *KernelSetup,
> + IN CHAR8 *CommandLine
> + )
> +{
> + EFI_STATUS Status;
> + struct boot_params *Bp;
> +
> + Status = BasicKernelSetupCheck (KernelSetup);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Bp = (struct boot_params*) KernelSetup;
> +
> + Bp->hdr.cmd_line_ptr = (UINT32)(UINTN) CommandLine;
> +
> + return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +LoadLinuxSetInitrd (
> + IN OUT VOID *KernelSetup,
> + IN VOID *Initrd,
> + IN UINTN InitrdSize
> + )
> +{
> + EFI_STATUS Status;
> + struct boot_params *Bp;
> +
> + Status = BasicKernelSetupCheck (KernelSetup);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Bp = (struct boot_params*) KernelSetup;
> +
> + Bp->hdr.ramdisk_start = (UINT32)(UINTN) Initrd;
> + Bp->hdr.ramdisk_len = (UINT32) InitrdSize;
> +
> + return EFI_SUCCESS;
> +}
> +
> +
> +STATIC VOID
> +FindBits (
> + unsigned long Mask,
> + UINT8 *Pos,
> + UINT8 *Size
> + )
> +{
> + UINT8 First, Len;
> +
> + First = 0;
> + Len = 0;
> +
> + if (Mask) {
> + while (!(Mask & 0x1)) {
> + Mask = Mask >> 1;
> + First++;
> + }
> +
> + while (Mask & 0x1) {
> + Mask = Mask >> 1;
> + Len++;
> + }
> + }
> + *Pos = First;
> + *Size = Len;
> +}
> +
> +
> +STATIC
> +EFI_STATUS
> +SetupGraphicsFromGop (
> + struct screen_info *Si,
> + EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop
> + )
> +{
> + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
> + EFI_STATUS Status;
> + UINTN Size;
> +
> + Status = Gop->QueryMode(Gop, Gop->Mode->Mode, &Size, &Info);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + /* We found a GOP */
> +
> + /* EFI framebuffer */
> + Si->orig_video_isVGA = 0x70;
> +
> + Si->orig_x = 0;
> + Si->orig_y = 0;
> + Si->orig_video_page = 0;
> + Si->orig_video_mode = 0;
> + Si->orig_video_cols = 0;
> + Si->orig_video_lines = 0;
> + Si->orig_video_ega_bx = 0;
> + Si->orig_video_points = 0;
> +
> + Si->lfb_base = (UINT32) Gop->Mode->FrameBufferBase;
> + Si->lfb_size = (UINT32) Gop->Mode->FrameBufferSize;
> + Si->lfb_width = (UINT16) Info->HorizontalResolution;
> + Si->lfb_height = (UINT16) Info->VerticalResolution;
> + Si->pages = 1;
> + Si->vesapm_seg = 0;
> + Si->vesapm_off = 0;
> +
> + if (Info->PixelFormat == PixelRedGreenBlueReserved8BitPerColor) {
> + Si->lfb_depth = 32;
> + Si->red_size = 8;
> + Si->red_pos = 0;
> + Si->green_size = 8;
> + Si->green_pos = 8;
> + Si->blue_size = 8;
> + Si->blue_pos = 16;
> + Si->rsvd_size = 8;
> + Si->rsvd_pos = 24;
> + Si->lfb_linelength = (UINT16) (Info->PixelsPerScanLine * 4);
> +
> + } else if (Info->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
> + Si->lfb_depth = 32;
> + Si->red_size = 8;
> + Si->red_pos = 16;
> + Si->green_size = 8;
> + Si->green_pos = 8;
> + Si->blue_size = 8;
> + Si->blue_pos = 0;
> + Si->rsvd_size = 8;
> + Si->rsvd_pos = 24;
> + Si->lfb_linelength = (UINT16) (Info->PixelsPerScanLine * 4);
> + } else if (Info->PixelFormat == PixelBitMask) {
> + FindBits(Info->PixelInformation.RedMask,
> + &Si->red_pos, &Si->red_size);
> + FindBits(Info->PixelInformation.GreenMask,
> + &Si->green_pos, &Si->green_size);
> + FindBits(Info->PixelInformation.BlueMask,
> + &Si->blue_pos, &Si->blue_size);
> + FindBits(Info->PixelInformation.ReservedMask,
> + &Si->rsvd_pos, &Si->rsvd_size);
> + Si->lfb_depth = Si->red_size + Si->green_size +
> + Si->blue_size + Si->rsvd_size;
> + Si->lfb_linelength = (UINT16) ((Info->PixelsPerScanLine * Si->lfb_depth) / 8);
> + } else {
> + Si->lfb_depth = 4;
> + Si->red_size = 0;
> + Si->red_pos = 0;
> + Si->green_size = 0;
> + Si->green_pos = 0;
> + Si->blue_size = 0;
> + Si->blue_pos = 0;
> + Si->rsvd_size = 0;
> + Si->rsvd_pos = 0;
> + Si->lfb_linelength = Si->lfb_width / 2;
> + }
> +
> + return Status;
> +}
> +
> +
> +STATIC
> +EFI_STATUS
> +SetupGraphics (
> + IN OUT struct boot_params *Bp
> + )
> +{
> + EFI_STATUS Status;
> + EFI_HANDLE *HandleBuffer;
> + UINTN HandleCount;
> + UINTN Index;
> + EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
> +
> + ZeroMem ((VOID*)&Bp->screen_info, sizeof(Bp->screen_info));
> +
> + Status = gBS->LocateHandleBuffer (
> + ByProtocol,
> + &gEfiGraphicsOutputProtocolGuid,
> + NULL,
> + &HandleCount,
> + &HandleBuffer
> + );
> + if (!EFI_ERROR (Status)) {
> + for (Index = 0; Index < HandleCount; Index++) {
> + Status = gBS->HandleProtocol (
> + HandleBuffer[Index],
> + &gEfiGraphicsOutputProtocolGuid,
> + (VOID*) &Gop
> + );
> + if (EFI_ERROR (Status)) {
> + continue;
> + }
> +
> + Status = SetupGraphicsFromGop (&Bp->screen_info, Gop);
> + if (!EFI_ERROR (Status)) {
> + FreePool (HandleBuffer);
> + return EFI_SUCCESS;
> + }
> + }
> +
> + FreePool (HandleBuffer);
> + }
> +
> + return EFI_NOT_FOUND;
> +}
> +
> +
> +STATIC
> +EFI_STATUS
> +SetupLinuxBootParams (
> + IN OUT struct boot_params *Bp
> + )
> +{
> + SetupGraphics (Bp);
> +
> + SetupLinuxMemmap (Bp);
> +
> + return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +LoadLinux (
> + IN VOID *Kernel,
> + IN OUT VOID *KernelSetup
> + )
> +{
> + EFI_STATUS Status;
> + struct boot_params *Bp;
> +
> + Status = BasicKernelSetupCheck (KernelSetup);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Bp = (struct boot_params *) KernelSetup;
> +
> + if (Bp->hdr.version < 0x205 || !Bp->hdr.relocatable_kernel) {
> + //
> + // We only support relocatable kernels
> + //
> + return EFI_UNSUPPORTED;
> + }
> +
> + InitLinuxDescriptorTables ();
> +
> + Bp->hdr.code32_start = (UINT32)(UINTN) Kernel;
> + if (Bp->hdr.version >= 0x20c && Bp->hdr.handover_offset &&
> + (Bp->hdr.xloadflags & (sizeof (UINTN) == 4 ? BIT2 : BIT3))) {
> + DEBUG ((EFI_D_INFO, "Jumping to kernel EFI handover point at ofs %x\n",
> Bp->hdr.handover_offset));
> +
> + DisableInterrupts ();
> + JumpToUefiKernel ((VOID*) gImageHandle, (VOID*) gST, KernelSetup,
> Kernel);
> + }
> +
> + //
> + // Old kernels without EFI handover protocol
> + //
> + SetupLinuxBootParams (KernelSetup);
> +
> + DEBUG ((EFI_D_INFO, "Jumping to kernel\n"));
> + DisableInterrupts ();
> + SetLinuxDescriptorTables ();
> + JumpToKernel (Kernel, (VOID*) KernelSetup);
> +
> + return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c
> new file mode 100644
> index 0000000000..624fbc37cb
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c
> @@ -0,0 +1,175 @@
> +/** @file
> + Initialize GDT for Linux.
> +
> + Copyright (c) 2006 - 2012 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "LoadLinuxLib.h"
> +
> +
> +//
> +// Local structure definitions
> +//
> +
> +#pragma pack (1)
> +
> +//
> +// Global Descriptor Entry structures
> +//
> +
> +typedef struct _GDT_ENTRY {
> + UINT16 Limit15_0;
> + UINT16 Base15_0;
> + UINT8 Base23_16;
> + UINT8 Type;
> + UINT8 Limit19_16_and_flags;
> + UINT8 Base31_24;
> +} GDT_ENTRY;
> +
> +typedef
> +struct _GDT_ENTRIES {
> + GDT_ENTRY Null;
> + GDT_ENTRY Null2;
> + GDT_ENTRY Linear;
> + GDT_ENTRY LinearCode;
> + GDT_ENTRY TaskSegment;
> + GDT_ENTRY Spare4;
> + GDT_ENTRY Spare5;
> +} GDT_ENTRIES;
> +
> +#pragma pack ()
> +
> +STATIC GDT_ENTRIES *mGdt = NULL;
> +
> +//
> +// Global descriptor table (GDT) Template
> +//
> +STATIC GDT_ENTRIES GdtTemplate = {
> + //
> + // Null
> + //
> + {
> + 0x0, // limit 15:0
> + 0x0, // base 15:0
> + 0x0, // base 23:16
> + 0x0, // type
> + 0x0, // limit 19:16, flags
> + 0x0, // base 31:24
> + },
> + //
> + // Null2
> + //
> + {
> + 0x0, // limit 15:0
> + 0x0, // base 15:0
> + 0x0, // base 23:16
> + 0x0, // type
> + 0x0, // limit 19:16, flags
> + 0x0, // base 31:24
> + },
> + //
> + // Linear
> + //
> + {
> + 0x0FFFF, // limit 0xFFFFF
> + 0x0, // base 0
> + 0x0,
> + 0x09A, // present, ring 0, data, expand-up, writable
> + 0x0CF, // page-granular, 32-bit
> + 0x0,
> + },
> + //
> + // LinearCode
> + //
> + {
> + 0x0FFFF, // limit 0xFFFFF
> + 0x0, // base 0
> + 0x0,
> + 0x092, // present, ring 0, data, expand-up, writable
> + 0x0CF, // page-granular, 32-bit
> + 0x0,
> + },
> + //
> + // TaskSegment
> + //
> + {
> + 0x0, // limit 0
> + 0x0, // base 0
> + 0x0,
> + 0x089, // ?
> + 0x080, // ?
> + 0x0,
> + },
> + //
> + // Spare4
> + //
> + {
> + 0x0, // limit 0
> + 0x0, // base 0
> + 0x0,
> + 0x0, // present, ring 0, data, expand-up, writable
> + 0x0, // page-granular, 32-bit
> + 0x0,
> + },
> + //
> + // Spare5
> + //
> + {
> + 0x0, // limit 0
> + 0x0, // base 0
> + 0x0,
> + 0x0, // present, ring 0, data, expand-up, writable
> + 0x0, // page-granular, 32-bit
> + 0x0,
> + },
> +};
> +
> +/**
> + Initialize Global Descriptor Table.
> +
> +**/
> +VOID
> +InitLinuxDescriptorTables (
> + VOID
> + )
> +{
> + //
> + // Allocate Runtime Data for the GDT
> + //
> + mGdt = AllocateRuntimePool (sizeof (GdtTemplate) + 8);
> + ASSERT (mGdt != NULL);
> + mGdt = ALIGN_POINTER (mGdt, 8);
> +
> + //
> + // Initialize all GDT entries
> + //
> + CopyMem (mGdt, &GdtTemplate, sizeof (GdtTemplate));
> +
> +}
> +
> +/**
> + Initialize Global Descriptor Table.
> +
> +**/
> +VOID
> +SetLinuxDescriptorTables (
> + VOID
> + )
> +{
> + IA32_DESCRIPTOR GdtPtr;
> + IA32_DESCRIPTOR IdtPtr;
> +
> + //
> + // Write GDT register
> + //
> + GdtPtr.Base = (UINT32)(UINTN)(VOID*) mGdt;
> + GdtPtr.Limit = (UINT16) (sizeof (GdtTemplate) - 1);
> + AsmWriteGdtr (&GdtPtr);
> +
> + IdtPtr.Base = (UINT32) 0;
> + IdtPtr.Limit = (UINT16) 0;
> + AsmWriteIdtr (&IdtPtr);
> +}
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c
> b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c
> new file mode 100644
> index 0000000000..6ba8784cf3
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c
> @@ -0,0 +1,507 @@
> +/** @file
> + File System Access for NvVarsFileLib
> +
> + Copyright (c) 2004 - 2014 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "NvVarsFileLib.h"
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +
> +
> +/**
> + Open the NvVars file for reading or writing
> +
> + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid
> instance
> + @param[in] ReadingFile - TRUE: open the file for reading. FALSE: writing
> + @param[out] NvVarsFile - If EFI_SUCCESS is returned, then this is updated
> + with the opened NvVars file.
> +
> + @return EFI_SUCCESS if the file was opened
> +
> +**/
> +EFI_STATUS
> +GetNvVarsFile (
> + IN EFI_HANDLE FsHandle,
> + IN BOOLEAN ReadingFile,
> + OUT EFI_FILE_HANDLE *NvVarsFile
> + )
> +{
> + EFI_STATUS Status;
> + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs;
> + EFI_FILE_HANDLE Root;
> +
> + //
> + // Get the FileSystem protocol on that handle
> + //
> + Status = gBS->HandleProtocol (
> + FsHandle,
> + &gEfiSimpleFileSystemProtocolGuid,
> + (VOID **)&Fs
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // Get the volume (the root directory)
> + //
> + Status = Fs->OpenVolume (Fs, &Root);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // Attempt to open the NvVars file in the root directory
> + //
> + Status = Root->Open (
> + Root,
> + NvVarsFile,
> + L"NvVars",
> + ReadingFile ?
> + EFI_FILE_MODE_READ :
> + (
> + EFI_FILE_MODE_CREATE |
> + EFI_FILE_MODE_READ |
> + EFI_FILE_MODE_WRITE
> + ),
> + 0
> + );
> +
> + return Status;
> +}
> +
> +
> +/**
> + Open the NvVars file for reading or writing
> +
> + @param[in] File - The file to inspect
> + @param[out] Exists - Returns whether the file exists
> + @param[out] Size - Returns the size of the file
> + (0 if the file does not exist)
> +
> +**/
> +VOID
> +NvVarsFileReadCheckup (
> + IN EFI_FILE_HANDLE File,
> + OUT BOOLEAN *Exists,
> + OUT UINTN *Size
> + )
> +{
> + EFI_FILE_INFO *FileInfo;
> +
> + *Exists = FALSE;
> + *Size = 0;
> +
> + FileInfo = FileHandleGetInfo (File);
> + if (FileInfo == NULL) {
> + return;
> + }
> +
> + if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) {
> + FreePool (FileInfo);
> + return;
> + }
> +
> + *Exists = TRUE;
> + *Size = (UINTN) FileInfo->FileSize;
> +
> + FreePool (FileInfo);
> +}
> +
> +
> +/**
> + Open the NvVars file for reading or writing
> +
> + @param[in] File - The file to inspect
> + @param[out] Exists - Returns whether the file exists
> + @param[out] Size - Returns the size of the file
> + (0 if the file does not exist)
> +
> +**/
> +EFI_STATUS
> +FileHandleEmpty (
> + IN EFI_FILE_HANDLE File
> + )
> +{
> + EFI_STATUS Status;
> + EFI_FILE_INFO *FileInfo;
> +
> + //
> + // Retrieve the FileInfo structure
> + //
> + FileInfo = FileHandleGetInfo (File);
> + if (FileInfo == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // If the path is a directory, then return an error
> + //
> + if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) {
> + FreePool (FileInfo);
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // If the file size is already 0, then it is empty, so
> + // we can return success.
> + //
> + if (FileInfo->FileSize == 0) {
> + FreePool (FileInfo);
> + return EFI_SUCCESS;
> + }
> +
> + //
> + // Set the file size to 0.
> + //
> + FileInfo->FileSize = 0;
> + Status = FileHandleSetInfo (File, FileInfo);
> +
> + FreePool (FileInfo);
> +
> + return Status;
> +}
> +
> +
> +/**
> + Reads a file to a newly allocated buffer
> +
> + @param[in] File - The file to read
> + @param[in] ReadSize - The size of data to read from the file
> +
> + @return Pointer to buffer allocated to hold the file
> + contents. NULL if an error occurred.
> +
> +**/
> +VOID*
> +FileHandleReadToNewBuffer (
> + IN EFI_FILE_HANDLE FileHandle,
> + IN UINTN ReadSize
> + )
> +{
> + EFI_STATUS Status;
> + UINTN ActualReadSize;
> + VOID *FileContents;
> +
> + ActualReadSize = ReadSize;
> + FileContents = AllocatePool (ReadSize);
> + if (FileContents != NULL) {
> + Status = FileHandleRead (
> + FileHandle,
> + &ReadSize,
> + FileContents
> + );
> + if (EFI_ERROR (Status) || (ActualReadSize != ReadSize)) {
> + FreePool (FileContents);
> + return NULL;
> + }
> + }
> +
> + return FileContents;
> +}
> +
> +
> +/**
> + Reads the contents of the NvVars file on the file system
> +
> + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid
> instance
> +
> + @return EFI_STATUS based on the success or failure of the file read
> +
> +**/
> +EFI_STATUS
> +ReadNvVarsFile (
> + IN EFI_HANDLE FsHandle
> + )
> +{
> + EFI_STATUS Status;
> + EFI_FILE_HANDLE File;
> + UINTN FileSize;
> + BOOLEAN FileExists;
> + VOID *FileContents;
> + EFI_HANDLE SerializedVariables;
> +
> + Status = GetNvVarsFile (FsHandle, TRUE, &File);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_INFO, "FsAccess.c: Could not open NV Variables file on this
> file system\n"));
> + return Status;
> + }
> +
> + NvVarsFileReadCheckup (File, &FileExists, &FileSize);
> + if (FileSize == 0) {
> + FileHandleClose (File);
> + return EFI_UNSUPPORTED;
> + }
> +
> + FileContents = FileHandleReadToNewBuffer (File, FileSize);
> + if (FileContents == NULL) {
> + FileHandleClose (File);
> + return EFI_UNSUPPORTED;
> + }
> +
> + DEBUG ((
> + EFI_D_INFO,
> + "FsAccess.c: Read %Lu bytes from NV Variables file\n",
> + (UINT64)FileSize
> + ));
> +
> + Status = SerializeVariablesNewInstanceFromBuffer (
> + &SerializedVariables,
> + FileContents,
> + FileSize
> + );
> + if (!RETURN_ERROR (Status)) {
> + Status = SerializeVariablesSetSerializedVariables (SerializedVariables);
> + }
> +
> + FreePool (FileContents);
> + FileHandleClose (File);
> +
> + return Status;
> +}
> +
> +
> +/**
> + Writes a variable to indicate that the NV variables
> + have been loaded from the file system.
> +
> +**/
> +STATIC
> +VOID
> +SetNvVarsVariable (
> + VOID
> + )
> +{
> + BOOLEAN VarData;
> + UINTN Size;
> +
> + //
> + // Write a variable to indicate we've already loaded the
> + // variable data. If it is found, we skip the loading on
> + // subsequent attempts.
> + //
> + Size = sizeof (VarData);
> + VarData = TRUE;
> + gRT->SetVariable (
> + L"NvVars",
> + &gEfiSimpleFileSystemProtocolGuid,
> + EFI_VARIABLE_NON_VOLATILE |
> + EFI_VARIABLE_BOOTSERVICE_ACCESS |
> + EFI_VARIABLE_RUNTIME_ACCESS,
> + Size,
> + (VOID*) &VarData
> + );
> +}
> +
> +
> +/**
> + Loads the non-volatile variables from the NvVars file on the
> + given file system.
> +
> + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid
> instance
> +
> + @return EFI_STATUS based on the success or failure of load operation
> +
> +**/
> +EFI_STATUS
> +LoadNvVarsFromFs (
> + EFI_HANDLE FsHandle
> + )
> +{
> + EFI_STATUS Status;
> + BOOLEAN VarData;
> + UINTN Size;
> +
> + DEBUG ((EFI_D_INFO, "FsAccess.c: LoadNvVarsFromFs\n"));
> +
> + //
> + // We write a variable to indicate we've already loaded the
> + // variable data. If it is found, we skip the loading.
> + //
> + // This is relevant if the non-volatile variable have been
> + // able to survive a reboot operation. In that case, we don't
> + // want to re-load the file as it would overwrite newer changes
> + // made to the variables.
> + //
> + Size = sizeof (VarData);
> + VarData = TRUE;
> + Status = gRT->GetVariable (
> + L"NvVars",
> + &gEfiSimpleFileSystemProtocolGuid,
> + NULL,
> + &Size,
> + (VOID*) &VarData
> + );
> + if (Status == EFI_SUCCESS) {
> + DEBUG ((EFI_D_INFO, "NV Variables were already loaded\n"));
> + return EFI_ALREADY_STARTED;
> + }
> +
> + //
> + // Attempt to restore the variables from the NvVars file.
> + //
> + Status = ReadNvVarsFile (FsHandle);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_INFO, "Error while restoring NV variable data\n"));
> + return Status;
> + }
> +
> + //
> + // Write a variable to indicate we've already loaded the
> + // variable data. If it is found, we skip the loading on
> + // subsequent attempts.
> + //
> + SetNvVarsVariable();
> +
> + DEBUG ((
> + EFI_D_INFO,
> + "FsAccess.c: Read NV Variables file (size=%Lu)\n",
> + (UINT64)Size
> + ));
> +
> + return Status;
> +}
> +
> +
> +STATIC
> +RETURN_STATUS
> +EFIAPI
> +IterateVariablesCallbackAddAllNvVariables (
> + IN VOID *Context,
> + IN CHAR16 *VariableName,
> + IN EFI_GUID *VendorGuid,
> + IN UINT32 Attributes,
> + IN UINTN DataSize,
> + IN VOID *Data
> + )
> +{
> + EFI_HANDLE Instance;
> +
> + Instance = (EFI_HANDLE) Context;
> +
> + //
> + // Only save non-volatile variables
> + //
> + if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {
> + return RETURN_SUCCESS;
> + }
> +
> + return SerializeVariablesAddVariable (
> + Instance,
> + VariableName,
> + VendorGuid,
> + Attributes,
> + DataSize,
> + Data
> + );
> +}
> +
> +
> +/**
> + Saves the non-volatile variables into the NvVars file on the
> + given file system.
> +
> + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid
> instance
> +
> + @return EFI_STATUS based on the success or failure of load operation
> +
> +**/
> +EFI_STATUS
> +SaveNvVarsToFs (
> + EFI_HANDLE FsHandle
> + )
> +{
> + EFI_STATUS Status;
> + EFI_FILE_HANDLE File;
> + UINTN WriteSize;
> + UINTN VariableDataSize;
> + VOID *VariableData;
> + EFI_HANDLE SerializedVariables;
> +
> + SerializedVariables = NULL;
> +
> + Status = SerializeVariablesNewInstance (&SerializedVariables);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Status = SerializeVariablesIterateSystemVariables (
> + IterateVariablesCallbackAddAllNvVariables,
> + (VOID*) SerializedVariables
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + VariableData = NULL;
> + VariableDataSize = 0;
> + Status = SerializeVariablesToBuffer (
> + SerializedVariables,
> + NULL,
> + &VariableDataSize
> + );
> + if (Status == RETURN_BUFFER_TOO_SMALL) {
> + VariableData = AllocatePool (VariableDataSize);
> + if (VariableData == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + } else {
> + Status = SerializeVariablesToBuffer (
> + SerializedVariables,
> + VariableData,
> + &VariableDataSize
> + );
> + }
> + }
> +
> + SerializeVariablesFreeInstance (SerializedVariables);
> +
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // Open the NvVars file for writing.
> + //
> + Status = GetNvVarsFile (FsHandle, FALSE, &File);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_INFO, "FsAccess.c: Unable to open file to saved NV
> Variables\n"));
> + return Status;
> + }
> +
> + //
> + // Empty the starting file contents.
> + //
> + Status = FileHandleEmpty (File);
> + if (EFI_ERROR (Status)) {
> + FileHandleClose (File);
> + return Status;
> + }
> +
> + WriteSize = VariableDataSize;
> + Status = FileHandleWrite (File, &WriteSize, VariableData);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + FileHandleClose (File);
> +
> + if (!EFI_ERROR (Status)) {
> + //
> + // Write a variable to indicate we've already loaded the
> + // variable data. If it is found, we skip the loading on
> + // subsequent attempts.
> + //
> + SetNvVarsVariable();
> +
> + DEBUG ((EFI_D_INFO, "Saved NV Variables to NvVars file\n"));
> + }
> +
> + return Status;
> +}
> +
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.c
> new file mode 100644
> index 0000000000..f60fbc6112
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.c
> @@ -0,0 +1,77 @@
> +/** @file
> + Save Non-Volatile Variables to a file system.
> +
> + Copyright (c) 2009 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "NvVarsFileLib.h"
> +#include <Library/DebugLib.h>
> +#include <Library/NvVarsFileLib.h>
> +
> +EFI_HANDLE mNvVarsFileLibFsHandle = NULL;
> +
> +
> +/**
> + Attempts to connect the NvVarsFileLib to the specified file system.
> +
> + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid
> instance
> +
> + @return The EFI_STATUS while attempting to connect the NvVarsFileLib
> + to the file system instance.
> + @retval EFI_SUCCESS - The given file system was connected successfully
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +ConnectNvVarsToFileSystem (
> + IN EFI_HANDLE FsHandle
> + )
> +{
> + EFI_STATUS Status;
> +
> + //
> + // We might fail to load the variable, since the file system initially
> + // will not have the NvVars file.
> + //
> + LoadNvVarsFromFs (FsHandle);
> +
> + //
> + // We must be able to save the variables successfully to the file system
> + // to have connected successfully.
> + //
> + Status = SaveNvVarsToFs (FsHandle);
> + if (!EFI_ERROR (Status)) {
> + mNvVarsFileLibFsHandle = FsHandle;
> + }
> +
> + return Status;
> +}
> +
> +
> +/**
> + Update non-volatile variables stored on the file system.
> +
> + @return The EFI_STATUS while attempting to update the variable on
> + the connected file system.
> + @retval EFI_SUCCESS - The non-volatile variables were saved to the disk
> + @retval EFI_NOT_STARTED - A file system has not been connected
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdateNvVarsOnFileSystem (
> + )
> +{
> + if (mNvVarsFileLibFsHandle == NULL) {
> + //
> + // A file system had not been connected to the library.
> + //
> + return EFI_NOT_STARTED;
> + } else {
> + return SaveNvVarsToFs (mNvVarsFileLibFsHandle);
> + }
> +}
> +
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> riablesLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> riablesLib.c
> new file mode 100644
> index 0000000000..c32a978550
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> riablesLib.c
> @@ -0,0 +1,869 @@
> +/** @file
> + Serialize Variables Library implementation
> +
> + Copyright (c) 2004 - 2011 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "SerializeVariablesLib.h"
> +
> +/**
> + Serialization format:
> +
> + The SerializeVariablesLib interface does not specify a format
> + for the serialization of the variable data. This library uses
> + a packed array of a non-uniformly sized data structure elements.
> +
> + Each variable is stored (packed) as:
> + UINT32 VendorNameSize; // Name size in bytes
> + CHAR16 VendorName[?]; // The variable unicode name including the
> + // null terminating character.
> + EFI_GUID VendorGuid; // The variable GUID
> + UINT32 DataSize; // The size of variable data in bytes
> + UINT8 Data[?]; // The variable data
> +
> +**/
> +
> +
> +/**
> + Unpacks the next variable from the buffer
> +
> + @param[in] Buffer - Buffer pointing to the next variable instance
> + On subsequent calls, the pointer should be incremented
> + by the returned SizeUsed value.
> + @param[in] MaxSize - Max allowable size for the variable data
> + On subsequent calls, this should be decremented
> + by the returned SizeUsed value.
> + @param[out] Name - Variable name string (address in Buffer)
> + @param[out] NameSize - Size of Name in bytes
> + @param[out] Guid - GUID of variable (address in Buffer)
> + @param[out] Attributes - Attributes of variable
> + @param[out] Data - Buffer containing Data for variable (address in Buffer)
> + @param[out] DataSize - Size of Data in bytes
> + @param[out] SizeUsed - Total size used for this variable instance in Buffer
> +
> + @return EFI_STATUS based on the success or failure of the operation
> +
> +**/
> +STATIC
> +EFI_STATUS
> +UnpackVariableFromBuffer (
> + IN VOID *Buffer,
> + IN UINTN MaxSize,
> + OUT CHAR16 **Name,
> + OUT UINT32 *NameSize,
> + OUT EFI_GUID **Guid,
> + OUT UINT32 *Attributes,
> + OUT UINT32 *DataSize,
> + OUT VOID **Data,
> + OUT UINTN *SizeUsed
> + )
> +{
> + UINT8 *BytePtr;
> + UINTN Offset;
> +
> + BytePtr = (UINT8*)Buffer;
> + Offset = 0;
> +
> + *NameSize = *(UINT32*) (BytePtr + Offset);
> + Offset = Offset + sizeof (UINT32);
> +
> + if (Offset > MaxSize) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *Name = (CHAR16*) (BytePtr + Offset);
> + Offset = Offset + *(UINT32*)BytePtr;
> + if (Offset > MaxSize) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *Guid = (EFI_GUID*) (BytePtr + Offset);
> + Offset = Offset + sizeof (EFI_GUID);
> + if (Offset > MaxSize) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *Attributes = *(UINT32*) (BytePtr + Offset);
> + Offset = Offset + sizeof (UINT32);
> + if (Offset > MaxSize) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *DataSize = *(UINT32*) (BytePtr + Offset);
> + Offset = Offset + sizeof (UINT32);
> + if (Offset > MaxSize) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *Data = (VOID*) (BytePtr + Offset);
> + Offset = Offset + *DataSize;
> + if (Offset > MaxSize) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + *SizeUsed = Offset;
> +
> + return EFI_SUCCESS;
> +}
> +
> +
> +/**
> + Iterates through the variables in the buffer, and calls a callback
> + function for each variable found.
> +
> + @param[in] CallbackFunction - Function called for each variable instance
> + @param[in] Context - Passed to each call of CallbackFunction
> + @param[in] Buffer - Buffer containing serialized variables
> + @param[in] MaxSize - Size of Buffer in bytes
> +
> + @return EFI_STATUS based on the success or failure of the operation
> +
> +**/
> +STATIC
> +EFI_STATUS
> +IterateVariablesInBuffer (
> + IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,
> + IN VOID *CallbackContext,
> + IN VOID *Buffer,
> + IN UINTN MaxSize
> + )
> +{
> + RETURN_STATUS Status;
> + UINTN TotalSizeUsed;
> + UINTN SizeUsed;
> +
> + CHAR16 *Name;
> + UINT32 NameSize;
> + CHAR16 *AlignedName;
> + UINT32 AlignedNameMaxSize;
> + EFI_GUID *Guid;
> + UINT32 Attributes;
> + UINT32 DataSize;
> + VOID *Data;
> +
> + SizeUsed = 0;
> + AlignedName = NULL;
> + AlignedNameMaxSize = 0;
> + Name = NULL;
> + Guid = NULL;
> + Attributes = 0;
> + DataSize = 0;
> + Data = NULL;
> +
> + for (
> + Status = EFI_SUCCESS, TotalSizeUsed = 0;
> + !EFI_ERROR (Status) && (TotalSizeUsed < MaxSize);
> + ) {
> + Status = UnpackVariableFromBuffer (
> + (VOID*) ((UINT8*) Buffer + TotalSizeUsed),
> + (MaxSize - TotalSizeUsed),
> + &Name,
> + &NameSize,
> + &Guid,
> + &Attributes,
> + &DataSize,
> + &Data,
> + &SizeUsed
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // We copy the name to a separately allocated buffer,
> + // to be sure it is 16-bit aligned.
> + //
> + if (NameSize > AlignedNameMaxSize) {
> + if (AlignedName != NULL) {
> + FreePool (AlignedName);
> + }
> + AlignedName = AllocatePool (NameSize);
> + }
> + if (AlignedName == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> + CopyMem (AlignedName, Name, NameSize);
> +
> + TotalSizeUsed = TotalSizeUsed + SizeUsed;
> +
> + //
> + // Run the callback function
> + //
> + Status = (*CallbackFunction) (
> + CallbackContext,
> + AlignedName,
> + Guid,
> + Attributes,
> + DataSize,
> + Data
> + );
> +
> + }
> +
> + if (AlignedName != NULL) {
> + FreePool (AlignedName);
> + }
> +
> + //
> + // Make sure the entire buffer was used, or else return an error
> + //
> + if (TotalSizeUsed != MaxSize) {
> + DEBUG ((
> + EFI_D_ERROR,
> + "Deserialize variables error: TotalSizeUsed(%Lu) != MaxSize(%Lu)\n",
> + (UINT64)TotalSizeUsed,
> + (UINT64)MaxSize
> + ));
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +
> +STATIC
> +RETURN_STATUS
> +EFIAPI
> +IterateVariablesCallbackNop (
> + IN VOID *Context,
> + IN CHAR16 *VariableName,
> + IN EFI_GUID *VendorGuid,
> + IN UINT32 Attributes,
> + IN UINTN DataSize,
> + IN VOID *Data
> + )
> +{
> + return RETURN_SUCCESS;
> +}
> +
> +
> +STATIC
> +RETURN_STATUS
> +EFIAPI
> +IterateVariablesCallbackSetInInstance (
> + IN VOID *Context,
> + IN CHAR16 *VariableName,
> + IN EFI_GUID *VendorGuid,
> + IN UINT32 Attributes,
> + IN UINTN DataSize,
> + IN VOID *Data
> + )
> +{
> + EFI_HANDLE Instance;
> +
> + Instance = (EFI_HANDLE) Context;
> +
> + return SerializeVariablesAddVariable (
> + Instance,
> + VariableName,
> + VendorGuid,
> + Attributes,
> + DataSize,
> + Data
> + );
> +}
> +
> +
> +STATIC
> +RETURN_STATUS
> +EFIAPI
> +IterateVariablesCallbackSetSystemVariable (
> + IN VOID *Context,
> + IN CHAR16 *VariableName,
> + IN EFI_GUID *VendorGuid,
> + IN UINT32 Attributes,
> + IN UINTN DataSize,
> + IN VOID *Data
> + )
> +{
> + EFI_STATUS Status;
> + STATIC CONST UINT32 AuthMask =
> + EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS |
> + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
> +
> + Status = gRT->SetVariable (
> + VariableName,
> + VendorGuid,
> + Attributes,
> + DataSize,
> + Data
> + );
> +
> + if (Status == EFI_SECURITY_VIOLATION && (Attributes & AuthMask) != 0) {
> + DEBUG ((DEBUG_WARN, "%a: setting authenticated variable \"%s\" "
> + "failed with EFI_SECURITY_VIOLATION, ignoring\n", __FUNCTION__,
> + VariableName));
> + Status = EFI_SUCCESS;
> + } else if (Status == EFI_WRITE_PROTECTED) {
> + DEBUG ((DEBUG_WARN, "%a: setting ReadOnly variable \"%s\" "
> + "failed with EFI_WRITE_PROTECTED, ignoring\n", __FUNCTION__,
> + VariableName));
> + Status = EFI_SUCCESS;
> + }
> + return Status;
> +}
> +
> +
> +STATIC
> +RETURN_STATUS
> +EnsureExtraBufferSpace (
> + IN SV_INSTANCE *Instance,
> + IN UINTN Size
> + )
> +{
> + VOID *NewBuffer;
> + UINTN NewSize;
> +
> + NewSize = Instance->DataSize + Size;
> + if (NewSize <= Instance->BufferSize) {
> + return RETURN_SUCCESS;
> + }
> +
> + //
> + // Double the required size to lessen the need to re-allocate in the future
> + //
> + NewSize = 2 * NewSize;
> +
> + NewBuffer = AllocatePool (NewSize);
> + if (NewBuffer == NULL) {
> + return RETURN_OUT_OF_RESOURCES;
> + }
> +
> + if (Instance->BufferPtr != NULL) {
> + CopyMem (NewBuffer, Instance->BufferPtr, Instance->DataSize);
> + FreePool (Instance->BufferPtr);
> + }
> +
> + Instance->BufferPtr = NewBuffer;
> + Instance->BufferSize = NewSize;
> +
> + return RETURN_SUCCESS;
> +}
> +
> +
> +STATIC
> +VOID
> +AppendToBuffer (
> + IN SV_INSTANCE *Instance,
> + IN VOID *Data,
> + IN UINTN Size
> + )
> +{
> + UINTN NewSize;
> +
> + ASSERT (Instance != NULL);
> + ASSERT (Data != NULL);
> +
> + NewSize = Instance->DataSize + Size;
> + ASSERT ((Instance->DataSize + Size) <= Instance->BufferSize);
> +
> + CopyMem (
> + (VOID*) (((UINT8*) (Instance->BufferPtr)) + Instance->DataSize),
> + Data,
> + Size
> + );
> +
> + Instance->DataSize = NewSize;
> +}
> +
> +
> +/**
> + Creates a new variable serialization instance
> +
> + @param[out] Handle - Handle for a variable serialization instance
> +
> + @retval RETURN_SUCCESS - The variable serialization instance was
> + successfully created.
> + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources
> to
> + create the variable serialization instance.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesNewInstance (
> + OUT EFI_HANDLE *Handle
> + )
> +{
> + SV_INSTANCE *New;
> +
> + New = AllocateZeroPool (sizeof (*New));
> + if (New == NULL) {
> + return RETURN_OUT_OF_RESOURCES;
> + }
> +
> + New->Signature = SV_SIGNATURE;
> +
> + *Handle = (EFI_HANDLE) New;
> + return RETURN_SUCCESS;
> +}
> +
> +
> +/**
> + Free memory associated with a variable serialization instance
> +
> + @param[in] Handle - Handle for a variable serialization instance
> +
> + @retval RETURN_SUCCESS - The variable serialization instance was
> + successfully freed.
> + @retval RETURN_INVALID_PARAMETER - Handle was not a valid
> + variable serialization instance.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesFreeInstance (
> + IN EFI_HANDLE Handle
> + )
> +{
> + SV_INSTANCE *Instance;
> +
> + Instance = SV_FROM_HANDLE (Handle);
> +
> + if (Instance->Signature != SV_SIGNATURE) {
> + return RETURN_INVALID_PARAMETER;
> + }
> +
> + Instance->Signature = 0;
> +
> + if (Instance->BufferPtr != NULL) {
> + FreePool (Instance->BufferPtr);
> + }
> +
> + FreePool (Instance);
> +
> + return RETURN_SUCCESS;
> +}
> +
> +
> +/**
> + Creates a new variable serialization instance using the given
> + binary representation of the variables to fill the new instance
> +
> + @param[out] Handle - Handle for a variable serialization instance
> + @param[in] Buffer - A buffer with the serialized representation
> + of the variables. Must be the same format as produced
> + by SerializeVariablesToBuffer.
> + @param[in] Size - This is the size of the binary representation
> + of the variables.
> +
> + @retval RETURN_SUCCESS - The binary representation was successfully
> + imported into a new variable serialization instance
> + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources
> to
> + create the new variable serialization instance
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesNewInstanceFromBuffer (
> + OUT EFI_HANDLE *Handle,
> + IN VOID *Buffer,
> + IN UINTN Size
> + )
> +{
> + RETURN_STATUS Status;
> +
> + Status = SerializeVariablesNewInstance (Handle);
> + if (RETURN_ERROR (Status)) {
> + return Status;
> + }
> +
> + Status = IterateVariablesInBuffer (
> + IterateVariablesCallbackNop,
> + NULL,
> + Buffer,
> + Size
> + );
> + if (RETURN_ERROR (Status)) {
> + SerializeVariablesFreeInstance (*Handle);
> + return Status;
> + }
> +
> + Status = IterateVariablesInBuffer (
> + IterateVariablesCallbackSetInInstance,
> + (VOID*) *Handle,
> + Buffer,
> + Size
> + );
> + if (RETURN_ERROR (Status)) {
> + SerializeVariablesFreeInstance (*Handle);
> + return Status;
> + }
> +
> + return Status;
> +}
> +
> +
> +/**
> + Iterates all variables found with RuntimeServices GetNextVariableName
> +
> + @param[in] CallbackFunction - Function called for each variable instance
> + @param[in] Context - Passed to each call of CallbackFunction
> +
> + @retval RETURN_SUCCESS - All variables were iterated without the
> + CallbackFunction returning an error
> + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources
> to
> + iterate through the variables
> + @return Any of RETURN_ERROR indicates an error reading the variable
> + or an error was returned from CallbackFunction
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesIterateSystemVariables (
> + IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,
> + IN VOID *Context
> + )
> +{
> + RETURN_STATUS Status;
> + UINTN VariableNameBufferSize;
> + UINTN VariableNameSize;
> + CHAR16 *VariableName;
> + EFI_GUID VendorGuid;
> + UINTN VariableDataBufferSize;
> + UINTN VariableDataSize;
> + VOID *VariableData;
> + UINT32 VariableAttributes;
> + VOID *NewBuffer;
> +
> + //
> + // Initialize the variable name and data buffer variables.
> + //
> + VariableNameBufferSize = sizeof (CHAR16);
> + VariableName = AllocateZeroPool (VariableNameBufferSize);
> +
> + VariableDataBufferSize = 0;
> + VariableData = NULL;
> +
> + for (;;) {
> + //
> + // Get the next variable name and guid
> + //
> + VariableNameSize = VariableNameBufferSize;
> + Status = gRT->GetNextVariableName (
> + &VariableNameSize,
> + VariableName,
> + &VendorGuid
> + );
> + if (Status == EFI_BUFFER_TOO_SMALL) {
> + //
> + // The currently allocated VariableName buffer is too small,
> + // so we allocate a larger buffer, and copy the old buffer
> + // to it.
> + //
> + NewBuffer = AllocatePool (VariableNameSize);
> + if (NewBuffer == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + break;
> + }
> + CopyMem (NewBuffer, VariableName, VariableNameBufferSize);
> + if (VariableName != NULL) {
> + FreePool (VariableName);
> + }
> + VariableName = NewBuffer;
> + VariableNameBufferSize = VariableNameSize;
> +
> + //
> + // Try to get the next variable name again with the larger buffer.
> + //
> + Status = gRT->GetNextVariableName (
> + &VariableNameSize,
> + VariableName,
> + &VendorGuid
> + );
> + }
> +
> + if (EFI_ERROR (Status)) {
> + if (Status == EFI_NOT_FOUND) {
> + Status = EFI_SUCCESS;
> + }
> + break;
> + }
> +
> + //
> + // Get the variable data and attributes
> + //
> + VariableDataSize = VariableDataBufferSize;
> + Status = gRT->GetVariable (
> + VariableName,
> + &VendorGuid,
> + &VariableAttributes,
> + &VariableDataSize,
> + VariableData
> + );
> + if (Status == EFI_BUFFER_TOO_SMALL) {
> + //
> + // The currently allocated VariableData buffer is too small,
> + // so we allocate a larger buffer.
> + //
> + if (VariableDataBufferSize != 0) {
> + FreePool (VariableData);
> + VariableData = NULL;
> + VariableDataBufferSize = 0;
> + }
> + VariableData = AllocatePool (VariableDataSize);
> + if (VariableData == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + break;
> + }
> + VariableDataBufferSize = VariableDataSize;
> +
> + //
> + // Try to read the variable again with the larger buffer.
> + //
> + Status = gRT->GetVariable (
> + VariableName,
> + &VendorGuid,
> + &VariableAttributes,
> + &VariableDataSize,
> + VariableData
> + );
> + }
> + if (EFI_ERROR (Status)) {
> + break;
> + }
> +
> + //
> + // Run the callback function
> + //
> + Status = (*CallbackFunction) (
> + Context,
> + VariableName,
> + &VendorGuid,
> + VariableAttributes,
> + VariableDataSize,
> + VariableData
> + );
> + if (EFI_ERROR (Status)) {
> + break;
> + }
> +
> + }
> +
> + if (VariableName != NULL) {
> + FreePool (VariableName);
> + }
> +
> + if (VariableData != NULL) {
> + FreePool (VariableData);
> + }
> +
> + return Status;
> +}
> +
> +
> +/**
> + Iterates all variables found in the variable serialization instance
> +
> + @param[in] Handle - Handle for a variable serialization instance
> + @param[in] CallbackFunction - Function called for each variable instance
> + @param[in] Context - Passed to each call of CallbackFunction
> +
> + @retval RETURN_SUCCESS - All variables were iterated without the
> + CallbackFunction returning an error
> + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources
> to
> + iterate through the variables
> + @return Any of RETURN_ERROR indicates an error reading the variable
> + or an error was returned from CallbackFunction
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesIterateInstanceVariables (
> + IN EFI_HANDLE Handle,
> + IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,
> + IN VOID *Context
> + )
> +{
> + SV_INSTANCE *Instance;
> +
> + Instance = SV_FROM_HANDLE (Handle);
> +
> + if ((Instance->BufferPtr != NULL) && (Instance->DataSize != 0)) {
> + return IterateVariablesInBuffer (
> + CallbackFunction,
> + Context,
> + Instance->BufferPtr,
> + Instance->DataSize
> + );
> + } else {
> + return RETURN_SUCCESS;
> + }
> +}
> +
> +
> +/**
> + Sets all variables found in the variable serialization instance
> +
> + @param[in] Handle - Handle for a variable serialization instance
> +
> + @retval RETURN_SUCCESS - All variables were set successfully
> + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources
> to
> + set all the variables
> + @return Any of RETURN_ERROR indicates an error reading the variables
> + or in attempting to set a variable
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesSetSerializedVariables (
> + IN EFI_HANDLE Handle
> + )
> +{
> + return SerializeVariablesIterateInstanceVariables (
> + Handle,
> + IterateVariablesCallbackSetSystemVariable,
> + NULL
> + );
> +}
> +
> +
> +/**
> + Adds a variable to the variable serialization instance
> +
> + @param[in] Handle - Handle for a variable serialization instance
> + @param[in] VariableName - Refer to RuntimeServices GetVariable
> + @param[in] VendorGuid - Refer to RuntimeServices GetVariable
> + @param[in] Attributes - Refer to RuntimeServices GetVariable
> + @param[in] DataSize - Refer to RuntimeServices GetVariable
> + @param[in] Data - Refer to RuntimeServices GetVariable
> +
> + @retval RETURN_SUCCESS - All variables were set successfully
> + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources
> to
> + add the variable
> + @retval RETURN_INVALID_PARAMETER - Handle was not a valid
> + variable serialization instance or
> + VariableName, VariableGuid or Data are NULL.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesAddVariable (
> + IN EFI_HANDLE Handle,
> + IN CHAR16 *VariableName,
> + IN EFI_GUID *VendorGuid,
> + IN UINT32 Attributes,
> + IN UINTN DataSize,
> + IN VOID *Data
> + )
> +{
> + RETURN_STATUS Status;
> + SV_INSTANCE *Instance;
> + UINT32 SerializedNameSize;
> + UINT32 SerializedDataSize;
> + UINTN SerializedSize;
> +
> + Instance = SV_FROM_HANDLE (Handle);
> +
> + if ((Instance->Signature != SV_SIGNATURE) ||
> + (VariableName == NULL) || (VendorGuid == NULL) || (Data == NULL)) {
> + }
> +
> + SerializedNameSize = (UINT32) StrSize (VariableName);
> +
> + SerializedSize =
> + sizeof (SerializedNameSize) +
> + SerializedNameSize +
> + sizeof (*VendorGuid) +
> + sizeof (Attributes) +
> + sizeof (SerializedDataSize) +
> + DataSize;
> +
> + Status = EnsureExtraBufferSpace (
> + Instance,
> + SerializedSize
> + );
> + if (RETURN_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // Add name size (UINT32)
> + //
> + AppendToBuffer (Instance, (VOID*) &SerializedNameSize, sizeof
> (SerializedNameSize));
> +
> + //
> + // Add variable unicode name string
> + //
> + AppendToBuffer (Instance, (VOID*) VariableName, SerializedNameSize);
> +
> + //
> + // Add variable GUID
> + //
> + AppendToBuffer (Instance, (VOID*) VendorGuid, sizeof (*VendorGuid));
> +
> + //
> + // Add variable attributes
> + //
> + AppendToBuffer (Instance, (VOID*) &Attributes, sizeof (Attributes));
> +
> + //
> + // Add variable data size (UINT32)
> + //
> + SerializedDataSize = (UINT32) DataSize;
> + AppendToBuffer (Instance, (VOID*) &SerializedDataSize, sizeof
> (SerializedDataSize));
> +
> + //
> + // Add variable data
> + //
> + AppendToBuffer (Instance, Data, DataSize);
> +
> + return RETURN_SUCCESS;
> +}
> +
> +
> +/**
> + Serializes the variables known to this instance into the
> + provided buffer.
> +
> + @param[in] Handle - Handle for a variable serialization instance
> + @param[out] Buffer - A buffer to store the binary representation
> + of the variables.
> + @param[in,out] Size - On input this is the size of the buffer.
> + On output this is the size of the binary representation
> + of the variables.
> +
> + @retval RETURN_SUCCESS - The binary representation was successfully
> + completed and returned in the buffer.
> + @retval RETURN_OUT_OF_RESOURCES - There we not enough resources
> to
> + save the variables to the buffer.
> + @retval RETURN_INVALID_PARAMETER - Handle was not a valid
> + variable serialization instance or
> + Size or Buffer were NULL.
> + @retval RETURN_BUFFER_TOO_SMALL - The Buffer size as indicated by
> + the Size parameter was too small for the serialized
> + variable data. Size is returned with the required size.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerializeVariablesToBuffer (
> + IN EFI_HANDLE Handle,
> + OUT VOID *Buffer,
> + IN OUT UINTN *Size
> + )
> +{
> + SV_INSTANCE *Instance;
> +
> + Instance = SV_FROM_HANDLE (Handle);
> +
> + if (Size == NULL) {
> + return RETURN_INVALID_PARAMETER;
> + }
> +
> + if (*Size < Instance->DataSize) {
> + *Size = Instance->DataSize;
> + return RETURN_BUFFER_TOO_SMALL;
> + }
> +
> + if (Buffer == NULL) {
> + return RETURN_INVALID_PARAMETER;
> + }
> +
> + *Size = Instance->DataSize;
> + CopyMem (Buffer, Instance->BufferPtr, Instance->DataSize);
> +
> + return RETURN_SUCCESS;
> +}
> +
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c
> new file mode 100644
> index 0000000000..7bede1496d
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c
> @@ -0,0 +1,865 @@
> +/** @file
> + This driver effectuates OVMF's platform configuration settings and exposes
> + them via HII.
> +
> + Copyright (C) 2014, Red Hat, Inc.
> + Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/HiiLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiHiiServicesLib.h>
> +#include <Protocol/DevicePath.h>
> +#include <Protocol/GraphicsOutput.h>
> +#include <Protocol/HiiConfigAccess.h>
> +#include <Guid/MdeModuleHii.h>
> +#include <Guid/SimicsX58PlatformConfig.h>
> +
> +#include "Platform.h"
> +#include "PlatformConfig.h"
> +#include <Library/DxeServicesTableLib.h>
> +//
> +// The HiiAddPackages() library function requires that any controller (or
> +// image) handle, to be associated with the HII packages under installation, be
> +// "decorated" with a device path. The tradition seems to be a vendor device
> +// path.
> +//
> +// We'd like to associate our HII packages with the driver's image handle. The
> +// first idea is to use the driver image's device path. Unfortunately, loaded
> +// images only come with an EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL
> (not the
> +// usual EFI_DEVICE_PATH_PROTOCOL), ie. a different GUID. In addition, even
> the
> +// EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL interface may be NULL, if
> the image
> +// has been loaded from an "unnamed" memory source buffer.
> +//
> +// Hence let's just stick with the tradition -- use a dedicated vendor device
> +// path, with the driver's FILE_GUID.
> +//
> +#pragma pack(1)
> +typedef struct {
> + VENDOR_DEVICE_PATH VendorDevicePath;
> + EFI_DEVICE_PATH_PROTOCOL End;
> +} PKG_DEVICE_PATH;
> +#pragma pack()
> +
> +STATIC PKG_DEVICE_PATH mPkgDevicePath = {
> + {
> + {
> + HARDWARE_DEVICE_PATH,
> + HW_VENDOR_DP,
> + {
> + (UINT8) (sizeof (VENDOR_DEVICE_PATH) ),
> + (UINT8) (sizeof (VENDOR_DEVICE_PATH) >> 8)
> + }
> + },
> + EFI_CALLER_ID_GUID
> + },
> + {
> + END_DEVICE_PATH_TYPE,
> + END_ENTIRE_DEVICE_PATH_SUBTYPE,
> + {
> + (UINT8) (END_DEVICE_PATH_LENGTH ),
> + (UINT8) (END_DEVICE_PATH_LENGTH >> 8)
> + }
> + }
> +};
> +
> +//
> +// The configuration interface between the HII engine (form display etc) and
> +// this driver.
> +//
> +STATIC EFI_HII_CONFIG_ACCESS_PROTOCOL mConfigAccess;
> +
> +//
> +// The handle representing our list of packages after installation.
> +//
> +STATIC EFI_HII_HANDLE mInstalledPackages;
> +
> +//
> +// The arrays below constitute our HII package list. They are auto-generated by
> +// the VFR compiler and linked into the driver image during the build.
> +//
> +// - The strings package receives its C identifier from the driver's BASE_NAME,
> +// plus "Strings".
> +//
> +// - The forms package receives its C identifier from the VFR file's basename,
> +// plus "Bin".
> +//
> +//
> +extern UINT8 PlatformDxeStrings[];
> +extern UINT8 PlatformFormsBin[];
> +
> +//
> +// We want to be notified about GOP installations until we find one GOP
> +// interface that lets us populate the form.
> +//
> +STATIC EFI_EVENT mGopEvent;
> +
> +//
> +// The registration record underneath this pointer allows us to iterate through
> +// the GOP instances one by one.
> +//
> +STATIC VOID *mGopTracker;
> +
> +//
> +// Cache the resolutions we get from the GOP.
> +//
> +typedef struct {
> + UINT32 X;
> + UINT32 Y;
> +} GOP_MODE;
> +
> +STATIC UINTN mNumGopModes;
> +STATIC GOP_MODE *mGopModes;
> +
> +
> +/**
> + Load the persistent platform configuration and translate it to binary form
> + state.
> +
> + If the platform configuration is missing, then the function fills in a
> + default state.
> +
> + @param[out] MainFormState Binary form/widget state after translation.
> +
> + @retval EFI_SUCCESS Form/widget state ready.
> + @return Error codes from underlying functions.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +PlatformConfigToFormState (
> + OUT MAIN_FORM_STATE *MainFormState
> + )
> +{
> + EFI_STATUS Status;
> + PLATFORM_CONFIG PlatformConfig;
> + UINT64 OptionalElements;
> + UINTN ModeNumber;
> +
> + ZeroMem (MainFormState, sizeof *MainFormState);
> +
> + Status = PlatformConfigLoad (&PlatformConfig, &OptionalElements);
> + switch (Status) {
> + case EFI_SUCCESS:
> + if (OptionalElements & PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION) {
> + //
> + // Format the preferred resolution as text.
> + //
> + UnicodeSPrintAsciiFormat (
> + (CHAR16 *) MainFormState->CurrentPreferredResolution,
> + sizeof MainFormState->CurrentPreferredResolution,
> + "%Ldx%Ld",
> + (INT64) PlatformConfig.HorizontalResolution,
> + (INT64) PlatformConfig.VerticalResolution);
> +
> + //
> + // Try to locate it in the drop-down list too. This may not succeed, but
> + // that's fine.
> + //
> + for (ModeNumber = 0; ModeNumber < mNumGopModes;
> ++ModeNumber) {
> + if (mGopModes[ModeNumber].X == PlatformConfig.HorizontalResolution
> &&
> + mGopModes[ModeNumber].Y == PlatformConfig.VerticalResolution) {
> + MainFormState->NextPreferredResolution = (UINT32) ModeNumber;
> + break;
> + }
> + }
> +
> + break;
> + }
> + //
> + // fall through otherwise
> + //
> +
> + case EFI_NOT_FOUND:
> + UnicodeSPrintAsciiFormat (
> + (CHAR16 *) MainFormState->CurrentPreferredResolution,
> + sizeof MainFormState->CurrentPreferredResolution,
> + "Unset");
> + break;
> +
> + default:
> + return Status;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +
> +/**
> + This function is called by the HII machinery when it fetches the form state.
> +
> + See the precise documentation in the UEFI spec.
> +
> + @param[in] This The Config Access Protocol instance.
> +
> + @param[in] Request A <ConfigRequest> format UCS-2 string describing the
> + query.
> +
> + @param[out] Progress A pointer into Request on output, identifying the
> query
> + element where processing failed.
> +
> + @param[out] Results A <MultiConfigAltResp> format UCS-2 string that has
> + all values filled in for the names in the Request
> + string.
> +
> + @retval EFI_SUCCESS Extraction of form state in <MultiConfigAltResp>
> + encoding successful.
> + @return Status codes from underlying functions.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +ExtractConfig (
> + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> + IN CONST EFI_STRING Request,
> + OUT EFI_STRING *Progress,
> + OUT EFI_STRING *Results
> +)
> +{
> + MAIN_FORM_STATE MainFormState;
> + EFI_STATUS Status;
> +
> + DEBUG ((EFI_D_VERBOSE, "%a: Request=\"%s\"\n", __FUNCTION__,
> Request));
> +
> + Status = PlatformConfigToFormState (&MainFormState);
> + if (EFI_ERROR (Status)) {
> + *Progress = Request;
> + return Status;
> + }
> +
> + //
> + // Answer the textual request keying off the binary form state.
> + //
> + Status = gHiiConfigRouting->BlockToConfig (gHiiConfigRouting, Request,
> + (VOID *) &MainFormState, sizeof MainFormState,
> + Results, Progress);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_ERROR, "%a: BlockToConfig(): %r, Progress=\"%s\"\n",
> + __FUNCTION__, Status, (Status == EFI_DEVICE_ERROR) ? NULL :
> *Progress));
> + } else {
> + DEBUG ((EFI_D_VERBOSE, "%a: Results=\"%s\"\n", __FUNCTION__,
> *Results));
> + }
> + return Status;
> +}
> +
> +
> +/**
> + Interpret the binary form state and save it as persistent platform
> + configuration.
> +
> + @param[in] MainFormState Binary form/widget state to verify and save.
> +
> + @retval EFI_SUCCESS Platform configuration saved.
> + @return Error codes from underlying functions.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +FormStateToPlatformConfig (
> + IN CONST MAIN_FORM_STATE *MainFormState
> + )
> +{
> + EFI_STATUS Status;
> + PLATFORM_CONFIG PlatformConfig;
> + CONST GOP_MODE *GopMode;
> +
> + //
> + // There's nothing to do with the textual CurrentPreferredResolution field.
> + // We verify and translate the selection in the drop-down list.
> + //
> + if (MainFormState->NextPreferredResolution >= mNumGopModes) {
> + return EFI_INVALID_PARAMETER;
> + }
> + GopMode = mGopModes + MainFormState->NextPreferredResolution;
> +
> + ZeroMem (&PlatformConfig, sizeof PlatformConfig);
> + PlatformConfig.HorizontalResolution = GopMode->X;
> + PlatformConfig.VerticalResolution = GopMode->Y;
> +
> + Status = PlatformConfigSave (&PlatformConfig);
> + return Status;
> +}
> +
> +
> +/**
> + This function is called by the HII machinery when it wants the driver to
> + interpret and persist the form state.
> +
> + See the precise documentation in the UEFI spec.
> +
> + @param[in] This The Config Access Protocol instance.
> +
> + @param[in] Configuration A <ConfigResp> format UCS-2 string describing
> the
> + form state.
> +
> + @param[out] Progress A pointer into Configuration on output,
> + identifying the element where processing failed.
> +
> + @retval EFI_SUCCESS Configuration verified, state permanent.
> +
> + @return Status codes from underlying functions.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +RouteConfig (
> + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> + IN CONST EFI_STRING Configuration,
> + OUT EFI_STRING *Progress
> +)
> +{
> + MAIN_FORM_STATE MainFormState;
> + UINTN BlockSize;
> + EFI_STATUS Status;
> +
> + DEBUG ((EFI_D_VERBOSE, "%a: Configuration=\"%s\"\n", __FUNCTION__,
> + Configuration));
> +
> + //
> + // the "read" step in RMW
> + //
> + Status = PlatformConfigToFormState (&MainFormState);
> + if (EFI_ERROR (Status)) {
> + *Progress = Configuration;
> + return Status;
> + }
> +
> + //
> + // the "modify" step in RMW
> + //
> + // (Update the binary form state. This update may be partial, which is why in
> + // general we must pre-load the form state from the platform config.)
> + //
> + BlockSize = sizeof MainFormState;
> + Status = gHiiConfigRouting->ConfigToBlock (gHiiConfigRouting, Configuration,
> + (VOID *) &MainFormState, &BlockSize, Progress);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_ERROR, "%a: ConfigToBlock(): %r, Progress=\"%s\"\n",
> + __FUNCTION__, Status,
> + (Status == EFI_BUFFER_TOO_SMALL) ? NULL : *Progress));
> + return Status;
> + }
> +
> + //
> + // the "write" step in RMW
> + //
> + Status = FormStateToPlatformConfig (&MainFormState);
> + if (EFI_ERROR (Status)) {
> + *Progress = Configuration;
> + }
> + return Status;
> +}
> +
> +
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +Callback (
> + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> + IN EFI_BROWSER_ACTION Action,
> + IN EFI_QUESTION_ID QuestionId,
> + IN UINT8 Type,
> + IN OUT EFI_IFR_TYPE_VALUE *Value,
> + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
> + )
> +{
> + DEBUG ((EFI_D_VERBOSE, "%a: Action=0x%Lx QuestionId=%d Type=%d\n",
> + __FUNCTION__, (UINT64) Action, QuestionId, Type));
> +
> + if (Action != EFI_BROWSER_ACTION_CHANGED) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + switch (QuestionId) {
> + case QUESTION_SAVE_EXIT:
> + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
> + break;
> +
> + case QUESTION_DISCARD_EXIT:
> + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
> + break;
> +
> + default:
> + break;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +
> +/**
> + Query and save all resolutions supported by the GOP.
> +
> + @param[in] Gop The Graphics Output Protocol instance to query.
> +
> + @param[out] NumGopModes The number of modes supported by the GOP.
> On output,
> + this parameter will be positive.
> +
> + @param[out] GopModes On output, a dynamically allocated array
> containing
> + the resolutions returned by the GOP. The caller is
> + responsible for freeing the array after use.
> +
> + @retval EFI_UNSUPPORTED No modes found.
> + @retval EFI_OUT_OF_RESOURCES Failed to allocate GopModes.
> + @return Error codes from Gop->QueryMode().
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +QueryGopModes (
> + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop,
> + OUT UINTN *NumGopModes,
> + OUT GOP_MODE **GopModes
> + )
> +{
> + EFI_STATUS Status;
> + UINT32 ModeNumber;
> +
> + if (Gop->Mode->MaxMode == 0) {
> + return EFI_UNSUPPORTED;
> + }
> + *NumGopModes = Gop->Mode->MaxMode;
> +
> + *GopModes = AllocatePool (Gop->Mode->MaxMode * sizeof **GopModes);
> + if (*GopModes == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + for (ModeNumber = 0; ModeNumber < Gop->Mode->MaxMode;
> ++ModeNumber) {
> + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
> + UINTN SizeOfInfo;
> +
> + Status = Gop->QueryMode (Gop, ModeNumber, &SizeOfInfo, &Info);
> + if (EFI_ERROR (Status)) {
> + goto FreeGopModes;
> + }
> +
> + (*GopModes)[ModeNumber].X = Info->HorizontalResolution;
> + (*GopModes)[ModeNumber].Y = Info->VerticalResolution;
> + FreePool (Info);
> + }
> +
> + return EFI_SUCCESS;
> +
> +FreeGopModes:
> + FreePool (*GopModes);
> +
> + return Status;
> +}
> +
> +
> +/**
> + Create a set of "one-of-many" (ie. "drop down list") option IFR opcodes,
> + based on available GOP resolutions, to be placed under a "one-of-many" (ie.
> + "drop down list") opcode.
> +
> + @param[in] PackageList The package list with the formset and form for
> + which the drop down options are produced. Option
> + names are added as new strings to PackageList.
> +
> + @param[out] OpCodeBuffer On output, a dynamically allocated opcode
> buffer
> + with drop down list options corresponding to GOP
> + resolutions. The caller is responsible for freeing
> + OpCodeBuffer with HiiFreeOpCodeHandle() after use.
> +
> + @param[in] NumGopModes Number of entries in GopModes.
> +
> + @param[in] GopModes Array of resolutions retrieved from the GOP.
> +
> + @retval EFI_SUCESS Opcodes have been successfully produced.
> +
> + @return Status codes from underlying functions. PackageList may
> + have been extended with new strings. OpCodeBuffer is
> + unchanged.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +CreateResolutionOptions (
> + IN EFI_HII_HANDLE *PackageList,
> + OUT VOID **OpCodeBuffer,
> + IN UINTN NumGopModes,
> + IN GOP_MODE *GopModes
> + )
> +{
> + EFI_STATUS Status;
> + VOID *OutputBuffer;
> + UINTN ModeNumber;
> +
> + OutputBuffer = HiiAllocateOpCodeHandle ();
> + if (OutputBuffer == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + for (ModeNumber = 0; ModeNumber < NumGopModes; ++ModeNumber) {
> + CHAR16 Desc[MAXSIZE_RES_CUR];
> + EFI_STRING_ID NewString;
> + VOID *OpCode;
> +
> + UnicodeSPrintAsciiFormat (Desc, sizeof Desc, "%Ldx%Ld",
> + (INT64) GopModes[ModeNumber].X, (INT64)
> GopModes[ModeNumber].Y);
> + NewString = HiiSetString (PackageList, 0 /* new string */, Desc,
> + NULL /* for all languages */);
> + if (NewString == 0) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto FreeOutputBuffer;
> + }
> + OpCode = HiiCreateOneOfOptionOpCode (OutputBuffer, NewString,
> + 0 /* Flags */, EFI_IFR_NUMERIC_SIZE_4, ModeNumber);
> + if (OpCode == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto FreeOutputBuffer;
> + }
> + }
> +
> + *OpCodeBuffer = OutputBuffer;
> + return EFI_SUCCESS;
> +
> +FreeOutputBuffer:
> + HiiFreeOpCodeHandle (OutputBuffer);
> +
> + return Status;
> +}
> +
> +
> +/**
> + Populate the form identified by the (PackageList, FormSetGuid, FormId)
> + triplet.
> +
> + The drop down list of video resolutions is generated from (NumGopModes,
> + GopModes).
> +
> + @retval EFI_SUCESS Form successfully updated.
> + @return Status codes from underlying functions.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +PopulateForm (
> + IN EFI_HII_HANDLE *PackageList,
> + IN EFI_GUID *FormSetGuid,
> + IN EFI_FORM_ID FormId,
> + IN UINTN NumGopModes,
> + IN GOP_MODE *GopModes
> + )
> +{
> + EFI_STATUS Status;
> + VOID *OpCodeBuffer;
> + VOID *OpCode;
> + EFI_IFR_GUID_LABEL *Anchor;
> + VOID *OpCodeBuffer2;
> +
> + OpCodeBuffer2 = NULL;
> +
> + //
> + // 1. Allocate an empty opcode buffer.
> + //
> + OpCodeBuffer = HiiAllocateOpCodeHandle ();
> + if (OpCodeBuffer == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // 2. Create a label opcode (which is a Tiano extension) inside the buffer.
> + // The label's number must match the "anchor" label in the form.
> + //
> + OpCode = HiiCreateGuidOpCode (OpCodeBuffer, &gEfiIfrTianoGuid,
> + NULL /* optional copy origin */, sizeof *Anchor);
> + if (OpCode == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto FreeOpCodeBuffer;
> + }
> + Anchor = OpCode;
> + Anchor->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> + Anchor->Number = LABEL_RES_NEXT;
> +
> + //
> + // 3. Create the opcodes inside the buffer that are to be inserted into the
> + // form.
> + //
> + // 3.1. Get a list of resolutions.
> + //
> + Status = CreateResolutionOptions (PackageList, &OpCodeBuffer2,
> + NumGopModes, GopModes);
> + if (EFI_ERROR (Status)) {
> + goto FreeOpCodeBuffer;
> + }
> +
> + //
> + // 3.2. Create a one-of-many question with the above options.
> + //
> + OpCode = HiiCreateOneOfOpCode (
> + OpCodeBuffer, // create opcode inside this
> + // opcode buffer,
> + QUESTION_RES_NEXT, // ID of question,
> + FORMSTATEID_MAIN_FORM, // identifies form state
> + // storage,
> + (UINT16) OFFSET_OF (MAIN_FORM_STATE, // value of question stored
> + NextPreferredResolution), // at this offset,
> + STRING_TOKEN (STR_RES_NEXT), // Prompt,
> + STRING_TOKEN (STR_RES_NEXT_HELP), // Help,
> + 0, // QuestionFlags,
> + EFI_IFR_NUMERIC_SIZE_4, // see sizeof
> + // NextPreferredResolution,
> + OpCodeBuffer2, // buffer with possible
> + // choices,
> + NULL // DEFAULT opcodes
> + );
> + if (OpCode == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto FreeOpCodeBuffer2;
> + }
> +
> + //
> + // 4. Update the form with the opcode buffer.
> + //
> + Status = HiiUpdateForm (PackageList, FormSetGuid, FormId,
> + OpCodeBuffer, // buffer with head anchor, and new contents to be
> + // inserted at it
> + NULL // buffer with tail anchor, for deleting old
> + // contents up to it
> + );
> +
> +FreeOpCodeBuffer2:
> + HiiFreeOpCodeHandle (OpCodeBuffer2);
> +
> +FreeOpCodeBuffer:
> + HiiFreeOpCodeHandle (OpCodeBuffer);
> +
> + return Status;
> +}
> +
> +
> +/**
> + Load and execute the platform configuration.
> +
> + @retval EFI_SUCCESS Configuration loaded and executed.
> + @return Status codes from PlatformConfigLoad().
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +ExecutePlatformConfig (
> + VOID
> + )
> +{
> + EFI_STATUS Status;
> + PLATFORM_CONFIG PlatformConfig;
> + UINT64 OptionalElements;
> +
> + Status = PlatformConfigLoad (&PlatformConfig, &OptionalElements);
> + if (EFI_ERROR (Status)) {
> + DEBUG (((Status == EFI_NOT_FOUND) ? EFI_D_VERBOSE : EFI_D_ERROR,
> + "%a: failed to load platform config: %r\n", __FUNCTION__, Status));
> + return Status;
> + }
> +
> + if (OptionalElements & PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION) {
> + //
> + // Pass the preferred resolution to GraphicsConsoleDxe via dynamic PCDs.
> + //
> + PcdSet32 (PcdVideoHorizontalResolution,
> + PlatformConfig.HorizontalResolution);
> + PcdSet32 (PcdVideoVerticalResolution,
> + PlatformConfig.VerticalResolution);
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +
> +/**
> + Notification callback for GOP interface installation.
> +
> + @param[in] Event Event whose notification function is being invoked.
> +
> + @param[in] Context The pointer to the notification function's context, which
> + is implementation-dependent.
> +**/
> +STATIC
> +VOID
> +EFIAPI
> +GopInstalled (
> + IN EFI_EVENT Event,
> + IN VOID *Context
> + )
> +{
> + EFI_STATUS Status;
> + EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
> +
> + ASSERT (Event == mGopEvent);
> +
> + //
> + // Check further GOPs.
> + //
> + for (;;) {
> + mNumGopModes = 0;
> + mGopModes = NULL;
> +
> + Status = gBS->LocateProtocol (&gEfiGraphicsOutputProtocolGuid,
> mGopTracker,
> + (VOID **) &Gop);
> + if (EFI_ERROR (Status)) {
> + return;
> + }
> +
> + Status = QueryGopModes (Gop, &mNumGopModes, &mGopModes);
> + if (EFI_ERROR (Status)) {
> + continue;
> + }
> +
> + Status = PopulateForm (mInstalledPackages,
> &gSimicsX58PlatformConfigGuid,
> + FORMID_MAIN_FORM, mNumGopModes, mGopModes);
> + if (EFI_ERROR (Status)) {
> + FreePool (mGopModes);
> + continue;
> + }
> +
> + break;
> + }
> +
> + //
> + // Success -- so uninstall this callback. Closing the event removes all
> + // pending notifications and all protocol registrations.
> + //
> + Status = gBS->CloseEvent (mGopEvent);
> + ASSERT_EFI_ERROR (Status);
> + mGopEvent = NULL;
> + mGopTracker = NULL;
> +}
> +
> +
> +/**
> + Entry point for this driver.
> +
> + @param[in] ImageHandle Image handle of this driver.
> + @param[in] SystemTable Pointer to SystemTable.
> +
> + @retval EFI_SUCESS Driver has loaded successfully.
> + @retval EFI_OUT_OF_RESOURCES Failed to install HII packages.
> + @return Error codes from lower level functions.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +PlatformInit (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + EFI_STATUS Status;
> +
> + ExecutePlatformConfig ();
> +
> + mConfigAccess.ExtractConfig = &ExtractConfig;
> + mConfigAccess.RouteConfig = &RouteConfig;
> + mConfigAccess.Callback = &Callback;
> +
> + //
> + // Declare ourselves suitable for HII communication.
> + //
> + Status = gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
> + &gEfiDevicePathProtocolGuid, &mPkgDevicePath,
> + &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess,
> + NULL);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // Publish the HII package list to HII Database.
> + //
> + mInstalledPackages = HiiAddPackages (
> + &gEfiCallerIdGuid, // PackageListGuid
> + ImageHandle, // associated DeviceHandle
> + PlatformDxeStrings, // 1st package
> + PlatformFormsBin, // 2nd package
> + NULL // terminator
> + );
> + if (mInstalledPackages == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto UninstallProtocols;
> + }
> +
> + Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
> &GopInstalled,
> + NULL /* Context */, &mGopEvent);
> + if (EFI_ERROR (Status)) {
> + goto RemovePackages;
> + }
> +
> + Status = gBS->RegisterProtocolNotify (&gEfiGraphicsOutputProtocolGuid,
> + mGopEvent, &mGopTracker);
> + if (EFI_ERROR (Status)) {
> + goto CloseGopEvent;
> + }
> +
> + //
> + // Check already installed GOPs.
> + //
> + Status = gBS->SignalEvent (mGopEvent);
> + ASSERT_EFI_ERROR (Status);
> +
> + return EFI_SUCCESS;
> +
> +CloseGopEvent:
> + gBS->CloseEvent (mGopEvent);
> +
> +RemovePackages:
> + HiiRemovePackages (mInstalledPackages);
> +
> +UninstallProtocols:
> + gBS->UninstallMultipleProtocolInterfaces (ImageHandle,
> + &gEfiDevicePathProtocolGuid, &mPkgDevicePath,
> + &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess,
> + NULL);
> + return Status;
> +}
> +
> +/**
> + Unload the driver.
> +
> + @param[in] ImageHandle Handle that identifies the image to evict.
> +
> + @retval EFI_SUCCESS The image has been unloaded.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PlatformUnload (
> + IN EFI_HANDLE ImageHandle
> + )
> +{
> + if (mGopEvent == NULL) {
> + //
> + // The GOP callback ran successfully and unregistered itself. Release the
> + // resources allocated there.
> + //
> + ASSERT (mGopModes != NULL);
> + FreePool (mGopModes);
> + } else {
> + //
> + // Otherwise we need to unregister the callback.
> + //
> + ASSERT (mGopModes == NULL);
> + gBS->CloseEvent (mGopEvent);
> + }
> +
> + //
> + // Release resources allocated by the entry point.
> + //
> + HiiRemovePackages (mInstalledPackages);
> + gBS->UninstallMultipleProtocolInterfaces (ImageHandle,
> + &gEfiDevicePathProtocolGuid, &mPkgDevicePath,
> + &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess,
> + NULL);
> + return EFI_SUCCESS;
> +}
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c
> new file mode 100644
> index 0000000000..b3b2b34064
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c
> @@ -0,0 +1,123 @@
> +/** @file
> + Utility functions for serializing (persistently storing) and deserializing
> + OVMF's platform configuration.
> +
> + Copyright (C) 2014, Red Hat, Inc.
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Guid/SimicsX58PlatformConfig.h>
> +
> +#include "PlatformConfig.h"
> +
> +//
> +// Name of the UEFI variable that we use for persistent storage.
> +//
> +STATIC CHAR16 mVariableName[] = L"PlatformConfig";
> +
> +
> +/**
> + Serialize and persistently save platform configuration.
> +
> + @param[in] PlatformConfig The platform configuration to serialize and save.
> +
> + @return Status codes returned by gRT->SetVariable().
> +**/
> +EFI_STATUS
> +EFIAPI
> +PlatformConfigSave (
> + IN PLATFORM_CONFIG *PlatformConfig
> + )
> +{
> + EFI_STATUS Status;
> +
> + //
> + // We could implement any kind of translation here, as part of serialization.
> + // For example, we could expose the platform configuration in separate
> + // variables with human-readable contents, allowing other tools to access
> + // them more easily. For now, just save a binary dump.
> + //
> + Status = gRT->SetVariable (mVariableName, &gSimicsX58PlatformConfigGuid,
> + EFI_VARIABLE_NON_VOLATILE |
> EFI_VARIABLE_BOOTSERVICE_ACCESS |
> + EFI_VARIABLE_RUNTIME_ACCESS,
> + sizeof *PlatformConfig, PlatformConfig);
> + return Status;
> +}
> +
> +
> +/**
> + Load and deserialize platform configuration.
> +
> + When the function fails, output parameters are indeterminate.
> +
> + @param[out] PlatformConfig The platform configuration to receive the
> + loaded data.
> +
> + @param[out] OptionalElements This bitmap describes the presence of
> optional
> + configuration elements that have been loaded.
> + PLATFORM_CONFIG_F_DOWNGRADE means that some
> + unknown elements, present in the wire format,
> + have been ignored.
> +
> + @retval EFI_SUCCESS Loading & deserialization successful.
> + @return Error codes returned by GetVariable2().
> +**/
> +EFI_STATUS
> +EFIAPI
> +PlatformConfigLoad (
> + OUT PLATFORM_CONFIG *PlatformConfig,
> + OUT UINT64 *OptionalElements
> + )
> +{
> + VOID *Data;
> + UINTN DataSize;
> + EFI_STATUS Status;
> +
> + //
> + // Any translation done in PlatformConfigSave() would have to be mirrored
> + // here. For now, just load the binary dump.
> + //
> + // Versioning of the binary wire format is implemented based on size
> + // (only incremental changes, ie. new fields), and on GUID.
> + // (Incompatible changes require a GUID change.)
> + //
> + Status = GetVariable2 (mVariableName, &gSimicsX58PlatformConfigGuid,
> &Data,
> + &DataSize);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + *OptionalElements = 0;
> + if (DataSize > sizeof *PlatformConfig) {
> + //
> + // Handle firmware downgrade -- keep only leading part.
> + //
> + CopyMem (PlatformConfig, Data, sizeof *PlatformConfig);
> + *OptionalElements |= PLATFORM_CONFIG_F_DOWNGRADE;
> + } else {
> + CopyMem (PlatformConfig, Data, DataSize);
> +
> + //
> + // Handle firmware upgrade -- zero out missing fields.
> + //
> + ZeroMem ((UINT8 *)PlatformConfig + DataSize,
> + sizeof *PlatformConfig - DataSize);
> + }
> +
> + //
> + // Based on DataSize, report the optional features that we recognize.
> + //
> + if (DataSize >= (OFFSET_OF (PLATFORM_CONFIG, VerticalResolution) +
> + sizeof PlatformConfig->VerticalResolution)) {
> + *OptionalElements |= PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION;
> + }
> +
> + FreePool (Data);
> + return EFI_SUCCESS;
> +}
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c
> new file mode 100644
> index 0000000000..fa2c22116c
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c
> @@ -0,0 +1,57 @@
> +/** @file
> + PC/AT CMOS access routines
> +
> + Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "Cmos.h"
> +#include "Library/IoLib.h"
> +
> +/**
> + Reads 8-bits of CMOS data.
> +
> + Reads the 8-bits of CMOS data at the location specified by Index.
> + The 8-bit read value is returned.
> +
> + @param Index The CMOS location to read.
> +
> + @return The value read.
> +
> +**/
> +UINT8
> +EFIAPI
> +CmosRead8 (
> + IN UINTN Index
> + )
> +{
> + IoWrite8 (0x70, (UINT8) Index);
> + return IoRead8 (0x71);
> +}
> +
> +
> +/**
> + Writes 8-bits of CMOS data.
> +
> + Writes 8-bits of CMOS data to the location specified by Index
> + with the value specified by Value and returns Value.
> +
> + @param Index The CMOS location to write.
> + @param Value The value to write to CMOS.
> +
> + @return The value written to CMOS.
> +
> +**/
> +UINT8
> +EFIAPI
> +CmosWrite8 (
> + IN UINTN Index,
> + IN UINT8 Value
> + )
> +{
> + IoWrite8 (0x70, (UINT8) Index);
> + IoWrite8 (0x71, Value);
> + return Value;
> +}
> +
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/FeatureControl.c
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/FeatureControl.c
> new file mode 100644
> index 0000000000..692405e417
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/FeatureControl.c
> @@ -0,0 +1,114 @@
> +/** @file
> + Install a callback when necessary for setting the Feature Control MSR on all
> + processors.
> +
> + Copyright (C) 2016, Red Hat, Inc.
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Ppi/MpServices.h>
> +#include <Register/Intel/Msr/Core2Msr.h>
> +
> +#include "Platform.h"
> +
> +//
> +// The value to be written to the Feature Control MSR, retrieved from fw_cfg.
> +//
> +STATIC UINT64 mFeatureControlValue = 0x00000005;
> +
> +/**
> + Write the Feature Control MSR on an Application Processor or the Boot
> + Processor.
> +
> + All APs execute this function in parallel. The BSP executes the function
> + separately.
> +
> + @param[in,out] WorkSpace Pointer to the input/output argument
> workspace
> + shared by all processors.
> +**/
> +STATIC
> +VOID
> +EFIAPI
> +WriteFeatureControl (
> + IN OUT VOID *WorkSpace
> + )
> +{
> + AsmWriteMsr64 (MSR_CORE2_FEATURE_CONTROL, mFeatureControlValue);
> +}
> +
> +/**
> + Notification function called when EFI_PEI_MP_SERVICES_PPI becomes
> available.
> +
> + @param[in] PeiServices Indirect reference to the PEI Services Table.
> + @param[in] NotifyDescriptor Address of the notification descriptor data
> + structure.
> + @param[in] Ppi Address of the PPI that was installed.
> +
> + @return Status of the notification. The status code returned from this
> + function is ignored.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +OnMpServicesAvailable (
> + IN EFI_PEI_SERVICES **PeiServices,
> + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
> + IN VOID *Ppi
> + )
> +{
> + EFI_PEI_MP_SERVICES_PPI *MpServices;
> + EFI_STATUS Status;
> +
> + DEBUG ((EFI_D_VERBOSE, "%a: %a\n", gEfiCallerBaseName,
> __FUNCTION__));
> + //
> + // Write the MSR on all the APs in parallel.
> + //
> + MpServices = Ppi;
> + Status = MpServices->StartupAllAPs (
> + (CONST EFI_PEI_SERVICES **)PeiServices,
> + MpServices,
> + WriteFeatureControl, // Procedure
> + FALSE, // SingleThread
> + 0, // TimeoutInMicroSeconds: inf.
> + NULL // ProcedureArgument
> + );
> + if (EFI_ERROR (Status) && Status != EFI_NOT_STARTED) {
> + DEBUG ((EFI_D_ERROR, "%a: StartupAllAps(): %r\n", __FUNCTION__,
> Status));
> + return Status;
> + }
> +
> + //
> + // Now write the MSR on the BSP too.
> + //
> + WriteFeatureControl (NULL);
> +
> + return EFI_SUCCESS;
> +}
> +
> +//
> +// Notification object for registering the callback, for when
> +// EFI_PEI_MP_SERVICES_PPI becomes available.
> +//
> +STATIC CONST EFI_PEI_NOTIFY_DESCRIPTOR mMpServicesNotify = {
> + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | // Flags
> + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
> + &gEfiPeiMpServicesPpiGuid, // Guid
> + OnMpServicesAvailable // Notify
> +};
> +
> +VOID
> +InstallFeatureControlCallback (
> + VOID
> + )
> +{
> + EFI_STATUS Status;
> +
> + Status = PeiServicesNotifyPpi (&mMpServicesNotify);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_ERROR, "%a: failed to set up MP Services callback: %r\n",
> + __FUNCTION__, Status));
> + }
> +}
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c
> new file mode 100644
> index 0000000000..818d135c95
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c
> @@ -0,0 +1,100 @@
> +/** @file
> + Build FV related hobs for platform.
> +
> + Copyright (c) 2006 - 2013 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PiPei.h"
> +#include "Platform.h"
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PcdLib.h>
> +
> +
> +/**
> + Publish PEI & DXE (Decompressed) Memory based FVs to let PEI
> + and DXE know about them.
> +
> + @retval EFI_SUCCESS Platform PEI FVs were initialized successfully.
> +
> +**/
> +EFI_STATUS
> +PeiFvInitialization (
> + VOID
> + )
> +{
> + BOOLEAN SecureS3Needed;
> +
> + DEBUG ((EFI_D_INFO, "Platform PEI Firmware Volume Initialization\n"));
> +
> + DEBUG (
> + (EFI_D_ERROR, "Firmware Volume HOB: 0x%x 0x%x\n",
> + PcdGet32 (PcdSimicsPeiMemFvBase),
> + PcdGet32 (PcdSimicsPeiMemFvSize)
> + )
> + );
> + //
> + // Create a memory allocation HOB for the PEI FV.
> + //
> + // Allocate as ACPI NVS is S3 is supported
> + //
> + BuildMemoryAllocationHob (
> + PcdGet32 (PcdSimicsPeiMemFvBase),
> + PcdGet32 (PcdSimicsPeiMemFvSize),
> + mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
> + );
> +
> + //
> + // Let DXE know about the DXE FV
> + //
> + BuildFvHob (PcdGet32 (PcdSimicsDxeMemFvBase), PcdGet32
> (PcdSimicsDxeMemFvSize));
> +
> + SecureS3Needed = mS3Supported && FeaturePcdGet
> (PcdSmmSmramRequire);
> +
> + //
> + // Create a memory allocation HOB for the DXE FV.
> + //
> + // If "secure" S3 is needed, then SEC will decompress both PEI and DXE
> + // firmware volumes at S3 resume too, hence we need to keep away the OS
> from
> + // DXEFV as well. Otherwise we only need to keep away DXE itself from the
> + // DXEFV area.
> + //
> + BuildMemoryAllocationHob (
> + PcdGet32 (PcdSimicsDxeMemFvBase),
> + PcdGet32 (PcdSimicsDxeMemFvSize),
> + SecureS3Needed ? EfiACPIMemoryNVS : EfiBootServicesData
> + );
> +
> + //
> + // Additionally, said decompression will use temporary memory above the
> end
> + // of DXEFV, so let's keep away the OS from there too.
> + //
> + if (SecureS3Needed) {
> + UINT32 DxeMemFvEnd;
> +
> + DxeMemFvEnd = PcdGet32 (PcdSimicsDxeMemFvBase) +
> + PcdGet32 (PcdSimicsDxeMemFvSize);
> + BuildMemoryAllocationHob (
> + DxeMemFvEnd,
> + PcdGet32 (PcdSimicsDecompressionScratchEnd) - DxeMemFvEnd,
> + EfiACPIMemoryNVS
> + );
> + }
> +
> + //
> + // Let PEI know about the DXE FV so it can find the DXE Core
> + //
> + PeiServicesInstallFvInfoPpi (
> + NULL,
> + (VOID *)(UINTN) PcdGet32 (PcdSimicsDxeMemFvBase),
> + PcdGet32 (PcdSimicsDxeMemFvSize),
> + NULL,
> + NULL
> + );
> +
> + return EFI_SUCCESS;
> +}
> +
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c
> new file mode 100644
> index 0000000000..4c527baef2
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c
> @@ -0,0 +1,568 @@
> +/** @file
> + Memory Detection for Virtual Machines.
> +
> + Copyright (c) 2006 - 2016 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// The package level header files this module uses
> +//
> +#include <PiPei.h>
> +
> +//
> +// The Library classes this module consumes
> +//
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PeimEntryPoint.h>
> +#include <Library/ResourcePublicationLib.h>
> +#include <Library/MtrrLib.h>
> +#include <SimicsPlatforms.h>
> +#include <Guid/SmramMemoryReserve.h>
> +
> +#include "Platform.h"
> +#include "Cmos.h"
> +
> +UINT8 mPhysMemAddressWidth;
> +
> +STATIC UINT32 mS3AcpiReservedMemoryBase;
> +STATIC UINT32 mS3AcpiReservedMemorySize;
> +
> +STATIC UINT16 mX58TsegMbytes;
> +
> +VOID
> +X58TsegMbytesInitialization(
> + VOID
> +)
> +{
> +
> + if (mHostBridgeDevId != INTEL_ICH10_DEVICE_ID) {
> + DEBUG ((
> + DEBUG_ERROR,
> + "%a: no TSEG (SMRAM) on host bridge DID=0x%04x; "
> + "only DID=0x%04x (X58) is supported\n",
> + __FUNCTION__,
> + mHostBridgeDevId,
> + INTEL_ICH10_DEVICE_ID
> + ));
> + ASSERT (FALSE);
> + CpuDeadLoop ();
> + }
> +
> + //
> + // Check if QEMU offers an extended TSEG.
> + //
> + // This can be seen from writing MCH_EXT_TSEG_MB_QUERY to the
> MCH_EXT_TSEG_MB
> + // register, and reading back the register.
> + //
> + // On a QEMU machine type that does not offer an extended TSEG, the initial
> + // write overwrites whatever value a malicious guest OS may have placed in
> + // the (unimplemented) register, before entering S3 or rebooting.
> + // Subsequently, the read returns MCH_EXT_TSEG_MB_QUERY unchanged.
> + //
> + // On a QEMU machine type that offers an extended TSEG, the initial write
> + // triggers an update to the register. Subsequently, the value read back
> + // (which is guaranteed to differ from MCH_EXT_TSEG_MB_QUERY) tells us
> the
> + // number of megabytes.
> + //
> + mX58TsegMbytes = FixedPcdGet8(PcdX58TsegMbytes);
> + return;
> +}
> +
> +
> +UINT32
> +GetSystemMemorySizeBelow4gb (
> + VOID
> + )
> +{
> + UINT8 Cmos0x34;
> + UINT8 Cmos0x35;
> +
> + //
> + // CMOS 0x34/0x35 specifies the system memory above 16 MB.
> + // * CMOS(0x35) is the high byte
> + // * CMOS(0x34) is the low byte
> + // * The size is specified in 64kb chunks
> + // * Since this is memory above 16MB, the 16MB must be added
> + // into the calculation to get the total memory size.
> + //
> +
> + Cmos0x34 = (UINT8) CmosRead8 (0x34);
> + Cmos0x35 = (UINT8) CmosRead8 (0x35);
> +
> + return (UINT32) (((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) +
> SIZE_16MB);
> +}
> +
> +
> +STATIC
> +UINT64
> +GetSystemMemorySizeAbove4gb (
> + )
> +{
> + UINT32 Size;
> + UINTN CmosIndex;
> +
> + //
> + // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
> + // * CMOS(0x5d) is the most significant size byte
> + // * CMOS(0x5c) is the middle size byte
> + // * CMOS(0x5b) is the least significant size byte
> + // * The size is specified in 64kb chunks
> + //
> +
> + Size = 0;
> + for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) {
> + Size = (UINT32) (Size << 8) + (UINT32) CmosRead8 (CmosIndex);
> + }
> +
> + return LShiftU64 (Size, 16);
> +}
> +
> +
> +/**
> + Return the highest address that DXE could possibly use, plus one.
> +**/
> +STATIC
> +UINT64
> +GetFirstNonAddress (
> + VOID
> + )
> +{
> + UINT64 FirstNonAddress;
> + UINT64 Pci64Base, Pci64Size;
> +
> + FirstNonAddress = BASE_4GB + GetSystemMemorySizeAbove4gb ();
> +
> + //
> + // If DXE is 32-bit, then we're done; PciBusDxe will degrade 64-bit MMIO
> + // resources to 32-bit anyway. See DegradeResource() in
> + // "PciResourceSupport.c".
> + //
> +#ifdef MDE_CPU_IA32
> + if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
> + return FirstNonAddress;
> + }
> +#endif
> +
> + //
> + // Otherwise, in order to calculate the highest address plus one, we must
> + // consider the 64-bit PCI host aperture too. Fetch the default size.
> + //
> + Pci64Size = PcdGet64 (PcdPciMmio64Size);
> +
> + if (Pci64Size == 0) {
> + if (mBootMode != BOOT_ON_S3_RESUME) {
> + DEBUG ((EFI_D_INFO, "%a: disabling 64-bit PCI host aperture\n",
> + __FUNCTION__));
> + PcdSet64 (PcdPciMmio64Size, 0);
> + }
> +
> + //
> + // There's nothing more to do; the amount of memory above 4GB fully
> + // determines the highest address plus one. The memory hotplug area (see
> + // below) plays no role for the firmware in this case.
> + //
> + return FirstNonAddress;
> + }
> +
> + //
> + // SeaBIOS aligns both boundaries of the 64-bit PCI host aperture to 1GB, so
> + // that the host can map it with 1GB hugepages. Follow suit.
> + //
> + Pci64Base = ALIGN_VALUE (FirstNonAddress, (UINT64)SIZE_1GB);
> + Pci64Size = ALIGN_VALUE (Pci64Size, (UINT64)SIZE_1GB);
> +
> + //
> + // The 64-bit PCI host aperture should also be "naturally" aligned. The
> + // alignment is determined by rounding the size of the aperture down to the
> + // next smaller or equal power of two. That is, align the aperture by the
> + // largest BAR size that can fit into it.
> + //
> + Pci64Base = ALIGN_VALUE (Pci64Base, GetPowerOfTwo64 (Pci64Size));
> +
> + if (mBootMode != BOOT_ON_S3_RESUME) {
> + //
> + // The core PciHostBridgeDxe driver will automatically add this range to
> + // the GCD memory space map through our PciHostBridgeLib instance; here
> we
> + // only need to set the PCDs.
> + //
> + PcdSet64 (PcdPciMmio64Base, Pci64Base);
> + PcdSet64 (PcdPciMmio64Size, Pci64Size);
> + DEBUG ((EFI_D_INFO, "%a: Pci64Base=0x%Lx Pci64Size=0x%Lx\n",
> + __FUNCTION__, Pci64Base, Pci64Size));
> + }
> +
> + //
> + // The useful address space ends with the 64-bit PCI host aperture.
> + //
> + FirstNonAddress = Pci64Base + Pci64Size;
> + return FirstNonAddress;
> +}
> +
> +
> +/**
> + Initialize the mPhysMemAddressWidth variable, based on guest RAM size.
> +**/
> +VOID
> +AddressWidthInitialization (
> + VOID
> + )
> +{
> + UINT64 FirstNonAddress;
> +
> + //
> + // As guest-physical memory size grows, the permanent PEI RAM
> requirements
> + // are dominated by the identity-mapping page tables built by the DXE IPL.
> + // The DXL IPL keys off of the physical address bits advertized in the CPU
> + // HOB. To conserve memory, we calculate the minimum address width here.
> + //
> + FirstNonAddress = GetFirstNonAddress ();
> + mPhysMemAddressWidth = (UINT8)HighBitSet64 (FirstNonAddress);
> +
> + //
> + // If FirstNonAddress is not an integral power of two, then we need an
> + // additional bit.
> + //
> + if ((FirstNonAddress & (FirstNonAddress - 1)) != 0) {
> + ++mPhysMemAddressWidth;
> + }
> +
> + //
> + // The minimum address width is 36 (covers up to and excluding 64 GB, which
> + // is the maximum for Ia32 + PAE). The theoretical architecture maximum for
> + // X64 long mode is 52 bits, but the DXE IPL clamps that down to 48 bits. We
> + // can simply assert that here, since 48 bits are good enough for 256 TB.
> + //
> + if (mPhysMemAddressWidth <= 36) {
> + mPhysMemAddressWidth = 36;
> + }
> + ASSERT (mPhysMemAddressWidth <= 48);
> +}
> +
> +
> +/**
> + Calculate the cap for the permanent PEI memory.
> +**/
> +STATIC
> +UINT32
> +GetPeiMemoryCap (
> + VOID
> + )
> +{
> + BOOLEAN Page1GSupport;
> + UINT32 RegEax;
> + UINT32 RegEdx;
> + UINT32 Pml4Entries;
> + UINT32 PdpEntries;
> + UINTN TotalPages;
> +
> + //
> + // If DXE is 32-bit, then just return the traditional 64 MB cap.
> + //
> +#ifdef MDE_CPU_IA32
> + if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
> + return SIZE_64MB;
> + }
> +#endif
> +
> + //
> + // Dependent on physical address width, PEI memory allocations can be
> + // dominated by the page tables built for 64-bit DXE. So we key the cap off
> + // of those. The code below is based on CreateIdentityMappingPageTables() in
> + // "MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c".
> + //
> + Page1GSupport = FALSE;
> + if (PcdGetBool (PcdUse1GPageTable)) {
> + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
> + if (RegEax >= 0x80000001) {
> + AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
> + if ((RegEdx & BIT26) != 0) {
> + Page1GSupport = TRUE;
> + }
> + }
> + }
> +
> + if (mPhysMemAddressWidth <= 39) {
> + Pml4Entries = 1;
> + PdpEntries = 1 << (mPhysMemAddressWidth - 30);
> + ASSERT (PdpEntries <= 0x200);
> + } else {
> + Pml4Entries = 1 << (mPhysMemAddressWidth - 39);
> + ASSERT (Pml4Entries <= 0x200);
> + PdpEntries = 512;
> + }
> +
> + TotalPages = Page1GSupport ? Pml4Entries + 1 :
> + (PdpEntries + 1) * Pml4Entries + 1;
> + ASSERT (TotalPages <= 0x40201);
> +
> + //
> + // Add 64 MB for miscellaneous allocations. Note that for
> + // mPhysMemAddressWidth values close to 36, the cap will actually be
> + // dominated by this increment.
> + //
> + return (UINT32)(EFI_PAGES_TO_SIZE (TotalPages) + SIZE_64MB);
> +}
> +
> +
> +/**
> + Publish PEI core memory
> +
> + @return EFI_SUCCESS The PEIM initialized successfully.
> +
> +**/
> +EFI_STATUS
> +PublishPeiMemory (
> + VOID
> + )
> +{
> + EFI_STATUS Status;
> + EFI_PHYSICAL_ADDRESS MemoryBase;
> + UINT64 MemorySize;
> + UINT32 LowerMemorySize;
> + UINT32 PeiMemoryCap;
> +
> + LowerMemorySize = GetSystemMemorySizeBelow4gb ();
> + if (FeaturePcdGet (PcdSmmSmramRequire)) {
> + //
> + // TSEG is chipped from the end of low RAM
> + //
> + LowerMemorySize -= mX58TsegMbytes * SIZE_1MB;
> + }
> +
> + //
> + // If S3 is supported, then the S3 permanent PEI memory is placed next,
> + // downwards. Its size is primarily dictated by CpuMpPei. The formula below
> + // is an approximation.
> + //
> + if (mS3Supported) {
> + mS3AcpiReservedMemorySize = SIZE_512KB +
> + mMaxCpuCount *
> + PcdGet32 (PcdCpuApStackSize);
> + mS3AcpiReservedMemoryBase = LowerMemorySize -
> mS3AcpiReservedMemorySize;
> + LowerMemorySize = mS3AcpiReservedMemoryBase;
> + }
> +
> + if (mBootMode == BOOT_ON_S3_RESUME) {
> + MemoryBase = mS3AcpiReservedMemoryBase;
> + MemorySize = mS3AcpiReservedMemorySize;
> + } else {
> + PeiMemoryCap = GetPeiMemoryCap ();
> + DEBUG ((EFI_D_INFO, "%a: mPhysMemAddressWidth=%d
> PeiMemoryCap=%u KB\n",
> + __FUNCTION__, mPhysMemAddressWidth, PeiMemoryCap >> 10));
> +
> + //
> + // Determine the range of memory to use during PEI
> + //
> + // Technically we could lay the permanent PEI RAM over SEC's temporary
> + // decompression and scratch buffer even if "secure S3" is needed, since
> + // their lifetimes don't overlap. However, PeiFvInitialization() will cover
> + // RAM up to PcdOvmfDecompressionScratchEnd with an
> EfiACPIMemoryNVS memory
> + // allocation HOB, and other allocations served from the permanent PEI RAM
> + // shouldn't overlap with that HOB.
> + //
> + MemoryBase = mS3Supported && FeaturePcdGet (PcdSmmSmramRequire)
> ?
> + PcdGet32 (PcdSimicsDecompressionScratchEnd) :
> + PcdGet32 (PcdSimicsDxeMemFvBase) + PcdGet32
> (PcdSimicsDxeMemFvSize);
> + MemorySize = LowerMemorySize - MemoryBase;
> + }
> + DEBUG((EFI_D_INFO, "MemoryBase=0x%lx MemorySize=0x%lx\n",
> MemoryBase, MemorySize));
> + //
> + // Publish this memory to the PEI Core
> + //
> + Status = PublishSystemMemory(MemoryBase, MemorySize);
> + ASSERT_EFI_ERROR (Status);
> +
> + return Status;
> +}
> +
> +
> +/**
> + Peform Memory Detection for QEMU / KVM
> +
> +**/
> +STATIC
> +VOID
> +QemuInitializeRam (
> + VOID
> + )
> +{
> + UINT64 LowerMemorySize;
> + UINT64 UpperMemorySize;
> + UINTN BufferSize;
> + UINT8 SmramIndex;
> + UINT8 SmramRanges;
> + EFI_PEI_HOB_POINTERS Hob;
> + EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *SmramHobDescriptorBlock;
> + UINT8 Index;
> +
> + DEBUG ((EFI_D_INFO, "%a called\n", __FUNCTION__));
> +
> + //
> + // Determine total memory size available
> + //
> + LowerMemorySize = GetSystemMemorySizeBelow4gb ();
> + UpperMemorySize = GetSystemMemorySizeAbove4gb ();
> +
> + if (mBootMode == BOOT_ON_S3_RESUME) {
> + //
> + // Create the following memory HOB as an exception on the S3 boot path.
> + //
> + // Normally we'd create memory HOBs only on the normal boot path.
> However,
> + // CpuMpPei specifically needs such a low-memory HOB on the S3 path as
> + // well, for "borrowing" a subset of it temporarily, for the AP startup
> + // vector.
> + //
> + // CpuMpPei saves the original contents of the borrowed area in permanent
> + // PEI RAM, in a backup buffer allocated with the normal PEI services.
> + // CpuMpPei restores the original contents ("returns" the borrowed area) at
> + // End-of-PEI. End-of-PEI in turn is emitted by S3Resume2Pei before
> + // transferring control to the OS's wakeup vector in the FACS.
> + //
> + // We expect any other PEIMs that "borrow" memory similarly to CpuMpPei
> to
> + // restore the original contents. Furthermore, we expect all such PEIMs
> + // (CpuMpPei included) to claim the borrowed areas by producing memory
> + // allocation HOBs, and to honor preexistent memory allocation HOBs when
> + // looking for an area to borrow.
> + //
> + AddMemoryRangeHob (0, BASE_512KB + BASE_128KB);
> + } else {
> + //
> + // Create memory HOBs
> + //
> + AddMemoryRangeHob (0, BASE_512KB + BASE_128KB);
> +
> + if (FeaturePcdGet (PcdSmmSmramRequire)) {
> + UINT32 TsegSize;
> +
> + TsegSize = mX58TsegMbytes * SIZE_1MB;
> + AddMemoryRangeHob (BASE_1MB, LowerMemorySize - TsegSize);
> + AddReservedMemoryBaseSizeHob (LowerMemorySize - TsegSize, TsegSize,
> + TRUE);
> +
> + BufferSize = sizeof(EFI_SMRAM_HOB_DESCRIPTOR_BLOCK);
> + SmramRanges = 1;
> +
> + Hob.Raw = BuildGuidHob(
> + &gEfiSmmPeiSmramMemoryReserveGuid,
> + BufferSize
> + );
> + ASSERT(Hob.Raw);
> +
> + SmramHobDescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK
> *)(Hob.Raw);
> + SmramHobDescriptorBlock->NumberOfSmmReservedRegions =
> SmramRanges;
> +
> + SmramIndex = 0;
> + for (Index = 0; Index < SmramRanges; Index++) {
> + //
> + // This is an SMRAM range, create an SMRAM descriptor
> + //
> + SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalStart =
> LowerMemorySize - TsegSize;
> + SmramHobDescriptorBlock->Descriptor[SmramIndex].CpuStart =
> LowerMemorySize - TsegSize;
> + SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalSize =
> TsegSize;
> + SmramHobDescriptorBlock->Descriptor[SmramIndex].RegionState =
> EFI_SMRAM_CLOSED | EFI_CACHEABLE;
> + SmramIndex++;
> + }
> +
> + } else {
> + AddMemoryRangeHob (BASE_1MB, LowerMemorySize);
> + }
> +
> + //
> + // If QEMU presents an E820 map, then create memory HOBs for the >=4GB
> RAM
> + // entries. Otherwise, create a single memory HOB with the flat >=4GB
> + // memory size read from the CMOS.
> + //
> + if (UpperMemorySize != 0) {
> + AddMemoryBaseSizeHob (BASE_4GB, UpperMemorySize);
> + }
> + }
> +}
> +
> +/**
> + Publish system RAM and reserve memory regions
> +
> +**/
> +VOID
> +InitializeRamRegions (
> + VOID
> + )
> +{
> + QemuInitializeRam ();
> +
> + if (mS3Supported && mBootMode != BOOT_ON_S3_RESUME) {
> + //
> + // This is the memory range that will be used for PEI on S3 resume
> + //
> + BuildMemoryAllocationHob (
> + mS3AcpiReservedMemoryBase,
> + mS3AcpiReservedMemorySize,
> + EfiACPIMemoryNVS
> + );
> +
> + //
> + // Cover the initial RAM area used as stack and temporary PEI heap.
> + //
> + // This is reserved as ACPI NVS so it can be used on S3 resume.
> + //
> + BuildMemoryAllocationHob (
> + PcdGet32 (PcdSimicsSecPeiTempRamBase),
> + PcdGet32 (PcdSimicsSecPeiTempRamSize),
> + EfiACPIMemoryNVS
> + );
> +
> + //
> + // SEC stores its table of GUIDed section handlers here.
> + //
> + BuildMemoryAllocationHob (
> + PcdGet64 (PcdGuidedExtractHandlerTableAddress),
> + PcdGet32 (PcdGuidedExtractHandlerTableSize),
> + EfiACPIMemoryNVS
> + );
> +
> + }
> +
> + if (mBootMode != BOOT_ON_S3_RESUME) {
> + if (!FeaturePcdGet (PcdSmmSmramRequire)) {
> + //
> + // Reserve the lock box storage area
> + //
> + // Since this memory range will be used on S3 resume, it must be
> + // reserved as ACPI NVS.
> + //
> + // If S3 is unsupported, then various drivers might still write to the
> + // LockBox area. We ought to prevent DXE from serving allocation requests
> + // such that they would overlap the LockBox storage.
> + //
> + ZeroMem (
> + (VOID*)(UINTN) PcdGet32 (PcdSimicsLockBoxStorageBase),
> + (UINTN) PcdGet32 (PcdSimicsLockBoxStorageSize)
> + );
> + BuildMemoryAllocationHob (
> + (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32
> (PcdSimicsLockBoxStorageBase),
> + (UINT64)(UINTN) PcdGet32 (PcdSimicsLockBoxStorageSize),
> + mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
> + );
> + }
> +
> + if (FeaturePcdGet (PcdSmmSmramRequire)) {
> + UINT32 TsegSize;
> +
> + //
> + // Make sure the TSEG area that we reported as a reserved memory
> resource
> + // cannot be used for reserved memory allocations.
> + //
> + TsegSize = mX58TsegMbytes * SIZE_1MB;
> + BuildMemoryAllocationHob (
> + GetSystemMemorySizeBelow4gb() - TsegSize,
> + TsegSize,
> + EfiReservedMemoryType
> + );
> + }
> + }
> +}
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.c
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.c
> new file mode 100644
> index 0000000000..e64bdc7c56
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.c
> @@ -0,0 +1,631 @@
> +/** @file
> + Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
> + Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// The package level header files this module uses
> +//
> +#include <PiPei.h>
> +
> +//
> +// The Library classes this module consumes
> +//
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/PeimEntryPoint.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/ResourcePublicationLib.h>
> +#include <Guid/MemoryTypeInformation.h>
> +#include <Ppi/MasterBootMode.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <SimicsPlatforms.h>
> +
> +#include "Platform.h"
> +#include "Cmos.h"
> +
> +EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
> + { EfiACPIMemoryNVS, 0x004 },
> + { EfiACPIReclaimMemory, 0x008 },
> + { EfiReservedMemoryType, 0x004 },
> + { EfiRuntimeServicesData, 0x024 },
> + { EfiRuntimeServicesCode, 0x030 },
> + { EfiBootServicesCode, 0x180 },
> + { EfiBootServicesData, 0xF00 },
> + { EfiMaxMemoryType, 0x000 }
> +};
> +
> +
> +EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[] = {
> + {
> + EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
> + &gEfiPeiMasterBootModePpiGuid,
> + NULL
> + }
> +};
> +
> +
> +UINT16 mHostBridgeDevId;
> +
> +EFI_BOOT_MODE mBootMode = BOOT_WITH_FULL_CONFIGURATION;
> +
> +BOOLEAN mS3Supported = FALSE;
> +
> +UINT32 mMaxCpuCount;
> +
> +VOID
> +AddIoMemoryBaseSizeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + UINT64 MemorySize
> + )
> +{
> + BuildResourceDescriptorHob (
> + EFI_RESOURCE_MEMORY_MAPPED_IO,
> + EFI_RESOURCE_ATTRIBUTE_PRESENT |
> + EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> + EFI_RESOURCE_ATTRIBUTE_TESTED,
> + MemoryBase,
> + MemorySize
> + );
> +}
> +
> +VOID
> +AddReservedMemoryBaseSizeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + UINT64 MemorySize,
> + BOOLEAN Cacheable
> + )
> +{
> + BuildResourceDescriptorHob (
> + EFI_RESOURCE_MEMORY_RESERVED,
> + EFI_RESOURCE_ATTRIBUTE_PRESENT |
> + EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> + (Cacheable ?
> + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
> + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
> + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE :
> + 0
> + ) |
> + EFI_RESOURCE_ATTRIBUTE_TESTED,
> + MemoryBase,
> + MemorySize
> + );
> +}
> +
> +VOID
> +AddIoMemoryRangeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + EFI_PHYSICAL_ADDRESS MemoryLimit
> + )
> +{
> + AddIoMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit -
> MemoryBase));
> +}
> +
> +
> +VOID
> +AddMemoryBaseSizeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + UINT64 MemorySize
> + )
> +{
> + BuildResourceDescriptorHob (
> + EFI_RESOURCE_SYSTEM_MEMORY,
> + EFI_RESOURCE_ATTRIBUTE_PRESENT |
> + EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
> + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
> + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
> + EFI_RESOURCE_ATTRIBUTE_TESTED,
> + MemoryBase,
> + MemorySize
> + );
> +}
> +
> +
> +VOID
> +AddMemoryRangeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + EFI_PHYSICAL_ADDRESS MemoryLimit
> + )
> +{
> + AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit -
> MemoryBase));
> +}
> +
> +
> +VOID
> +AddUntestedMemoryBaseSizeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + UINT64 MemorySize
> + )
> +{
> + BuildResourceDescriptorHob (
> + EFI_RESOURCE_SYSTEM_MEMORY,
> + EFI_RESOURCE_ATTRIBUTE_PRESENT |
> + EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
> + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
> + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE,
> + MemoryBase,
> + MemorySize
> + );
> +}
> +
> +
> +VOID
> +AddUntestedMemoryRangeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + EFI_PHYSICAL_ADDRESS MemoryLimit
> + )
> +{
> + AddUntestedMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit -
> MemoryBase));
> +}
> +
> +VOID
> +AddFlashDeviceRange (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + UINT64 MemorySize
> + )
> +{
> + BuildResourceDescriptorHob (
> + EFI_RESOURCE_FIRMWARE_DEVICE,
> + (EFI_RESOURCE_ATTRIBUTE_PRESENT |
> + EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
> + MemoryBase,
> + MemorySize
> + );
> +
> + BuildMemoryAllocationHob (
> + MemoryBase,
> + MemorySize,
> + EfiMemoryMappedIO
> + );
> +}
> +
> +VOID
> +MemMapInitialization (
> + VOID
> + )
> +{
> + UINT64 PciIoBase;
> + UINT64 PciIoSize;
> +
> + UINT32 TopOfLowRam;
> + UINT64 PciExBarBase;
> + UINT32 PciBase;
> + UINT32 PciSize;
> +
> + PciIoBase = 0xC000;
> + PciIoSize = 0x4000;
> +
> + //
> + // Create Memory Type Information HOB
> + //
> + BuildGuidDataHob (
> + &gEfiMemoryTypeInformationGuid,
> + mDefaultMemoryTypeInformation,
> + sizeof(mDefaultMemoryTypeInformation)
> + );
> +
> + //
> + // Video memory + Legacy BIOS region
> + //
> + AddIoMemoryRangeHob (0x0A0000, BASE_1MB);
> +
> + TopOfLowRam = GetSystemMemorySizeBelow4gb ();
> + PciExBarBase = 0;
> + if (mHostBridgeDevId == INTEL_ICH10_DEVICE_ID) {
> + //
> + // The MMCONFIG area is expected to fall between the top of low RAM and
> + // the base of the 32-bit PCI host aperture.
> + //
> + PciExBarBase = FixedPcdGet64 (PcdPciExpressBaseAddress);
> + ASSERT (TopOfLowRam <= PciExBarBase);
> + ASSERT (PciExBarBase <= MAX_UINT32 - SIZE_256MB);
> + PciBase = (UINT32)(PciExBarBase + SIZE_256MB);
> + } else {
> + PciBase = (TopOfLowRam < BASE_2GB) ? BASE_2GB : TopOfLowRam;
> + }
> +
> + //
> + // address purpose size
> + // ------------ -------- -------------------------
> + // 0x00000000 TopOfLowRam 0xDF000000
> + // 0xDF000000 Tseg+UMA 0x01000000
> + // 0xE0000000 PciExBarBase 0x10000000
> + // 0xF0000000 PciBase 0x0C000000
> + // -------------------------------------------------
> + // max(top, 2g) PCI MMIO 0xFC000000 - max(top, 2g)
> + // 0xFC000000 gap 44 MB
> + // 0xFEC00000 IO-APIC 4 KB
> + // 0xFEC01000 gap 1020 KB
> + // 0xFED00000 HPET 1 KB
> + // 0xFED00400 gap 111 KB
> + // 0xFED1C000 gap (PIIX4) / RCRB (ICH9) 16 KB
> + // 0xFED20000 gap 896 KB
> + // 0xFEE00000 LAPIC 1 MB
> + //
> + PciSize = 0xFC000000 - PciBase;
> + AddIoMemoryBaseSizeHob (PciBase, PciSize);
> + PcdSet64 (PcdPciMmio32Base, PciBase);
> + PcdSet64 (PcdPciMmio32Size, PciSize);
> + AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB);
> + AddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB);
> + if (mHostBridgeDevId == INTEL_ICH10_DEVICE_ID) {
> + AddIoMemoryBaseSizeHob (ICH10_ROOT_COMPLEX_BASE, SIZE_16KB);
> + //
> + // Note: there should be an
> + //
> + // AddIoMemoryBaseSizeHob (PciExBarBase, SIZE_256MB);
> + // BuildMemoryAllocationHob (PciExBarBase, SIZE_256MB,
> EfiMemoryMappedIO);
> + //
> + // call below, just like the one above for RCBA. However, Linux insists
> + // that the MMCONFIG area be marked in the E820 or UEFI memory map as
> + // "reserved memory" -- Linux does not content itself with a simple gap
> + // in the memory map wherever the MCFG ACPI table points to.
> + //
> + // This appears to be a safety measure. The PCI Firmware Specification
> + // (rev 3.1) says in 4.1.2. "MCFG Table Description": "The resources can
> + // *optionally* be returned in [...] EFIGetMemoryMap as reserved memory
> + // [...]". (Emphasis added here.)
> + //
> + // Normally we add memory resource descriptor HOBs in
> + // QemuInitializeRam(), and pre-allocate from those with memory
> + // allocation HOBs in InitializeRamRegions(). However, the MMCONFIG area
> + // is most definitely not RAM; so, as an exception, cover it with
> + // uncacheable reserved memory right here.
> + //
> + AddReservedMemoryBaseSizeHob (PciExBarBase, SIZE_256MB, FALSE);
> + BuildMemoryAllocationHob (PciExBarBase, SIZE_256MB,
> + EfiReservedMemoryType);
> + }
> + AddIoMemoryBaseSizeHob (PcdGet32(PcdCpuLocalApicBaseAddress),
> SIZE_1MB);
> +
> + // Add PCI IO Port space available for PCI resource allocations.
> + //
> + BuildResourceDescriptorHob (
> + EFI_RESOURCE_IO,
> + EFI_RESOURCE_ATTRIBUTE_PRESENT |
> + EFI_RESOURCE_ATTRIBUTE_INITIALIZED,
> + PciIoBase,
> + PciIoSize
> + );
> + PcdSet64 (PcdPciIoBase, PciIoBase);
> + PcdSet64 (PcdPciIoSize, PciIoSize);
> +
> + //
> + // Add flash range.
> + //
> + AddFlashDeviceRange (PcdGet32(PcdFlashAreaBaseAddress),
> PcdGet32(PcdFlashAreaSize));
> + //
> + // Video memory / ABSEG
> + //
> + AddIoMemoryBaseSizeHob (0x0A0000, 0x20000);
> + //
> + // Legacy BIOS region.
> + //
> + AddReservedMemoryBaseSizeHob (0xC0000, 0x40000, TRUE);
> +}
> +
> +VOID
> +MiscInitialization (
> + VOID
> + )
> +{
> + UINTN PmCmd;
> + UINTN Pmba;
> + UINT32 PmbaAndVal;
> + UINT32 PmbaOrVal;
> + UINTN AcpiCtlReg;
> + UINT8 AcpiEnBit;
> +
> + //
> + // Disable A20 Mask
> + //
> + IoOr8 (0x92, BIT1);
> +
> + //
> + // Build the CPU HOB with guest RAM size dependent address width and 16-
> bits
> + // of IO space. (Side note: unlike other HOBs, the CPU HOB is needed during
> + // S3 resume as well, so we build it unconditionally.)
> + //
> + BuildCpuHob (mPhysMemAddressWidth, 16);
> +
> + //
> + // Determine platform type and save Host Bridge DID to PCD
> + //
> + switch (mHostBridgeDevId) {
> + case INTEL_82441_DEVICE_ID:
> + PmCmd = POWER_MGMT_REGISTER_PIIX4 (PCI_COMMAND_OFFSET);
> + Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);
> + PmbaAndVal = ~(UINT32)PIIX4_PMBA_MASK;
> + PmbaOrVal = PIIX4_PMBA_VALUE;
> + AcpiCtlReg = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMREGMISC);
> + AcpiEnBit = PIIX4_PMREGMISC_PMIOSE;
> + break;
> + case INTEL_ICH10_DEVICE_ID:
> + PmCmd = POWER_MGMT_REGISTER_ICH10 (PCI_COMMAND_OFFSET);
> + Pmba = POWER_MGMT_REGISTER_ICH10 (ICH10_PMBASE);
> + PmbaAndVal = ~(UINT32)ICH10_PMBASE_MASK;
> + PmbaOrVal = ICH10_PMBASE_VALUE;
> + AcpiCtlReg = POWER_MGMT_REGISTER_ICH10 (ICH10_ACPI_CNTL);
> + AcpiEnBit = ICH10_ACPI_CNTL_ACPI_EN;
> + break;
> + default:
> + DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
> + __FUNCTION__, mHostBridgeDevId));
> + ASSERT (FALSE);
> + return;
> + }
> + PcdSet16 (PcdSimicsX58HostBridgePciDevId, mHostBridgeDevId);
> +
> + //
> + // If the appropriate IOspace enable bit is set, assume the ACPI PMBA
> + // has been configured and skip the setup here.
> + // This matches the logic in AcpiTimerLibConstructor ().
> + //
> + if ((PciRead8 (AcpiCtlReg) & AcpiEnBit) == 0) {
> + //
> + // The PEI phase should be exited with fully accessibe ACPI PM IO space:
> + // 1. set PMBA
> + //
> + PciAndThenOr32 (Pmba, PmbaAndVal, PmbaOrVal);
> +
> + //
> + // 2. set PCICMD/IOSE
> + //
> + PciOr8 (PmCmd, EFI_PCI_COMMAND_IO_SPACE);
> +
> + //
> + // 3. set ACPI PM IO enable bit (PMREGMISC:PMIOSE or
> ACPI_CNTL:ACPI_EN)
> + //
> + PciOr8 (AcpiCtlReg, AcpiEnBit);
> + }
> +
> + if (mHostBridgeDevId == INTEL_ICH10_DEVICE_ID) {
> + //
> + // Set Root Complex Register Block BAR
> + //
> + PciWrite32 (
> + POWER_MGMT_REGISTER_ICH10 (ICH10_RCBA),
> + ICH10_ROOT_COMPLEX_BASE | ICH10_RCBA_EN
> + );
> +
> + }
> + //
> + // Set the PM I/O base address to 0x400
> + //
> + PciAndThenOr32 (
> + PCI_LIB_ADDRESS (
> + 0,
> + 31,
> + 0,
> + 0x40
> + ),
> + (UINT32) ~0xfc0, ICH10_PMBASE_VALUE
> + );
> + //
> + // Enable AHCI and all ports on the SATA controller.
> + //
> + // Address MAP Reg, setting AHCI mode
> + //
> + PciOr16 (PCI_LIB_ADDRESS (0, 31, 2, 0x90), 0x0060);
> + //
> + //Enabling Ports 0-5
> + //
> + PciOr16 (PCI_LIB_ADDRESS (0, 31, 2, 0x92), 0x003F);
> + //
> + //Disabling Sata Controller 2, bit 25 = 1, bit 0 = 1
> + //
> + MmioWrite32(0xFED1F418, 0x02000001);
> + //
> + //Enable HPET at FED0_0000h – FED0_03FFh
> + //
> + MmioWrite8(ICH10_ROOT_COMPLEX_BASE + 0x3404, 0x80);
> + //
> + //Config and enable APIC
> + //
> + MmioWrite32(0xFEC00000 + 0X0, 0);
> + MmioWrite32(0xFEC00000 + 0X10, PcdGet8(PcdIoApicId)<<24);
> + MmioWrite8(ICH10_ROOT_COMPLEX_BASE + 0x31FF, 0x01);
> +}
> +
> +
> +VOID
> +BootModeInitialization (
> + VOID
> + )
> +{
> + EFI_STATUS Status;
> +
> + DEBUG((EFI_D_INFO, "modeValue = %x\n",
> IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12)));
> + if (IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12) == 0x5) {
> + mBootMode = BOOT_ON_S3_RESUME;
> + }
> +
> + Status = PeiServicesSetBootMode (mBootMode);
> + ASSERT_EFI_ERROR (Status);
> +
> + Status = PeiServicesInstallPpi (mPpiBootMode);
> + ASSERT_EFI_ERROR (Status);
> +}
> +
> +
> +VOID
> +ReserveEmuVariableNvStore (
> + )
> +{
> + EFI_PHYSICAL_ADDRESS VariableStore;
> +
> + //
> + // Allocate storage for NV variables early on so it will be
> + // at a consistent address. Since VM memory is preserved
> + // across reboots, this allows the NV variable storage to survive
> + // a VM reboot.
> + //
> + VariableStore =
> + (EFI_PHYSICAL_ADDRESS)(UINTN)
> + AllocateRuntimePages (
> + EFI_SIZE_TO_PAGES (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize))
> + );
> + DEBUG ((EFI_D_INFO,
> + "Reserved variable store memory: 0x%lX; size: %dkb\n",
> + VariableStore,
> + (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / 1024
> + ));
> + PcdSet64 (PcdEmuVariableNvStoreReserved, VariableStore);
> +}
> +
> +
> +VOID
> +SimicsVersionCheck(
> + VOID
> + )
> +{
> +
> + UINTN PciAddrPtr;
> + UINT8 CapOffset;
> + STATIC CHAR8 SimicsStr[0x100];
> + UINTN i;
> + UINT32 MajorVersion;
> + UINT32 MinorVersion;
> + UINT32 ModelNumber;
> +
> + PciAddrPtr = PCI_LIB_ADDRESS(0, SIMICS_SIDEBANDPCI_DEV,
> SIMICS_SIDEBANDPCI_FUNC, 0);
> + CapOffset = PciRead8(PciAddrPtr + PCI_CAPBILITY_POINTER_OFFSET);
> + if (CapOffset != 0xFF) {
> + ModelNumber = PciRead32(PciAddrPtr + CapOffset + 4);
> + MajorVersion = PciRead32(PciAddrPtr + CapOffset + 8);
> + MinorVersion = PciRead32(PciAddrPtr + CapOffset + 0xc);
> + for (i = 0; i < 0x80; i++) {
> + SimicsStr[i] = PciRead8(PciAddrPtr + CapOffset + 0x10 + i);
> + }
> + DEBUG((EFI_D_INFO, "=============SIMICS Version
> info=============\n"));
> + DEBUG((EFI_D_INFO, "Model number = %d\n", ModelNumber));
> + DEBUG((EFI_D_INFO, "Major version = %d\n", MajorVersion));
> + DEBUG((EFI_D_INFO, "Minor version = %d\n", MinorVersion));
> + DEBUG((EFI_D_INFO, "%a\n", SimicsStr));
> + DEBUG((EFI_D_INFO,
> "=============================================\n"));
> + }
> +}
> +
> +VOID
> +DebugDumpCmos (
> + VOID
> + )
> +{
> + UINT32 Loop;
> +
> + DEBUG ((EFI_D_INFO, "CMOS:\n"));
> +
> + for (Loop = 0; Loop < 0x80; Loop++) {
> + if ((Loop % 0x10) == 0) {
> + DEBUG ((EFI_D_INFO, "%02x:", Loop));
> + }
> + DEBUG ((EFI_D_INFO, " %02x", CmosRead8 (Loop)));
> + if ((Loop % 0x10) == 0xf) {
> + DEBUG ((EFI_D_INFO, "\n"));
> + }
> + }
> +}
> +
> +
> +/**
> + Fetch the number of boot CPUs from QEMU and expose it to UefiCpuPkg
> modules.
> + Set the mMaxCpuCount variable.
> +**/
> +VOID
> +MaxCpuCountInitialization (
> + VOID
> + )
> +{
> + mMaxCpuCount = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
> + return;
> +}
> +
> +/**
> + Determine if S3 support is explicitly enabled.
> +
> + @retval TRUE If S3 support is explicitly enabled. Other functions in this
> + library may be called (subject to their individual
> + restrictions).
> +
> + FALSE Otherwise. This includes unavailability of the firmware
> + configuration interface. No other function in this library
> + must be called.
> +**/
> +BOOLEAN
> +EFIAPI
> +QemuFwCfgS3Enabled(
> + VOID
> +)
> +{
> + //TO DO IF NEEDED
> + return TRUE;
> +}
> +
> +/**
> + Perform Platform PEI initialization.
> +
> + @param FileHandle Handle of the file being invoked.
> + @param PeiServices Describes the list of possible PEI Services.
> +
> + @return EFI_SUCCESS The PEIM initialized successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitializePlatform (
> + IN EFI_PEI_FILE_HANDLE FileHandle,
> + IN CONST EFI_PEI_SERVICES **PeiServices
> + )
> +{
> + EFI_STATUS Status;
> +
> + DEBUG ((EFI_D_ERROR, "Platform PEIM Loaded\n"));
> +
> + SimicsVersionCheck ();
> + DebugDumpCmos ();
> +
> + if (QemuFwCfgS3Enabled ()) {
> + DEBUG ((EFI_D_INFO, "S3 support was detected on SIMICS\n"));
> + mS3Supported = TRUE;
> + Status = PcdSetBoolS (PcdAcpiS3Enable, TRUE);
> + ASSERT_EFI_ERROR (Status);
> + }
> + AddressWidthInitialization ();
> + MaxCpuCountInitialization ();
> +
> + mHostBridgeDevId = PciRead16(SIMICS_HOSTBRIDGE_DID);
> +
> + if (FeaturePcdGet (PcdSmmSmramRequire)) {
> + X58TsegMbytesInitialization ();
> + }
> +
> + PublishPeiMemory ();
> +
> + InitializeRamRegions ();
> +
> + if (mBootMode != BOOT_ON_S3_RESUME) {
> + if (!FeaturePcdGet (PcdSmmSmramRequire)) {
> + ReserveEmuVariableNvStore ();
> + }
> + PeiFvInitialization ();
> + MemMapInitialization ();
> + }
> +
> + MiscInitialization ();
> + InstallFeatureControlCallback ();
> +
> + return EFI_SUCCESS;
> +}
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.c
> new file mode 100644
> index 0000000000..01a9ed40d5
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.c
> @@ -0,0 +1,108 @@
> +/** @file
> + Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +
> +/**
> + Performs silicon pre-mem policy initialization.
> +
> + The meaning of Policy is defined by silicon code.
> + It could be the raw data, a handle, a PPI, etc.
> +
> + The returned data must be used as input data for SiliconPolicyDonePreMem(),
> + and SiliconPolicyUpdateLib.SiliconPolicyUpdatePreMem().
> +
> + 1) In FSP path, the input Policy should be FspmUpd.
> + Value of FspmUpd has been initialized by FSP binary default value.
> + Only a subset of FspmUpd needs to be updated for different silicon sku.
> + The return data is same FspmUpd.
> +
> + 2) In non-FSP path, the input policy could be NULL.
> + The return data is the initialized policy.
> +
> + @param[in, out] Policy Pointer to policy.
> +
> + @return the initialized policy.
> +**/
> +VOID *
> +EFIAPI
> +SiliconPolicyInitPreMem (
> + IN OUT VOID *Policy OPTIONAL
> + )
> +{
> + return Policy;
> +}
> +
> +/*
> + The silicon pre-mem policy is finalized.
> + Silicon code can do initialization based upon the policy data.
> +
> + The input Policy must be returned by SiliconPolicyInitPreMem().
> +
> + @param[in] Policy Pointer to policy.
> +
> + @retval RETURN_SUCCESS The policy is handled consumed by silicon code.
> +*/
> +RETURN_STATUS
> +EFIAPI
> +SiliconPolicyDonePreMem (
> + IN VOID *Policy
> + )
> +{
> + return RETURN_SUCCESS;
> +}
> +
> +/**
> + Performs silicon post-mem policy initialization.
> +
> + The meaning of Policy is defined by silicon code.
> + It could be the raw data, a handle, a PPI, etc.
> +
> + The returned data must be used as input data for
> SiliconPolicyDonePostMem(),
> + and SiliconPolicyUpdateLib.SiliconPolicyUpdatePostMem().
> +
> + 1) In FSP path, the input Policy should be FspsUpd.
> + Value of FspsUpd has been initialized by FSP binary default value.
> + Only a subset of FspsUpd needs to be updated for different silicon sku.
> + The return data is same FspsUpd.
> +
> + 2) In non-FSP path, the input policy could be NULL.
> + The return data is the initialized policy.
> +
> + @param[in, out] Policy Pointer to policy.
> +
> + @return the initialized policy.
> +**/
> +VOID *
> +EFIAPI
> +SiliconPolicyInitPostMem (
> + IN OUT VOID *Policy OPTIONAL
> + )
> +{
> + return Policy;
> +}
> +
> +/*
> + The silicon post-mem policy is finalized.
> + Silicon code can do initialization based upon the policy data.
> +
> + The input Policy must be returned by SiliconPolicyInitPostMem().
> +
> + @param[in] Policy Pointer to policy.
> +
> + @retval RETURN_SUCCESS The policy is handled consumed by silicon code.
> +*/
> +RETURN_STATUS
> +EFIAPI
> +SiliconPolicyDonePostMem (
> + IN VOID *Policy
> + )
> +{
> + return RETURN_SUCCESS;
> +}
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sil
> iconPolicyUpdateLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sil
> iconPolicyUpdateLib.c
> new file mode 100644
> index 0000000000..6d9da67975
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sil
> iconPolicyUpdateLib.c
> @@ -0,0 +1,70 @@
> +/** @file
> + Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiPei.h>
> +
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Ppi/ReadOnlyVariable2.h>
> +#include <Library/PeiServicesLib.h>
> +
> +/**
> + Performs silicon pre-mem policy update.
> +
> + The meaning of Policy is defined by silicon code.
> + It could be the raw data, a handle, a PPI, etc.
> +
> + The input Policy must be returned by SiliconPolicyDonePreMem().
> +
> + 1) In FSP path, the input Policy should be FspmUpd.
> + A platform may use this API to update the FSPM UPD policy initialized
> + by the silicon module or the default UPD data.
> + The output of FSPM UPD data from this API is the final UPD data.
> +
> + 2) In non-FSP path, the board may use additional way to get
> + the silicon policy data field based upon the input Policy.
> +
> + @param[in, out] Policy Pointer to policy.
> +
> + @return the updated policy.
> +**/
> +VOID *
> +EFIAPI
> +SiliconPolicyUpdatePreMem (
> + IN OUT VOID *Policy
> + )
> +{
> + return Policy;
> +}
> +
> +/**
> + Performs silicon post-mem policy update.
> +
> + The meaning of Policy is defined by silicon code.
> + It could be the raw data, a handle, a PPI, etc.
> +
> + The input Policy must be returned by SiliconPolicyDonePostMem().
> +
> + 1) In FSP path, the input Policy should be FspsUpd.
> + A platform may use this API to update the FSPS UPD policy initialized
> + by the silicon module or the default UPD data.
> + The output of FSPS UPD data from this API is the final UPD data.
> +
> + 2) In non-FSP path, the board may use additional way to get
> + the silicon policy data field based upon the input Policy.
> +
> + @param[in, out] Policy Pointer to policy.
> +
> + @return the updated policy.
> +**/
> +VOID *
> +EFIAPI
> +SiliconPolicyUpdatePostMem (
> + IN OUT VOID *Policy
> + )
> +{
> + return Policy;
> +}
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> .c
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> .c
> new file mode 100644
> index 0000000000..82a2d60959
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> .c
> @@ -0,0 +1,148 @@
> +/** @file
> + This driver installs SMBIOS information for OVMF
> +
> + Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>
> + Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "SmbiosPlatformDxe.h"
> +
> +
> +/**
> +Reads 8-bits of CMOS data.
> +
> +Reads the 8-bits of CMOS data at the location specified by Index.
> +The 8-bit read value is returned.
> +
> +@param Index The CMOS location to read.
> +
> +@return The value read.
> +
> +**/
> +UINT8
> +EFIAPI
> +CmosRead8(
> + IN UINTN Index
> + )
> +{
> + IoWrite8(0x70, (UINT8)Index);
> + return IoRead8(0x71);
> +}
> +
> +UINT32
> +GetSystemMemorySizeBelow4gb(
> + VOID
> + )
> +{
> + UINT8 Cmos0x34;
> + UINT8 Cmos0x35;
> +
> + //
> + // CMOS 0x34/0x35 specifies the system memory above 16 MB.
> + // * CMOS(0x35) is the high byte
> + // * CMOS(0x34) is the low byte
> + // * The size is specified in 64kb chunks
> + // * Since this is memory above 16MB, the 16MB must be added
> + // into the calculation to get the total memory size.
> + //
> +
> + Cmos0x34 = (UINT8)CmosRead8(0x34);
> + Cmos0x35 = (UINT8)CmosRead8(0x35);
> +
> + return (UINT32)(((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) +
> SIZE_16MB);
> +}
> +
> +STATIC
> +UINT64
> +GetSystemMemorySizeAbove4gb(
> + VOID
> +)
> +{
> + UINT32 Size;
> + UINTN CmosIndex;
> +
> + //
> + // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
> + // * CMOS(0x5d) is the most significant size byte
> + // * CMOS(0x5c) is the middle size byte
> + // * CMOS(0x5b) is the least significant size byte
> + // * The size is specified in 64kb chunks
> + //
> +
> + Size = 0;
> + for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) {
> + Size = (UINT32)(Size << 8) + (UINT32)CmosRead8(CmosIndex);
> + }
> +
> + return LShiftU64(Size, 16);
> +}
> +
> +/**
> + Installs SMBIOS information for OVMF
> +
> + @param ImageHandle Module's image handle
> + @param SystemTable Pointer of EFI_SYSTEM_TABLE
> +
> + @retval EFI_SUCCESS Smbios data successfully installed
> + @retval Other Smbios data was not installed
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmbiosTablePublishEntry (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + EFI_STATUS Status;
> + EFI_SMBIOS_PROTOCOL *Smbios;
> + SMBIOS_TABLE_TYPE19 *Type19Record;
> + EFI_SMBIOS_HANDLE MemArrayMappedAddrSmbiosHandle;
> + UINT8 NumSlots;
> + UINT64 TotalMemorySize;
> +
> + //
> + // Find the SMBIOS protocol
> + //
> + Status = gBS->LocateProtocol (
> + &gEfiSmbiosProtocolGuid,
> + NULL,
> + (VOID**)&Smbios
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> + //
> + // Generate Memory Array Mapped Address info
> + //
> + NumSlots = 2;
> + TotalMemorySize = 0;
> + TotalMemorySize = GetSystemMemorySizeBelow4gb();
> + Type19Record = AllocatePool(sizeof(SMBIOS_TABLE_TYPE19));
> + ZeroMem(Type19Record, sizeof(SMBIOS_TABLE_TYPE19));
> + Type19Record->Hdr.Type =
> EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS;
> + Type19Record->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE19);
> + Type19Record->Hdr.Handle = 0;
> + Type19Record->StartingAddress = 0;
> + Type19Record->EndingAddress = (UINT32)RShiftU64(TotalMemorySize, 10) -
> 1;
> + Type19Record->MemoryArrayHandle = SMBIOS_HANDLE_PI_RESERVED;
> + Type19Record->PartitionWidth = (UINT8)(NumSlots);
> +
> + MemArrayMappedAddrSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> + Status = Smbios->Add(Smbios, NULL,
> &MemArrayMappedAddrSmbiosHandle,
> (EFI_SMBIOS_TABLE_HEADER*)Type19Record);
> + ASSERT_EFI_ERROR(Status);
> +
> + TotalMemorySize = GetSystemMemorySizeAbove4gb();
> + Type19Record->StartingAddress = 0xFFFFFFFF;
> + Type19Record->ExtendedStartingAddress = 0xFFFFFFFF;
> + Type19Record->ExtendedEndingAddress = TotalMemorySize + 0xFFFFFFFF -
> 1;
> +
> + MemArrayMappedAddrSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> + Status = Smbios->Add(Smbios, NULL,
> &MemArrayMappedAddrSmbiosHandle,
> (EFI_SMBIOS_TABLE_HEADER*)Type19Record);
> + FreePool(Type19Record);
> + ASSERT_EFI_ERROR(Status);
> +
> + return Status;
> +}
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf
> b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf
> new file mode 100644
> index 0000000000..839626eb86
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf
> @@ -0,0 +1,31 @@
> +## @file
> +# Component description file for PlatformAcpiTables module.
> +#
> +# ACPI table data and ASL sources required to boot the platform.
> +#
> +# Copyright (c) 2008 - 2018 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = PlatformAcpiTables
> + FILE_GUID = 7E374E25-8E01-4FEE-87F2-390C23C606CD
> + MODULE_TYPE = USER_DEFINED
> + VERSION_STRING = 1.0
> +
> +#
> +# The following information is for reference only and not required by the build
> tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 EBC
> +#
> +
> +[Sources]
> + Platform.h
> + Dsdt.asl
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> +
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl
> b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl
> new file mode 100644
> index 0000000000..76a8fbc081
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl
> @@ -0,0 +1,821 @@
> +/** @file
> + Contains root level name space objects for the platform
> +
> + Copyright (c) 2008 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +DefinitionBlock ("Dsdt.aml", "DSDT", 1, "INTEL ", "OVMF ", 4) {
> + //
> + // System Sleep States
> + //
> + Name (\_S3, Package () {5, 5, 0, 0})
> + Name (\_S4, Package () {6, 6, 0, 0})
> + Name (\_S5, Package () {7, 7, 0, 0})
> +
> + Name (GPIC, Zero)
> + Method (_PIC, 1, NotSerialized) // _PIC: Interrupt Model
> + {
> + GPIC = Arg0
> + }
> + //
> + // System Bus
> + //
> + Scope (\_SB) {
> + //
> + // PCI Root Bridge
> + //
> + Device (PCI0) {
> + Name (_HID, EISAID ("PNP0A03"))
> + Name (_ADR, 0x00000000)
> + Name (_BBN, 0x00)
> + Name (_UID, 0x00)
> +
> +
> + // Current resource settings
> + Name (_CRS, ResourceTemplate () {
> + WORDBusNumber ( // Bus number resource (0); the bridge produces
> bus numbers for its subsequent buses
> + ResourceProducer, // bit 0 of general flags is 1
> + MinFixed, // Range is fixed
> + MaxFixed, // Range is fixed
> + PosDecode, // PosDecode
> + 0x0000, // Granularity
> + 0x0000, // Min
> + 0x00FF, // Max
> + 0x0000, // Translation
> + 0x0100 // Range Length = Max-Min+1
> + )
> +
> + IO (Decode16, 0xCF8, 0xCF8, 0x01, 0x08) //Consumed resource
> (0xCF8-0xCFF)
> +
> + WORDIO ( // Consumed-and-produced resource (all I/O below
> CF8)
> + ResourceProducer, // bit 0 of general flags is 0
> + MinFixed, // Range is fixed
> + MaxFixed, // Range is fixed
> + PosDecode,
> + EntireRange,
> + 0x0000, // Granularity
> + 0x0000, // Min
> + 0x0CF7, // Max
> + 0x0000, // Translation
> + 0x0CF8 // Range Length
> + )
> +
> + WORDIO ( // Consumed-and-produced resource (all I/O above
> CFF)
> + ResourceProducer, // bit 0 of general flags is 0
> + MinFixed, // Range is fixed
> + MaxFixed, // Range is fixed
> + PosDecode,
> + EntireRange,
> + 0x0000, // Granularity
> + 0x0D00, // Min
> + 0xFFFF, // Max
> + 0x0000, // Translation
> + 0xF300 // Range Length
> + )
> +
> + DWORDMEMORY ( // Descriptor for legacy VGA video RAM
> + ResourceProducer, // bit 0 of general flags is 0
> + PosDecode,
> + MinFixed, // Range is fixed
> + MaxFixed, // Range is Fixed
> + Cacheable,
> + ReadWrite,
> + 0x00000000, // Granularity
> + 0x000A0000, // Min
> + 0x000BFFFF, // Max
> + 0x00000000, // Translation
> + 0x00020000 // Range Length
> + )
> +
> + DWORDMEMORY ( // Descriptor for 32-bit MMIO
> + ResourceProducer, // bit 0 of general flags is 0
> + PosDecode,
> + MinFixed, // Range is fixed
> + MaxFixed, // Range is Fixed
> + NonCacheable,
> + ReadWrite,
> + 0x00000000, // Granularity
> + 0xF0000000, // Min
> + 0xFBFFFFFF, // Max
> + 0x00000000, // Translation
> + 0x0C000000, // Range Length
> + , // ResourceSourceIndex
> + , // ResourceSource
> + PW32 // DescriptorName
> + )
> + })
> +
> + //
> + // PCI Interrupt Routing Table - PIC Mode Only
> + //
> + // If you change the IRQ mapping here you also need
> + // to change the mapping in the south bridge
> + // (pci-conf.py) and in the BIOS.
> + // INTA -> 0xa (10)
> + // INTB -> 0xb (11)
> + // INTC -> 0xa (10)
> + // INTD -> 0xb (11)
> +
> + Method (_PRT, 0, NotSerialized) {
> + If (GPIC) {
> + Return (AR00) // APIC Mode
> + }
> + Return (PR00) // PIC Mode
> + }
> +
> + Name (PR00, Package(){
> + Package () {0x000FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x000FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x000FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x000FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + //
> + // Bus 0, Device 1
> + //
> + Package () {0x0001FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x0001FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x0001FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x0001FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x0002FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x0002FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x0002FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x0002FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> + //
> + // Bus 0, Device 3
> + //
> + Package () {0x0003FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x0003FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x0003FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x0003FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x0004FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x0004FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x0004FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x0004FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x0005FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x0005FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x0005FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x0005FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x0006FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x0006FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x0006FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x0006FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x0007FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x0007FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x0007FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x0007FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x0008FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x0008FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x0008FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x0008FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x0009FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x0009FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x0009FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x0009FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x000AFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x000AFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x000AFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x000AFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x000BFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x000BFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x000BFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x000BFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x000CFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x000CFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x000CFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x000CFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x000DFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x000DFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x000DFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x000DFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x000EFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x000EFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x000EFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x000EFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x000FFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x000FFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x000FFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x000FFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x00010FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x00010FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x00010FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x00010FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x00011FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x00011FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x00011FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x00011FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x00012FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x00012FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x00012FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x00012FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x00013FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x00013FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x00013FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x00013FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x00014FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x00014FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x00014FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x00014FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x00015FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x00015FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x00015FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x00015FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x00016FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x00016FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x00016FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x00016FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x00017FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x00017FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x00017FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x00017FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x00018FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x00018FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x00018FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x00018FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x0001EFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x0001EFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x0001EFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x0001EFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x00019FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x00019FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x00019FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x00019FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x0001AFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x0001AFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x0001AFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x0001AFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x0001BFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x0001BFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x0001BFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x0001BFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x0001CFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x0001CFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x0001CFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x0001CFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x0001DFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x0001DFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x0001DFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x0001DFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> +
> + Package () {0x0001FFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
> + Package () {0x0001FFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
> + Package () {0x0001FFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
> + Package () {0x0001FFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
> + }
> + )
> +
> + Name(AR00, Package(){
> +
> + Package () {0x000FFFF, 0x00, 0, 16},
> + Package () {0x000FFFF, 0x01, 0, 17},
> + Package () {0x000FFFF, 0x02, 0, 18},
> + Package () {0x000FFFF, 0x03, 0, 19},
> +
> + //
> + // Bus 0, Device 1
> + //
> + Package () {0x0001FFFF, 0x00, 0, 16},
> + Package () {0x0001FFFF, 0x01, 0, 17},
> + Package () {0x0001FFFF, 0x02, 0, 18},
> + Package () {0x0001FFFF, 0x03, 0, 19},
> +
> + Package () {0x0002FFFF, 0x00, 0, 16},
> + Package () {0x0002FFFF, 0x01, 0, 17},
> + Package () {0x0002FFFF, 0x02, 0, 18},
> + Package () {0x0002FFFF, 0x03, 0, 19},
> + //
> + // Bus 0, Device 3
> + //
> + Package () {0x0003FFFF, 0x00, 0, 16},
> + Package () {0x0003FFFF, 0x01, 0, 17},
> + Package () {0x0003FFFF, 0x02, 0, 18},
> + Package () {0x0003FFFF, 0x03, 0, 19},
> +
> + Package () {0x0004FFFF, 0x00, 0, 16},
> + Package () {0x0004FFFF, 0x01, 0, 17},
> + Package () {0x0004FFFF, 0x02, 0, 18},
> + Package () {0x0004FFFF, 0x03, 0, 19},
> +
> + Package () {0x0005FFFF, 0x00, 0, 16},
> + Package () {0x0005FFFF, 0x01, 0, 17},
> + Package () {0x0005FFFF, 0x02, 0, 18},
> + Package () {0x0005FFFF, 0x03, 0, 19},
> +
> + Package () {0x0006FFFF, 0x00, 0, 16},
> + Package () {0x0006FFFF, 0x01, 0, 17},
> + Package () {0x0006FFFF, 0x02, 0, 18},
> + Package () {0x0006FFFF, 0x03, 0, 19},
> +
> + Package () {0x0007FFFF, 0x00, 0, 16},
> + Package () {0x0007FFFF, 0x01, 0, 17},
> + Package () {0x0007FFFF, 0x02, 0, 18},
> + Package () {0x0007FFFF, 0x03, 0, 19},
> +
> + Package () {0x0008FFFF, 0x00, 0, 16},
> + Package () {0x0008FFFF, 0x01, 0, 17},
> + Package () {0x0008FFFF, 0x02, 0, 18},
> + Package () {0x0008FFFF, 0x03, 0, 19},
> +
> + Package () {0x0009FFFF, 0x00, 0, 16},
> + Package () {0x0009FFFF, 0x01, 0, 17},
> + Package () {0x0009FFFF, 0x02, 0, 18},
> + Package () {0x0009FFFF, 0x03, 0, 19},
> +
> + Package () {0x000AFFFF, 0x00, 0, 16},
> + Package () {0x000AFFFF, 0x01, 0, 17},
> + Package () {0x000AFFFF, 0x02, 0, 18},
> + Package () {0x000AFFFF, 0x03, 0, 19},
> +
> + Package () {0x000BFFFF, 0x00, 0, 16},
> + Package () {0x000BFFFF, 0x01, 0, 17},
> + Package () {0x000BFFFF, 0x02, 0, 18},
> + Package () {0x000BFFFF, 0x03, 0, 19},
> +
> + Package () {0x000CFFFF, 0x00, 0, 16},
> + Package () {0x000CFFFF, 0x01, 0, 17},
> + Package () {0x000CFFFF, 0x02, 0, 18},
> + Package () {0x000CFFFF, 0x03, 0, 19},
> +
> + Package () {0x000DFFFF, 0x00, 0, 16},
> + Package () {0x000DFFFF, 0x01, 0, 17},
> + Package () {0x000DFFFF, 0x02, 0, 18},
> + Package () {0x000DFFFF, 0x03, 0, 19},
> +
> + Package () {0x000EFFFF, 0x00, 0, 16},
> + Package () {0x000EFFFF, 0x01, 0, 17},
> + Package () {0x000EFFFF, 0x02, 0C, 18},
> + Package () {0x000EFFFF, 0x03, 0, 19},
> +
> + Package () {0x000FFFFF, 0x00, 0, 16},
> + Package () {0x000FFFFF, 0x01, 0, 17},
> + Package () {0x000FFFFF, 0x02, 0, 18},
> + Package () {0x000FFFFF, 0x03, 0, 19},
> +
> + Package () {0x00010FFFF, 0x00, 0, 16},
> + Package () {0x00010FFFF, 0x01, 0, 17},
> + Package () {0x00010FFFF, 0x02, 0, 18},
> + Package () {0x00010FFFF, 0x03, 0, 19},
> +
> + Package () {0x00011FFFF, 0x00, 0, 16},
> + Package () {0x00011FFFF, 0x01, 0, 17},
> + Package () {0x00011FFFF, 0x02, 0, 18},
> + Package () {0x00011FFFF, 0x03, 0, 19},
> +
> + Package () {0x00012FFFF, 0x00, 0, 16},
> + Package () {0x00012FFFF, 0x01, 0, 17},
> + Package () {0x00012FFFF, 0x02, 0, 18},
> + Package () {0x00012FFFF, 0x03, 0, 19},
> +
> + Package () {0x00013FFFF, 0x00, 0, 16},
> + Package () {0x00013FFFF, 0x01, 0, 17},
> + Package () {0x00013FFFF, 0x02, 0, 18},
> + Package () {0x00013FFFF, 0x03, 0, 19},
> +
> + Package () {0x00014FFFF, 0x00, 0, 16},
> + Package () {0x00014FFFF, 0x01, 0, 17},
> + Package () {0x00014FFFF, 0x02, 0, 18},
> + Package () {0x00014FFFF, 0x03, 0, 19},
> +
> + Package () {0x00015FFFF, 0x00, 0, 16},
> + Package () {0x00015FFFF, 0x01, 0, 17},
> + Package () {0x00015FFFF, 0x02, 0, 18},
> + Package () {0x00015FFFF, 0x03, 0, 19},
> +
> + Package () {0x00016FFFF, 0x00, 0, 16},
> + Package () {0x00016FFFF, 0x01, 0, 17},
> + Package () {0x00016FFFF, 0x02, 0, 18},
> + Package () {0x00016FFFF, 0x03, 0, 19},
> +
> + Package () {0x00017FFFF, 0x00, 0, 16},
> + Package () {0x00017FFFF, 0x01, 0, 17},
> + Package () {0x00017FFFF, 0x02, 0, 18},
> + Package () {0x00017FFFF, 0x03, 0, 19},
> +
> + Package () {0x00018FFFF, 0x00, 0, 16},
> + Package () {0x00018FFFF, 0x01, 0, 17},
> + Package () {0x00018FFFF, 0x02, 0, 18},
> + Package () {0x00018FFFF, 0x03, 0, 19},
> +
> + Package () {0x0001EFFFF, 0x00, 0, 16},
> + Package () {0x0001EFFFF, 0x01, 0, 17},
> + Package () {0x0001EFFFF, 0x02, 0, 18},
> + Package () {0x0001EFFFF, 0x03, 0, 19},
> +
> + Package () {0x00019FFFF, 0x00, 0, 16},
> + Package () {0x00019FFFF, 0x01, 0, 17},
> + Package () {0x00019FFFF, 0x02, 0, 18},
> + Package () {0x00019FFFF, 0x03, 0, 19},
> +
> + Package () {0x0001AFFFF, 0x00, 0, 16},
> + Package () {0x0001AFFFF, 0x01, 0, 17},
> + Package () {0x0001AFFFF, 0x02, 0, 18},
> + Package () {0x0001AFFFF, 0x03, 0, 19},
> +
> + Package () {0x0001BFFFF, 0x00, 0, 16},
> + Package () {0x0001BFFFF, 0x01, 0, 17},
> + Package () {0x0001BFFFF, 0x02, 0, 18},
> + Package () {0x0001BFFFF, 0x03, 0, 19},
> +
> + Package () {0x0001CFFFF, 0x00, 0, 16},
> + Package () {0x0001CFFFF, 0x01, 0, 17},
> + Package () {0x0001CFFFF, 0x02, 0, 18},
> + Package () {0x0001CFFFF, 0x03, 0, 19},
> +
> + Package () {0x0001DFFFF, 0x00, 0, 16},
> + Package () {0x0001DFFFF, 0x01, 0, 17},
> + Package () {0x0001DFFFF, 0x02, 0, 18},
> + Package () {0x0001DFFFF, 0x03, 0, 19},
> +
> + Package () {0x0001FFFFF, 0x00, 0, 16},
> + Package () {0x0001FFFFF, 0x01, 0, 17},
> + Package () {0x0001FFFFF, 0x02, 0, 18},
> + Package () {0x0001FFFFF, 0x03, 0, 19},
> + }
> + )
> +
> + //
> + // PCI to ISA Bridge (Bus 0, Device 7, Function 0)
> + //
> + Device (LPC) {
> + Name (_ADR, 0x001F0000)
> +
> + //
> + // PCI Interrupt Routing Configuration Registers
> + //
> + OperationRegion (PRR0, PCI_Config, 0x60, 0x0C)
> + Field (PRR0, ANYACC, NOLOCK, PRESERVE) {
> + PIRA, 8,
> + PIRB, 8,
> + PIRC, 8,
> + PIRD, 8,
> + Offset (0x04),
> + PIRE, 8,
> + PIRF, 8,
> + PIRG, 8,
> + PIRH, 8
> + }
> +
> + //
> + // _STA method for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH
> + //
> + Method (PSTA, 1, NotSerialized) {
> + If (And (Arg0, 0x80)) {
> + Return (0x9)
> + } Else {
> + Return (0xB)
> + }
> + }
> +
> + //
> + // _DIS method for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH
> + //
> + Method (PDIS, 1, NotSerialized) {
> + Or (Arg0, 0x80, Arg0)
> + }
> +
> + //
> + // _CRS method for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH
> + //
> + Method (PCRS, 1, NotSerialized) {
> + Name (BUF0, ResourceTemplate () {IRQ (Level, ActiveLow, Shared){0}})
> + //
> + // Define references to buffer elements
> + //
> + CreateWordField (BUF0, 0x01, IRQW) // IRQ low
> + //
> + // Write current settings into IRQ descriptor
> + //
> + If (And (Arg0, 0x80)) {
> + Store (Zero, Local0)
> + } Else {
> + Store (One, Local0)
> + }
> + //
> + // Shift 1 by value in register 70
> + //
> + ShiftLeft (Local0, And (Arg0, 0x0F), IRQW) // Save in buffer
> + Return (BUF0) // Return Buf0
> + }
> +
> + //
> + // _PRS resource for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH
> + //
> + Name (PPRS, ResourceTemplate () {
> + IRQ (Level, ActiveLow, Shared) {3, 4, 5, 7, 9, 10, 11, 12, 14, 15}
> + })
> +
> + //
> + // _SRS method for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH
> + //
> + Method (PSRS, 2, NotSerialized) {
> + CreateWordField (Arg1, 0x01, IRQW) // IRQ low
> + FindSetRightBit (IRQW, Local0) // Set IRQ
> + If (LNotEqual (IRQW, Zero)) {
> + And (Local0, 0x7F, Local0)
> + Decrement (Local0)
> + } Else {
> + Or (Local0, 0x80, Local0)
> + }
> + Store (Local0, Arg0)
> + }
> +
> + //
> + // PCI IRQ Link A
> + //
> + Device (LNKA) {
> + Name (_HID, EISAID("PNP0C0F"))
> + Name (_UID, 1)
> +
> + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRA)) }
> + Method (_DIS, 0, NotSerialized) { PDIS (PIRA) }
> + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRA)) }
> + Method (_PRS, 0, NotSerialized) { Return (PPRS) }
> + Method (_SRS, 1, NotSerialized) { PSRS (PIRA, Arg0) }
> + }
> +
> + //
> + // PCI IRQ Link B
> + //
> + Device (LNKB) {
> + Name (_HID, EISAID("PNP0C0F"))
> + Name (_UID, 2)
> +
> + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRB)) }
> + Method (_DIS, 0, NotSerialized) { PDIS (PIRB) }
> + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRB)) }
> + Method (_PRS, 0, NotSerialized) { Return (PPRS) }
> + Method (_SRS, 1, NotSerialized) { PSRS (PIRB, Arg0) }
> + }
> +
> + //
> + // PCI IRQ Link C
> + //
> + Device (LNKC) {
> + Name (_HID, EISAID("PNP0C0F"))
> + Name (_UID, 3)
> +
> + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRC)) }
> + Method (_DIS, 0, NotSerialized) { PDIS (PIRC) }
> + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRC)) }
> + Method (_PRS, 0, NotSerialized) { Return (PPRS) }
> + Method (_SRS, 1, NotSerialized) { PSRS (PIRC, Arg0) }
> + }
> +
> + //
> + // PCI IRQ Link D
> + //
> + Device (LNKD) {
> + Name (_HID, EISAID("PNP0C0F"))
> + Name (_UID, 4)
> +
> + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRD)) }
> + Method (_DIS, 0, NotSerialized) { PDIS (PIRD) }
> + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRD)) }
> + Method (_PRS, 0, NotSerialized) { Return (PPRS) }
> + Method (_SRS, 1, NotSerialized) { PSRS (PIRD, Arg0) }
> + }
> +
> + //
> + // PCI IRQ Link E
> + //
> + Device (LNKE) {
> + Name (_HID, EISAID("PNP0C0F"))
> + Name (_UID, 5)
> +
> + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRE)) }
> + Method (_DIS, 0, NotSerialized) { PDIS (PIRE) }
> + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRE)) }
> + Method (_PRS, 0, NotSerialized) { Return (PPRS) }
> + Method (_SRS, 1, NotSerialized) { PSRS (PIRE, Arg0) }
> + }
> +
> + //
> + // PCI IRQ Link F
> + //
> + Device (LNKF) {
> + Name (_HID, EISAID("PNP0C0F"))
> + Name (_UID, 6)
> +
> + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRF)) }
> + Method (_DIS, 0, NotSerialized) { PDIS (PIRF) }
> + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRF)) }
> + Method (_PRS, 0, NotSerialized) { Return (PPRS) }
> + Method (_SRS, 1, NotSerialized) { PSRS (PIRF, Arg0) }
> + }
> +
> + //
> + // PCI IRQ Link G
> + //
> + Device (LNKG) {
> + Name (_HID, EISAID("PNP0C0F"))
> + Name (_UID, 7)
> +
> + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRG)) }
> + Method (_DIS, 0, NotSerialized) { PDIS (PIRG) }
> + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRG)) }
> + Method (_PRS, 0, NotSerialized) { Return (PPRS) }
> + Method (_SRS, 1, NotSerialized) { PSRS (PIRG, Arg0) }
> + }
> +
> + //
> + // PCI IRQ Link H
> + //
> + Device (LNKH) {
> + Name (_HID, EISAID("PNP0C0F"))
> + Name (_UID, 8)
> +
> + Method (_STA, 0, NotSerialized) { Return (PSTA (PIRH)) }
> + Method (_DIS, 0, NotSerialized) { PDIS (PIRH) }
> + Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRH)) }
> + Method (_PRS, 0, NotSerialized) { Return (PPRS) }
> + Method (_SRS, 1, NotSerialized) { PSRS (PIRH, Arg0) }
> + }
> +
> + //
> + // Programmable Interrupt Controller (PIC)
> + //
> + Device(PIC) {
> + Name (_HID, EISAID ("PNP0000"))
> + Name (_CRS, ResourceTemplate () {
> + IO (Decode16, 0x020, 0x020, 0x00, 0x02)
> + IO (Decode16, 0x0A0, 0x0A0, 0x00, 0x02)
> + IO (Decode16, 0x4D0, 0x4D0, 0x00, 0x02)
> + IRQNoFlags () {2}
> + })
> + }
> +
> + //
> + // ISA DMA
> + //
> + Device (DMAC) {
> + Name (_HID, EISAID ("PNP0200"))
> + Name (_CRS, ResourceTemplate () {
> + IO (Decode16, 0x00, 0x00, 0, 0x10)
> + IO (Decode16, 0x81, 0x81, 0, 0x03)
> + IO (Decode16, 0x87, 0x87, 0, 0x01)
> + IO (Decode16, 0x89, 0x89, 0, 0x03)
> + IO (Decode16, 0x8f, 0x8f, 0, 0x01)
> + IO (Decode16, 0xc0, 0xc0, 0, 0x20)
> + DMA (Compatibility, NotBusMaster, Transfer8) {4}
> + })
> + }
> +
> + //
> + // 8254 Timer
> + //
> + Device(TMR) {
> + Name(_HID,EISAID("PNP0100"))
> + Name(_CRS, ResourceTemplate () {
> + IO (Decode16, 0x40, 0x40, 0x00, 0x04)
> + IRQNoFlags () {0}
> + })
> + }
> +
> + //
> + // Real Time Clock
> + //
> + Device (RTC) {
> + Name (_HID, EISAID ("PNP0B00"))
> + Name (_CRS, ResourceTemplate () {
> + IO (Decode16, 0x70, 0x70, 0x00, 0x02)
> + IRQNoFlags () {8}
> + })
> + }
> +
> + //
> + // PCAT Speaker
> + //
> + Device(SPKR) {
> + Name (_HID, EISAID("PNP0800"))
> + Name (_CRS, ResourceTemplate () {
> + IO (Decode16, 0x61, 0x61, 0x01, 0x01)
> + })
> + }
> +
> + //
> + // Floating Point Coprocessor
> + //
> + Device(FPU) {
> + Name (_HID, EISAID("PNP0C04"))
> + Name (_CRS, ResourceTemplate () {
> + IO (Decode16, 0xF0, 0xF0, 0x00, 0x10)
> + IRQNoFlags () {13}
> + })
> + }
> +
> + //
> + // Generic motherboard devices and pieces that don't fit anywhere else
> + //
> + Device(XTRA) {
> + Name (_HID, EISAID ("PNP0C02"))
> + Name (_UID, 0x01)
> + Name (_CRS, ResourceTemplate () {
> + IO (Decode16, 0x010, 0x010, 0x00, 0x10)
> + IO (Decode16, 0x022, 0x022, 0x00, 0x1E)
> + IO (Decode16, 0x044, 0x044, 0x00, 0x1C)
> + IO (Decode16, 0x062, 0x062, 0x00, 0x02)
> + IO (Decode16, 0x065, 0x065, 0x00, 0x0B)
> + IO (Decode16, 0x072, 0x072, 0x00, 0x0E)
> + IO (Decode16, 0x080, 0x080, 0x00, 0x01)
> + IO (Decode16, 0x084, 0x084, 0x00, 0x03)
> + IO (Decode16, 0x088, 0x088, 0x00, 0x01)
> + IO (Decode16, 0x08c, 0x08c, 0x00, 0x03)
> + IO (Decode16, 0x090, 0x090, 0x00, 0x10)
> + IO (Decode16, 0x0A2, 0x0A2, 0x00, 0x1E)
> + IO (Decode16, 0x0E0, 0x0E0, 0x00, 0x10)
> + IO (Decode16, 0x1E0, 0x1E0, 0x00, 0x10)
> + IO (Decode16, 0x160, 0x160, 0x00, 0x10)
> + IO (Decode16, 0x278, 0x278, 0x00, 0x08)
> + IO (Decode16, 0x370, 0x370, 0x00, 0x02)
> + IO (Decode16, 0x378, 0x378, 0x00, 0x08)
> + IO (Decode16, 0x400, 0x400, 0x00, 0x40) // PMBLK1
> + IO (Decode16, 0x440, 0x440, 0x00, 0x10)
> + IO (Decode16, 0x678, 0x678, 0x00, 0x08)
> + IO (Decode16, 0x778, 0x778, 0x00, 0x08)
> + Memory32Fixed (ReadOnly, 0xFEC00000, 0x1000) // IO APIC
> + Memory32Fixed (ReadOnly, 0xFEE00000, 0x100000) // LAPIC
> + })
> + }
> +
> + //
> + // PS/2 Keyboard and PC/AT Enhanced Keyboard 101/102
> + //
> + Device (PS2K) {
> + Name (_HID, EISAID ("PNP0303"))
> + Name (_CID, EISAID ("PNP030B"))
> + Name(_CRS,ResourceTemplate() {
> + IO (Decode16, 0x60, 0x60, 0x00, 0x01)
> + IO (Decode16, 0x64, 0x64, 0x00, 0x01)
> + IRQNoFlags () {1}
> + })
> + }
> +
> + //
> + // PS/2 Mouse and Microsoft Mouse
> + //
> + Device (PS2M) { // PS/2 stype mouse port
> + Name (_HID, EISAID ("PNP0F03"))
> + Name (_CID, EISAID ("PNP0F13"))
> + Name (_CRS, ResourceTemplate() {
> + IRQNoFlags () {12}
> + })
> + }
> +
> + //
> + // UART Serial Port - COM1
> + //
> + Device (UAR1) {
> + Name (_HID, EISAID ("PNP0501"))
> + Name (_DDN, "COM1")
> + Name (_UID, 0x01)
> + Name(_CRS,ResourceTemplate() {
> + IO (Decode16, 0x3F8, 0x3F8, 0x00, 0x08)
> + IRQ (Edge, ActiveHigh, Exclusive, ) {4}
> + })
> + }
> +
> + //
> + // UART Serial Port - COM2
> + //
> + Device (UAR2) {
> + Name (_HID, EISAID ("PNP0501"))
> + Name (_DDN, "COM2")
> + Name (_UID, 0x02)
> + Name(_CRS,ResourceTemplate() {
> + IO (Decode16, 0x2F8, 0x2F8, 0x00, 0x08)
> + IRQ (Edge, ActiveHigh, Exclusive, ) {3}
> + })
> + }
> + }
> + }
> + }
> +}
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h
> b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h
> new file mode 100644
> index 0000000000..6395ec11e2
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h
> @@ -0,0 +1,75 @@
> +/** @file
> + Platform specific defines for constructing ACPI tables
> +
> + Copyright (c) 2013 - 2008 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _Platform_h_INCLUDED_
> +#define _Platform_h_INCLUDED_
> +
> +#include <PiDxe.h>
> +#include <IndustryStandard/Acpi.h>
> +
> +//
> +// ACPI table information used to initialize tables.
> +//
> +#define EFI_ACPI_OEM_ID 'O','V','M','F',' ',' ' // OEMID 6 bytes long
> +#define EFI_ACPI_OEM_TABLE_ID
> SIGNATURE_64('O','V','M','F','E','D','K','2') // OEM table id 8 bytes long
> +#define EFI_ACPI_OEM_REVISION 0x02000820
> +#define EFI_ACPI_CREATOR_ID SIGNATURE_32('O','V','M','F')
> +#define EFI_ACPI_CREATOR_REVISION 0x00000097
> +
> +#define INT_MODEL 0x01
> +#define SCI_INT_VECTOR 0x0009
> +#define SMI_CMD_IO_PORT 0xB2
> +#define ACPI_ENABLE 0x0E1
> +#define ACPI_DISABLE 0x01E
> +#define S4BIOS_REQ 0x00
> +#define PM1a_EVT_BLK 0x00000400
> +#define PM1b_EVT_BLK 0x00000000
> +#define PM1a_CNT_BLK 0x00000404
> +#define PM1b_CNT_BLK 0x00000000
> +#define PM2_CNT_BLK 0x00000450
> +#define PM_TMR_BLK 0x00000408
> +#define GPE0_BLK 0x00000420
> +#define GPE1_BLK 0x00000000
> +#define PM1_EVT_LEN 0x04
> +#define PM1_CNT_LEN 0x04
> +#define PM2_CNT_LEN 0x01
> +#define PM_TM_LEN 0x04
> +#define GPE0_BLK_LEN 0x10
> +#define GPE1_BLK_LEN 0x00
> +#define GPE1_BASE 0x00
> +#define RESERVED 0x00
> +#define P_LVL2_LAT 0x0065
> +#define P_LVL3_LAT 0x03E9
> +#define FLUSH_SIZE 0x0400
> +#define FLUSH_STRIDE 0x0010
> +#define DUTY_OFFSET 0x00
> +#define DUTY_WIDTH 0x00
> +#define DAY_ALRM 0x0D
> +#define MON_ALRM 0x00
> +#define CENTURY 0x00
> +#define FLAG (EFI_ACPI_2_0_WBINVD | \
> + EFI_ACPI_2_0_PROC_C1 | \
> + EFI_ACPI_2_0_SLP_BUTTON | \
> + EFI_ACPI_2_0_RTC_S4 | \
> + EFI_ACPI_2_0_RESET_REG_SUP)
> +#define RESET_REG 0xCF9
> +#define RESET_VALUE (BIT2 | BIT1) // PIIX3 Reset CPU + System Reset
> +
> +//
> +// Byte-aligned IO port register block initializer for
> +// EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE
> +//
> +#define GAS2_IO(Base, Size) { \
> + EFI_ACPI_2_0_SYSTEM_IO, /* AddressSpaceId */ \
> + (Size) * 8, /* RegisterBitWidth */ \
> + 0, /* RegisterBitOffset */ \
> + 0, /* Reserved */ \
> + (Base) /* Address */ \
> + }
> +
> +#endif
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsX58PlatformConfig.
> h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsX58PlatformConfig.
> h
> new file mode 100644
> index 0000000000..f65f61d74d
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsX58PlatformConfig.
> h
> @@ -0,0 +1,17 @@
> +/** @file
> + GUID for UEFI variables that are specific to OVMF configuration.
> +
> + Copyright (C) 2014, Red Hat, Inc.
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __SIMICSX58_PLATFORM_CONFIG_H__
> +#define __SIMICSX58_PLATFORM_CONFIG_H__
> +
> +#define SIMICSX58_PLATFORM_CONFIG_GUID \
> +{0xeed35f57, 0x4ff2, 0x4244, {0xb8, 0x3a, 0xea, 0x71, 0x5f, 0xd3, 0x59,
> 0xa5}}
> +
> +extern EFI_GUID gSimicsX58PlatformConfigGuid;
> +
> +#endif
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h
> new file mode 100644
> index 0000000000..36c08176d1
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h
> @@ -0,0 +1,106 @@
> +/** @file
> + Various register numbers and value bits based on the following publications:
> + - Intel(R) datasheet 319973-003
> + - Intel(R) datasheet 319974-017US
> +
> + Copyright (C) 2015, Red Hat, Inc.
> + Copyright (c) 2014, Gabriel L. Somlo <somlo@cmu.edu>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __X58_ICH10_H__
> +#define __X58_ICH10_H__
> +
> +#include <Library/PciLib.h>
> +
> +//
> +// Host Bridge Device ID (DID) value for ICH10
> +//
> +#define INTEL_ICH10_DEVICE_ID 0x3400
> +
> +//
> +// B/D/F/Type: 0/0/0/PCI
> +//
> +#define DRAMC_REGISTER_Q35(Offset) PCI_LIB_ADDRESS (0, 0, 0, (Offset))
> +#define DRAMC_REGISTER_X58(Offset) PCI_LIB_ADDRESS (0, 20, 0, (Offset))
> +#define MCH_GGC 0x52
> +#define MCH_GGC_IVD BIT1
> +
> +#define MCH_PCIEXBAR_LOW 0x10C
> +#define MCH_PCIEXBAR_LID 0x10E
> +#define MCH_PCIEXBAR_SHIFT 16
> +#define MCH_PCIEXBAR_LOWMASK 0x0FFFFFFF
> +#define MCH_PCIEXBAR_BUS_FF 0
> +#define MCH_PCIEXBAR_EN BIT0
> +
> +#define MCH_PCIEXBAR_HIGH 0x64
> +#define MCH_PCIEXBAR_HIGHMASK 0xFFFFFFF0
> +
> +#define MCH_SMRAM 0x9D
> +#define MCH_SMRAM_D_LCK BIT4
> +#define MCH_SMRAM_G_SMRAME BIT3
> +
> +#define MCH_ESMRAMC 0x9E
> +#define MCH_ESMRAMC_H_SMRAME BIT7
> +#define MCH_ESMRAMC_E_SMERR BIT6
> +#define MCH_ESMRAMC_SM_CACHE BIT5
> +#define MCH_ESMRAMC_SM_L1 BIT4
> +#define MCH_ESMRAMC_SM_L2 BIT3
> +#define MCH_ESMRAMC_TSEG_8MB BIT3
> +#define MCH_ESMRAMC_TSEG_2MB BIT2
> +#define MCH_ESMRAMC_TSEG_1MB BIT1
> +#define MCH_ESMRAMC_TSEG_MASK (BIT3 | BIT2 | BIT1)
> +#define MCH_ESMRAMC_T_EN BIT0
> +
> +#define MCH_GBSM 0xA4
> +#define MCH_GBSM_MB_SHIFT 20
> +
> +#define MCH_BGSM 0xA8
> +#define MCH_BGSM_MB_SHIFT 20
> +
> +#define MCH_TSEGMB 0xA8
> +#define MCH_TSEGMB_MB_SHIFT 20
> +
> +#define MCH_TOLUD 0xD0
> +
> +//
> +// B/D/F/Type: 0/0x1f/0/PCI
> +//
> +#define POWER_MGMT_REGISTER_ICH10(Offset) \
> + PCI_LIB_ADDRESS (0, 0x1f, 0, (Offset))
> +
> +#define ICH10_PMBASE 0x40
> +#define ICH10_PMBASE_MASK (BIT15 | BIT14 | BIT13 | BIT12 | BIT11 |
> \
> + BIT10 | BIT9 | BIT8 | BIT7)
> +
> +#define ICH10_ACPI_CNTL 0x44
> +#define ICH10_ACPI_CNTL_ACPI_EN BIT7
> +
> +#define ICH10_GEN_PMCON_1 0xA0
> +#define ICH10_GEN_PMCON_1_SMI_LOCK BIT4
> +
> +#define ICH10_RCBA 0xF0
> +#define ICH10_RCBA_EN BIT0
> +
> +#define ICH10_PMBASE_IO 0x400
> +//
> +// IO ports
> +//
> +#define ICH10_APM_CNT 0xB2
> +#define ICH10_APM_STS 0xB3
> +
> +//
> +// IO ports relative to PMBASE
> +//
> +#define ICH10_PMBASE_OFS_SMI_EN 0x30
> +#define ICH10_SMI_EN_APMC_EN BIT5
> +#define ICH10_SMI_EN_GBL_SMI_EN BIT0
> +#define ICH10_SMI_EN_EOS BIT1 // End of SMI
> +
> +#define ICH10_PMBASE_OFS_SMI_STS 0x34
> +#define ICH10_SMI_STS_APM BIT5 // APM Status
> +
> +#define ICH10_ROOT_COMPLEX_BASE 0xFED1C000
> +
> +#endif
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h
> new file mode 100644
> index 0000000000..12aeb1227c
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h
> @@ -0,0 +1,298 @@
> +/** @file
> + EFI ISA ACPI Protocol is used to enumerate and manage all the ISA controllers
> on
> + the platform's ISA Bus.
> +
> +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef __ISA_ACPI_H_
> +#define __ISA_ACPI_H_
> +
> +///
> +/// Global ID for the EFI ISA ACPI Protocol.
> +///
> +#define EFI_ISA_ACPI_PROTOCOL_GUID \
> + { \
> + 0x64a892dc, 0x5561, 0x4536, { 0x92, 0xc7, 0x79, 0x9b, 0xfc, 0x18, 0x33,
> 0x55 } \
> + }
> +
> +///
> +/// Forward declaration fo the EFI ISA ACPI Protocol
> +///
> +typedef struct _EFI_ISA_ACPI_PROTOCOL EFI_ISA_ACPI_PROTOCOL;
> +
> +///
> +/// ISA ACPI Protocol interrupt resource attributes.
> +///
> +#define EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_EDGE_SENSITIVE 0x01 ///<
> Edge triggered interrupt on a rising edge.
> +#define EFI_ISA_ACPI_IRQ_TYPE_LOW_TRUE_EDGE_SENSITIVE 0x02 ///<
> Edge triggered interrupt on a falling edge.
> +#define EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_LEVEL_SENSITIVE 0x04 ///<
> Level sensitive interrupt active high.
> +#define EFI_ISA_ACPI_IRQ_TYPE_LOW_TRUE_LEVEL_SENSITIVE 0x08 ///<
> Level sensitive interrupt active low.
> +
> +///
> +/// ISA ACPI Protocol DMA resource attributes.
> +///
> +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_MASK 0x03 ///< Bit mask
> of supported DMA speed attributes.
> +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_COMPATIBILITY 0x00 ///< ISA
> controller supports compatibility mode DMA transfers.
> +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_A 0x01 ///< ISA
> controller supports type A DMA transfers.
> +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_B 0x02 ///< ISA
> controller supports type B DMA transfers.
> +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_F 0x03 ///< ISA
> controller supports type F DMA transfers.
> +#define EFI_ISA_ACPI_DMA_COUNT_BY_BYTE 0x04 ///< ISA
> controller increments DMA address by bytes (8-bit).
> +#define EFI_ISA_ACPI_DMA_COUNT_BY_WORD 0x08 ///< ISA
> controller increments DMA address by words (16-bit).
> +#define EFI_ISA_ACPI_DMA_BUS_MASTER 0x10 ///< ISA
> controller is a DMA bus master.
> +#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_8_BIT 0x20 ///< ISA
> controller only supports 8-bit DMA transfers.
> +#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_8_BIT_AND_16_BIT 0x40
> ///< ISA controller both 8-bit and 16-bit DMA transfers.
> +#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_16_BIT 0x80 ///< ISA
> controller only supports 16-bit DMA transfers.
> +
> +///
> +/// ISA ACPI Protocol MMIO resource attributes
> +///
> +#define EFI_ISA_ACPI_MEMORY_WIDTH_MASK 0x03 ///< Bit mask
> of supported ISA memory width attributes.
> +#define EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT 0x00 ///< ISA
> MMIO region only supports 8-bit access.
> +#define EFI_ISA_ACPI_MEMORY_WIDTH_16_BIT 0x01 ///< ISA
> MMIO region only supports 16-bit access.
> +#define EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT_AND_16_BIT 0x02 ///<
> ISA MMIO region supports both 8-bit and 16-bit access.
> +#define EFI_ISA_ACPI_MEMORY_WRITEABLE 0x04 ///< ISA MMIO
> region supports write transactions.
> +#define EFI_ISA_ACPI_MEMORY_CACHEABLE 0x08 ///< ISA MMIO
> region supports being cached.
> +#define EFI_ISA_ACPI_MEMORY_SHADOWABLE 0x10 ///< ISA
> MMIO region may be shadowed.
> +#define EFI_ISA_ACPI_MEMORY_EXPANSION_ROM 0x20 ///< ISA
> MMIO region is an expansion ROM.
> +
> +///
> +/// ISA ACPI Protocol I/O resource attributes
> +///
> +#define EFI_ISA_ACPI_IO_DECODE_10_BITS 0x01 ///< ISA
> controllers uses a 10-bit address decoder for I/O cycles.
> +#define EFI_ISA_ACPI_IO_DECODE_16_BITS 0x02 ///< ISA
> controllers uses a 16-bit address decoder for I/O cycles.
> +
> +///
> +/// EFI ISA ACPI resource type
> +///
> +typedef enum {
> + EfiIsaAcpiResourceEndOfList, ///< Marks the end if a resource list.
> + EfiIsaAcpiResourceIo, ///< ISA I/O port resource range.
> + EfiIsaAcpiResourceMemory, ///< ISA MMIO resource range.
> + EfiIsaAcpiResourceDma, ///< ISA DMA resource.
> + EfiIsaAcpiResourceInterrupt ///< ISA interrupt resource.
> +} EFI_ISA_ACPI_RESOURCE_TYPE;
> +
> +///
> +/// EFI ISA ACPI generic resource structure
> +///
> +typedef struct {
> + EFI_ISA_ACPI_RESOURCE_TYPE Type; ///< The type of resource (I/O,
> MMIO, DMA, Interrupt).
> + UINT32 Attribute; ///< Bit mask of attributes associated with this
> resource. See EFI_ISA_ACPI_xxx macros for valid combinations.
> + UINT32 StartRange; ///< The start of the resource range.
> + UINT32 EndRange; ///< The end of the resource range.
> +} EFI_ISA_ACPI_RESOURCE;
> +
> +///
> +/// EFI ISA ACPI resource device identifier
> +///
> +typedef struct {
> + UINT32 HID; ///< The ACPI Hardware Identifier value associated with an ISA
> controller. Matchs ACPI DSDT contents.
> + UINT32 UID; ///< The ACPI Unique Identifier value associated with an ISA
> controller. Matches ACPI DSDT contents.
> +} EFI_ISA_ACPI_DEVICE_ID;
> +
> +///
> +/// EFI ISA ACPI resource list
> +///
> +typedef struct {
> + EFI_ISA_ACPI_DEVICE_ID Device; ///< The ACPI HID/UID associated with
> an ISA controller.
> + EFI_ISA_ACPI_RESOURCE *ResourceItem; ///< A pointer to the list of
> resources associated with an ISA controller.
> +} EFI_ISA_ACPI_RESOURCE_LIST;
> +
> +/**
> + Enumerates the ISA controllers on an ISA bus.
> +
> + This service allows all the ISA controllers on an ISA bus to be enumerated. If
> + Device is a pointer to a NULL value, then the first ISA controller on the ISA
> + bus is returned in Device and EFI_SUCCESS is returned. If Device is a pointer
> + to a value that was returned on a prior call to DeviceEnumerate(), then the
> next
> + ISA controller on the ISA bus is returned in Device and EFI_SUCCESS is
> returned.
> + If Device is a pointer to the last ISA controller on the ISA bus, then
> + EFI_NOT_FOUND is returned.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> + @param[out] Device The pointer to an ISA controller named by ACPI
> HID/UID.
> +
> + @retval EFI_SUCCESS The next ISA controller on the ISA bus was returned.
> + @retval EFI_NOT_FOUND No device found.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_DEVICE_ENUMERATE)(
> + IN EFI_ISA_ACPI_PROTOCOL *This,
> + OUT EFI_ISA_ACPI_DEVICE_ID **Device
> + );
> +
> +/**
> + Sets the power state of an ISA controller.
> +
> + This services sets the power state of the ISA controller specified by Device to
> + the power state specified by OnOff. TRUE denotes on, FALSE denotes off.
> + If the power state is sucessfully set on the ISA Controller, then
> + EFI_SUCCESS is returned.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> + @param[in] Device The pointer to an ISA controller named by ACPI HID/UID.
> + @param[in] OnOff TRUE denotes on, FALSE denotes off.
> +
> + @retval EFI_SUCCESS Successfully set the power state of the ISA controller.
> + @retval Other The ISA controller could not be placed in the requested
> power state.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_SET_DEVICE_POWER)(
> + IN EFI_ISA_ACPI_PROTOCOL *This,
> + IN EFI_ISA_ACPI_DEVICE_ID *Device,
> + IN BOOLEAN OnOff
> + );
> +
> +/**
> + Retrieves the current set of resources associated with an ISA controller.
> +
> + Retrieves the set of I/O, MMIO, DMA, and interrupt resources currently
> + assigned to the ISA controller specified by Device. These resources
> + are returned in ResourceList.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> + @param[in] Device The pointer to an ISA controller named by ACPI
> HID/UID.
> + @param[out] ResourceList The pointer to the current resource list for Device.
> +
> + @retval EFI_SUCCESS Successfully retrieved the current resource list.
> + @retval EFI_NOT_FOUND The resource list could not be retrieved.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_GET_CUR_RESOURCE)(
> + IN EFI_ISA_ACPI_PROTOCOL *This,
> + IN EFI_ISA_ACPI_DEVICE_ID *Device,
> + OUT EFI_ISA_ACPI_RESOURCE_LIST **ResourceList
> + );
> +
> +/**
> + Retrieves the set of possible resources that may be assigned to an ISA
> controller
> + with SetResource().
> +
> + Retrieves the possible sets of I/O, MMIO, DMA, and interrupt resources for
> the
> + ISA controller specified by Device. The sets are returned in ResourceList.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> + @param[in] Device The pointer to an ISA controller named by ACPI
> HID/UID.
> + @param[out] ResourceList The pointer to the returned list of resource lists.
> +
> + @retval EFI_UNSUPPORTED This service is not supported.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_GET_POS_RESOURCE)(
> + IN EFI_ISA_ACPI_PROTOCOL *This,
> + IN EFI_ISA_ACPI_DEVICE_ID *Device,
> + OUT EFI_ISA_ACPI_RESOURCE_LIST **ResourceList
> + );
> +
> +/**
> + Assigns resources to an ISA controller.
> +
> + Assigns the I/O, MMIO, DMA, and interrupt resources specified by
> ResourceList
> + to the ISA controller specified by Device. ResourceList must match a resource
> list returned by GetPosResource() for the same ISA controller.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> + @param[in] Device The pointer to an ISA controller named by ACPI
> HID/UID.
> + @param[in] ResourceList The pointer to a resources list that must be one of
> the
> + resource lists returned by GetPosResource() for the
> + ISA controller specified by Device.
> +
> + @retval EFI_SUCCESS Successfully set resources on the ISA controller.
> + @retval Other The resources could not be set for the ISA controller.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_SET_RESOURCE)(
> + IN EFI_ISA_ACPI_PROTOCOL *This,
> + IN EFI_ISA_ACPI_DEVICE_ID *Device,
> + IN EFI_ISA_ACPI_RESOURCE_LIST *ResourceList
> + );
> +
> +/**
> + Enables or disables an ISA controller.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> + @param[in] Device The pointer to the ISA controller to enable/disable.
> + @param[in] Enable TRUE to enable the ISA controller. FALSE to disable the
> + ISA controller.
> +
> + @retval EFI_SUCCESS Successfully enabled/disabled the ISA controller.
> + @retval Other The ISA controller could not be placed in the requested
> state.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_ENABLE_DEVICE)(
> + IN EFI_ISA_ACPI_PROTOCOL *This,
> + IN EFI_ISA_ACPI_DEVICE_ID *Device,
> + IN BOOLEAN Enable
> + );
> +
> +/**
> + Initializes an ISA controller, so that it can be used. This service must be called
> + before SetResource(), EnableDevice(), or SetPower() will behave as expected.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> + @param[in] Device The pointer to an ISA controller named by ACPI HID/UID.
> +
> + @retval EFI_SUCCESS Successfully initialized an ISA controller.
> + @retval Other The ISA controller could not be initialized.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_INIT_DEVICE)(
> + IN EFI_ISA_ACPI_PROTOCOL *This,
> + IN EFI_ISA_ACPI_DEVICE_ID *Device
> + );
> +
> +/**
> + Initializes all the HW states required for the ISA controllers on the ISA bus
> + to be enumerated and managed by the rest of the services in this prorotol.
> + This service must be called before any of the other services in this
> + protocol will function as expected.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> +
> + @retval EFI_SUCCESS Successfully initialized all required hardware states.
> + @retval Other The ISA interface could not be initialized.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_INTERFACE_INIT)(
> + IN EFI_ISA_ACPI_PROTOCOL *This
> + );
> +
> +///
> +/// The EFI_ISA_ACPI_PROTOCOL provides the services to enumerate and
> manage
> +/// ISA controllers on an ISA bus. These services include the ability to initialize,
> +/// enable, disable, and manage the power state of ISA controllers. It also
> +/// includes services to query current resources, query possible resources,
> +/// and assign resources to an ISA controller.
> +///
> +struct _EFI_ISA_ACPI_PROTOCOL {
> + EFI_ISA_ACPI_DEVICE_ENUMERATE DeviceEnumerate;
> + EFI_ISA_ACPI_SET_DEVICE_POWER SetPower;
> + EFI_ISA_ACPI_GET_CUR_RESOURCE GetCurResource;
> + EFI_ISA_ACPI_GET_POS_RESOURCE GetPosResource;
> + EFI_ISA_ACPI_SET_RESOURCE SetResource;
> + EFI_ISA_ACPI_ENABLE_DEVICE EnableDevice;
> + EFI_ISA_ACPI_INIT_DEVICE InitDevice;
> + EFI_ISA_ACPI_INTERFACE_INIT InterfaceInit;
> +};
> +
> +extern EFI_GUID gEfiIsaAcpiProtocolGuid;
> +
> +#endif
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h
> new file mode 100644
> index 0000000000..30000305fb
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h
> @@ -0,0 +1,356 @@
> +/** @file
> + ISA I/O Protocol is used by ISA device drivers to perform I/O, MMIO and DMA
> + operations on the ISA controllers they manage.
> +
> +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _EFI_ISA_IO_H_
> +#define _EFI_ISA_IO_H_
> +
> +#include <Protocol/IsaAcpi.h>
> +
> +///
> +/// Global ID for the EFI_ISA_IO_PROTOCOL
> +///
> +#define EFI_ISA_IO_PROTOCOL_GUID \
> + { \
> + 0x7ee2bd44, 0x3da0, 0x11d4, { 0x9a, 0x38, 0x0, 0x90, 0x27, 0x3f, 0xc1,
> 0x4d } \
> + }
> +
> +///
> +/// Forward declaration for the EFI_ISA_IO_PROTOCOL.
> +///
> +typedef struct _EFI_ISA_IO_PROTOCOL EFI_ISA_IO_PROTOCOL;
> +
> +///
> +/// Width of EFI_ISA_IO_PROTOCOL I/O Port and MMIO operations.
> +///
> +typedef enum {
> + EfiIsaIoWidthUint8 = 0, ///< 8-bit operation.
> + EfiIsaIoWidthUint16, ///< 16-bit operation.
> + EfiIsaIoWidthUint32, ///< 32-bit operation
> + EfiIsaIoWidthReserved,
> + EfiIsaIoWidthFifoUint8, ///< 8-bit FIFO operation.
> + EfiIsaIoWidthFifoUint16, ///< 16-bit FIFO operation.
> + EfiIsaIoWidthFifoUint32, ///< 32-bit FIFO operation.
> + EfiIsaIoWidthFifoReserved,
> + EfiIsaIoWidthFillUint8, ///< 8-bit Fill operation.
> + EfiIsaIoWidthFillUint16, ///< 16-bit Fill operation.
> + EfiIsaIoWidthFillUint32, ///< 32-bit Fill operation.
> + EfiIsaIoWidthFillReserved,
> + EfiIsaIoWidthMaximum
> +} EFI_ISA_IO_PROTOCOL_WIDTH;
> +
> +///
> +/// Attributes for the EFI_ISA_IO_PROTOCOL common DMA buffer allocations.
> +///
> +#define EFI_ISA_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE 0x080 ///<
> Map a memory range so write are combined.
> +#define EFI_ISA_IO_ATTRIBUTE_MEMORY_CACHED 0x800 ///< Map a
> memory range so all read and write accesses are cached.
> +#define EFI_ISA_IO_ATTRIBUTE_MEMORY_DISABLE 0x1000 ///< Disable
> a memory range.
> +
> +///
> +/// Channel attribute for EFI_ISA_IO_PROTOCOL slave DMA requests
> +///
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_COMPATIBLE 0x001
> ///< Set the speed of the DMA transfer in compatible mode.
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_A 0x002 ///< Not
> supported.
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_B 0x004 ///< Not
> supported.
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_C 0x008 ///< Not
> supported.
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_8 0x010 ///<
> Request 8-bit DMA transfers. Only available on channels 0..3.
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_16 0x020 ///<
> Request 16-bit DMA transfers. Only available on channels 4..7.
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SINGLE_MODE 0x040 ///<
> Request a single DMA transfer.
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_DEMAND_MODE 0x080
> ///< Request multiple DMA transfers until TC (Terminal Count) or EOP (End of
> Process).
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_AUTO_INITIALIZE 0x100 ///<
> Automatically reload base and count at the end of the DMA transfer.
> +
> +///
> +/// The DMA opreration type for EFI_ISA_IO_PROTOCOL DMA requests.
> +///
> +typedef enum {
> + ///
> + /// A read operation from system memory by a bus master.
> + ///
> + EfiIsaIoOperationBusMasterRead,
> + ///
> + /// A write operation to system memory by a bus master.
> + ///
> + EfiIsaIoOperationBusMasterWrite,
> + ///
> + /// Provides both read and write access to system memory by both the
> processor
> + /// and a bus master. The buffer is coherent from both the processor's and
> the
> + /// bus master's point of view.
> + ///
> + EfiIsaIoOperationBusMasterCommonBuffer,
> + ///
> + /// A read operation from system memory by a slave device.
> + ///
> + EfiIsaIoOperationSlaveRead,
> + ///
> + /// A write operation to system memory by a slave master.
> + ///
> + EfiIsaIoOperationSlaveWrite,
> + EfiIsaIoOperationMaximum
> +} EFI_ISA_IO_PROTOCOL_OPERATION;
> +
> +/**
> + Performs ISA I/O and MMIO Read/Write Cycles
> +
> + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> + @param[in] Width Specifies the width of the I/O or MMIO operation.
> + @param[in] Offset The offset into the ISA I/O or MMIO space to start the
> + operation.
> + @param[in] Count The number of I/O or MMIO operations to perform.
> + @param[in, out] Buffer For read operations, the destination buffer to store
> + the results. For write operations, the source buffer to
> + write data from.
> +
> + @retval EFI_SUCCESS The data was successfully read from or written to
> the device.
> + @retval EFI_UNSUPPORTED The Offset is not valid for this device.
> + @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid.
> + @retval EFI_OUT_OF_RESOURCES The request could not be completed due
> to a lack of resources.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_IO_PROTOCOL_IO_MEM)(
> + IN EFI_ISA_IO_PROTOCOL *This,
> + IN EFI_ISA_IO_PROTOCOL_WIDTH Width,
> + IN UINT32 Offset,
> + IN UINTN Count,
> + IN OUT VOID *Buffer
> + );
> +
> +///
> +/// Structure of functions for accessing ISA I/O and MMIO space.
> +///
> +typedef struct {
> + ///
> + /// Read from ISA I/O or MMIO space.
> + ///
> + EFI_ISA_IO_PROTOCOL_IO_MEM Read;
> + ///
> + /// Write to ISA I/O or MMIO space.
> + ///
> + EFI_ISA_IO_PROTOCOL_IO_MEM Write;
> +} EFI_ISA_IO_PROTOCOL_ACCESS;
> +
> +/**
> + Copies data from one region of ISA MMIO space to another region of ISA
> + MMIO space.
> +
> + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> + @param[in] Width Specifies the width of the MMIO copy operation.
> + @param[in] DestOffset The offset of the destination in ISA MMIO space.
> + @param[in] SrcOffset The offset of the source in ISA MMIO space.
> + @param[in] Count The number tranfers to perform for this copy
> operation.
> +
> + @retval EFI_SUCCESS The data was copied sucessfully.
> + @retval EFI_UNSUPPORTED The DestOffset or SrcOffset is not valid for
> this device.
> + @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid.
> + @retval EFI_OUT_OF_RESOURCES The request could not be completed due
> to a lack of resources.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_IO_PROTOCOL_COPY_MEM)(
> + IN EFI_ISA_IO_PROTOCOL *This,
> + IN EFI_ISA_IO_PROTOCOL_WIDTH Width,
> + IN UINT32 DestOffset,
> + IN UINT32 SrcOffset,
> + IN UINTN Count
> + );
> +
> +/**
> + Maps a memory region for DMA.
> +
> + This function returns the device-specific addresses required to access system
> memory.
> + This function is used to map system memory for ISA DMA operations. All ISA
> DMA
> + operations must be performed through their mapped addresses, and such
> mappings must
> + be freed with EFI_ISA_IO_PROTOCOL.Unmap() after the DMA operation is
> completed.
> +
> + If the DMA operation is a single read or write data transfer through an ISA bus
> + master, then EfiIsaIoOperationBusMasterRead or
> EfiIsaIoOperationBusMasterWrite
> + is used and the range is unmapped to complete the operation. If the DMA
> operation
> + is a single read or write data transfer through an ISA slave controller, then
> + EfiIsaIoOperationSlaveRead or EfiIsaIoOperationSlaveWrite is used and the
> range
> + is unmapped to complete the operation.
> +
> + If performing a DMA read operation, all the data must be present in system
> memory before the Map() is performed. Similarly,
> + if performing a DMA write operation, the data must not be accessed in system
> + memory until EFI_ISA_IO_PROTOCOL.Unmap() is performed. Bus master
> operations that
> + require both read and write access or require multiple host device
> interactions
> + within the same mapped region must use
> EfiIsaIoOperationBusMasterCommonBuffer.
> + However, only memory allocated via the
> EFI_ISA_IO_PROTOCOL.AllocateBuffer() interface
> + is guaranteed to be able to be mapped for this operation type. In all mapping
> + requests the NumberOfBytes returned may be less than originally requested.
> It is
> + the caller's responsibility to make additional requests to complete the entire
> + transfer.
> +
> + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> + @param[in] Operation Indicates the type of DMA (slave or bus
> master),
> + and if the DMA operation is going to read or
> + write to system memory.
> + @param[in] ChannelNumber The slave channel number to use for this
> DMA
> + operation. If Operation and ChannelAttributes
> + shows that this device performs bus mastering
> + DMA, then this field is ignored. The legal
> + range for this field is 0..7.
> + @param[in] ChannelAttributes A bitmask of the attributes used to
> configure
> + the slave DMA channel for this DMA operation.
> + See EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_* for the
> + legal bit combinations.
> + @param[in] HostAddress The system memory address to map to the
> device.
> + @param[in, out] NumberOfBytes On input the number of bytes to map.
> On
> + output the number of bytes that were mapped.
> + @param[out] DeviceAddress The resulting map address for the bus
> master
> + device to use to access the hosts HostAddress.
> + @param[out] Mapping A returned value that must be passed to into
> + EFI_ISA_IO_PROTOCOL.Unmap() to free all the the
> + resources associated with this map request.
> +
> + @retval EFI_SUCCESS The range was mapped for the returned
> NumberOfBytes.
> + @retval EFI_INVALID_PARAMETER The Operation is undefined.
> + @retval EFI_INVALID_PARAMETER The HostAddress is undefined.
> + @retval EFI_UNSUPPORTED The HostAddress can not be mapped as a
> common buffer.
> + @retval EFI_DEVICE_ERROR The system hardware could not map the
> requested address.
> + @retval EFI_OUT_OF_RESOURCES The memory pages could not be
> allocated.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_IO_PROTOCOL_MAP)(
> + IN EFI_ISA_IO_PROTOCOL *This,
> + IN EFI_ISA_IO_PROTOCOL_OPERATION Operation,
> + IN UINT8 ChannelNumber OPTIONAL,
> + IN UINT32 ChannelAttributes,
> + IN VOID *HostAddress,
> + IN OUT UINTN *NumberOfBytes,
> + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
> + OUT VOID **Mapping
> + );
> +
> +/**
> + Unmaps a memory region that was previously mapped with
> EFI_ISA_IO_PROTOCOL.Map().
> +
> + The EFI_ISA_IO_PROTOCOL.Map() operation is completed and any
> corresponding
> + resources are released. If the operation was EfiIsaIoOperationSlaveWrite
> + or EfiIsaIoOperationBusMasterWrite, the data is committed to system
> memory.
> + Any resources used for the mapping are freed.
> +
> + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> + @param[in] Mapping The mapping value returned from
> EFI_ISA_IO_PROTOCOL.Map().
> +
> + @retval EFI_SUCCESS The memory region was unmapped.
> + @retval EFI_DEVICE_ERROR The data was not committed to the target
> system memory.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_IO_PROTOCOL_UNMAP)(
> + IN EFI_ISA_IO_PROTOCOL *This,
> + IN VOID *Mapping
> + );
> +
> +/**
> + Allocates pages that are suitable for an
> EfiIsaIoOperationBusMasterCommonBuffer
> + mapping.
> +
> + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> + @param[in] Type The type allocation to perform.
> + @param[in] MemoryType The type of memory to allocate.
> + @param[in] Pages The number of pages to allocate.
> + @param[out] HostAddress A pointer to store the base address of the
> allocated range.
> + @param[in] Attributes The requested bit mask of attributes for the
> allocated range.
> +
> + @retval EFI_SUCCESS The requested memory pages were allocated.
> + @retval EFI_INVALID_PARAMETER Type is invalid.
> + @retval EFI_INVALID_PARAMETER MemoryType is invalid.
> + @retval EFI_INVALID_PARAMETER HostAddress is NULL.
> + @retval EFI_UNSUPPORTED Attributes is unsupported.
> + @retval EFI_UNSUPPORTED The memory range specified by
> HostAddress, Pages,
> + and Type is not available for common buffer use.
> + @retval EFI_OUT_OF_RESOURCES The memory pages could not be
> allocated.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_IO_PROTOCOL_ALLOCATE_BUFFER)(
> + IN EFI_ISA_IO_PROTOCOL *This,
> + IN EFI_ALLOCATE_TYPE Type,
> + IN EFI_MEMORY_TYPE MemoryType,
> + IN UINTN Pages,
> + OUT VOID **HostAddress,
> + IN UINT64 Attributes
> + );
> +
> +/**
> + Frees a common buffer that was allocated with
> EFI_ISA_IO_PROTOCOL.AllocateBuffer().
> +
> + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> + @param[in] Pages The number of pages to free from the previously
> allocated common buffer.
> + @param[in] HostAddress The base address of the previously allocated
> common buffer.
> +
> +
> + @retval EFI_SUCCESS The requested memory pages were freed.
> + @retval EFI_INVALID_PARAMETER The memory was not allocated with
> EFI_ISA_IO.AllocateBufer().
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_IO_PROTOCOL_FREE_BUFFER)(
> + IN EFI_ISA_IO_PROTOCOL *This,
> + IN UINTN Pages,
> + IN VOID *HostAddress
> + );
> +
> +/**
> + Flushes a DMA buffer, which forces all DMA posted write transactions to
> complete.
> +
> + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> +
> + @retval EFI_SUCCESS The DMA buffers were flushed.
> + @retval EFI_DEVICE_ERROR The buffers were not flushed due to a
> hardware error.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_IO_PROTOCOL_FLUSH)(
> + IN EFI_ISA_IO_PROTOCOL *This
> + );
> +
> +///
> +/// The EFI_ISA_IO_PROTOCOL provides the basic Memory, I/O, and DMA
> interfaces
> +/// used to abstract accesses to ISA controllers. There is one
> EFI_ISA_IO_PROTOCOL
> +/// instance for each ISA controller on a ISA bus. A device driver that wishes
> +/// to manage an ISA controller in a system will have to retrieve the
> +/// ISA_PCI_IO_PROTOCOL instance associated with the ISA controller.
> +///
> +struct _EFI_ISA_IO_PROTOCOL {
> + EFI_ISA_IO_PROTOCOL_ACCESS Mem;
> + EFI_ISA_IO_PROTOCOL_ACCESS Io;
> + EFI_ISA_IO_PROTOCOL_COPY_MEM CopyMem;
> + EFI_ISA_IO_PROTOCOL_MAP Map;
> + EFI_ISA_IO_PROTOCOL_UNMAP Unmap;
> + EFI_ISA_IO_PROTOCOL_ALLOCATE_BUFFER AllocateBuffer;
> + EFI_ISA_IO_PROTOCOL_FREE_BUFFER FreeBuffer;
> + EFI_ISA_IO_PROTOCOL_FLUSH Flush;
> + ///
> + /// The list of I/O , MMIO, DMA, and Interrupt resources associated with the
> + /// ISA controller abstracted by this instance of the EFI_ISA_IO_PROTOCOL.
> + ///
> + EFI_ISA_ACPI_RESOURCE_LIST *ResourceList;
> + ///
> + /// The size, in bytes, of the ROM image.
> + ///
> + UINT32 RomSize;
> + ///
> + /// A pointer to the in memory copy of the ROM image. The ISA Bus Driver is
> responsible
> + /// for allocating memory for the ROM image, and copying the contents of the
> ROM to memory
> + /// during ISA Bus initialization.
> + ///
> + VOID *RomImage;
> +};
> +
> +extern EFI_GUID gEfiIsaIoProtocolGuid;
> +
> +#endif
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h
> new file mode 100644
> index 0000000000..c38f2feba7
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h
> @@ -0,0 +1,291 @@
> +/** @file
> + This protocol abstracts the 8259 interrupt controller. This includes
> + PCI IRQ routing needed to program the PCI Interrupt Line register.
> +
> + Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> + @par Revision Reference:
> + This protocol is defined in Framework for EFI Compatibility Support Module
> spec
> + Version 0.97.
> +
> +**/
> +
> +#ifndef _EFI_LEGACY_8259_H_
> +#define _EFI_LEGACY_8259_H_
> +
> +
> +#define EFI_LEGACY_8259_PROTOCOL_GUID \
> + { \
> + 0x38321dba, 0x4fe0, 0x4e17, {0x8a, 0xec, 0x41, 0x30, 0x55, 0xea, 0xed,
> 0xc1 } \
> + }
> +
> +typedef struct _EFI_LEGACY_8259_PROTOCOL
> EFI_LEGACY_8259_PROTOCOL;
> +
> +typedef enum {
> + Efi8259Irq0,
> + Efi8259Irq1,
> + Efi8259Irq2,
> + Efi8259Irq3,
> + Efi8259Irq4,
> + Efi8259Irq5,
> + Efi8259Irq6,
> + Efi8259Irq7,
> + Efi8259Irq8,
> + Efi8259Irq9,
> + Efi8259Irq10,
> + Efi8259Irq11,
> + Efi8259Irq12,
> + Efi8259Irq13,
> + Efi8259Irq14,
> + Efi8259Irq15,
> + Efi8259IrqMax
> +} EFI_8259_IRQ;
> +
> +typedef enum {
> + Efi8259LegacyMode,
> + Efi8259ProtectedMode,
> + Efi8259MaxMode
> +} EFI_8259_MODE;
> +
> +/**
> + Get the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for
> + the legacy mode mask and the protected mode mask. The base address for
> the 8259
> + is different for legacy and protected mode, so two masks are required.
> +
> + @param This The protocol instance pointer.
> + @param MasterBase The base vector for the Master PIC in the 8259
> controller.
> + @param SlaveBase The base vector for the Slave PIC in the 8259
> controller.
> +
> + @retval EFI_SUCCESS The new bases were programmed.
> + @retval EFI_DEVICE_ERROR A device error occured programming the
> vector bases.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_SET_VECTOR_BASE)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN UINT8 MasterBase,
> + IN UINT8 SlaveBase
> + );
> +
> +/**
> + Get the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for
> + the legacy mode mask and the protected mode mask. The base address for
> the 8259
> + is different for legacy and protected mode, so two masks are required.
> +
> + @param This The protocol instance pointer.
> + @param LegacyMask Bit 0 is Irq0 - Bit 15 is Irq15.
> + @param LegacyEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
> + @param ProtectedMask Bit 0 is Irq0 - Bit 15 is Irq15.
> + @param ProtectedEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
> +
> + @retval EFI_SUCCESS 8259 status returned.
> + @retval EFI_DEVICE_ERROR Error reading 8259.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_GET_MASK)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + OUT UINT16 *LegacyMask, OPTIONAL
> + OUT UINT16 *LegacyEdgeLevel, OPTIONAL
> + OUT UINT16 *ProtectedMask, OPTIONAL
> + OUT UINT16 *ProtectedEdgeLevel OPTIONAL
> + );
> +
> +/**
> + Set the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for
> + the legacy mode mask and the protected mode mask. The base address for
> the 8259
> + is different for legacy and protected mode, so two masks are required.
> + Also set the edge/level masks.
> +
> + @param This The protocol instance pointer.
> + @param LegacyMask Bit 0 is Irq0 - Bit 15 is Irq15.
> + @param LegacyEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
> + @param ProtectedMask Bit 0 is Irq0 - Bit 15 is Irq15.
> + @param ProtectedEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
> +
> + @retval EFI_SUCCESS 8259 status returned.
> + @retval EFI_DEVICE_ERROR Error writing 8259.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_SET_MASK)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN UINT16 *LegacyMask, OPTIONAL
> + IN UINT16 *LegacyEdgeLevel, OPTIONAL
> + IN UINT16 *ProtectedMask, OPTIONAL
> + IN UINT16 *ProtectedEdgeLevel OPTIONAL
> + );
> +
> +/**
> + Set the 8259 mode of operation. The base address for the 8259 is different
> for
> + legacy and protected mode. The legacy mode requires the master 8259 to
> have a
> + master base of 0x08 and the slave base of 0x70. The protected mode base
> locations
> + are not defined. Interrupts must be masked by the caller before this function
> + is called. The interrupt mask from the current mode is saved. The interrupt
> + mask for the new mode is Mask, or if Mask does not exist the previously saved
> + mask is used.
> +
> + @param This The protocol instance pointer.
> + @param Mode The mode of operation. i.e. the real mode or
> protected mode.
> + @param Mask Optional interupt mask for the new mode.
> + @param EdgeLevel Optional trigger mask for the new mode.
> +
> + @retval EFI_SUCCESS 8259 programmed.
> + @retval EFI_DEVICE_ERROR Error writing to 8259.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_SET_MODE)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_MODE Mode,
> + IN UINT16 *Mask, OPTIONAL
> + IN UINT16 *EdgeLevel OPTIONAL
> + );
> +
> +/**
> + Convert from IRQ to processor interrupt vector number.
> +
> + @param This The protocol instance pointer.
> + @param Irq 8259 IRQ0 - IRQ15.
> + @param Vector The processor vector number that matches an Irq.
> +
> + @retval EFI_SUCCESS The Vector matching Irq is returned.
> + @retval EFI_INVALID_PARAMETER The Irq not valid.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_GET_VECTOR)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq,
> + OUT UINT8 *Vector
> + );
> +
> +/**
> + Enable Irq by unmasking interrupt in 8259
> +
> + @param This The protocol instance pointer.
> + @param Irq 8259 IRQ0 - IRQ15.
> + @param LevelTriggered TRUE if level triggered. FALSE if edge triggered.
> +
> + @retval EFI_SUCCESS The Irq was enabled on 8259.
> + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_ENABLE_IRQ)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq,
> + IN BOOLEAN LevelTriggered
> + );
> +
> +/**
> + Disable Irq by masking interrupt in 8259
> +
> + @param This The protocol instance pointer.
> + @param Irq 8259 IRQ0 - IRQ15.
> +
> + @retval EFI_SUCCESS The Irq was disabled on 8259.
> + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_DISABLE_IRQ)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq
> + );
> +
> +/**
> + PciHandle represents a PCI config space of a PCI function. Vector
> + represents Interrupt Pin (from PCI config space) and it is the data
> + that is programmed into the Interrupt Line (from the PCI config space)
> + register.
> +
> + @param This The protocol instance pointer.
> + @param PciHandle The PCI function to return the vector for.
> + @param Vector The vector for the function it matches.
> +
> + @retval EFI_SUCCESS A valid Vector was returned.
> + @retval EFI_INVALID_PARAMETER PciHandle not valid.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_GET_INTERRUPT_LINE)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_HANDLE PciHandle,
> + OUT UINT8 *Vector
> + );
> +
> +/**
> + Send an EOI to 8259
> +
> + @param This The protocol instance pointer.
> + @param Irq 8259 IRQ0 - IRQ15.
> +
> + @retval EFI_SUCCESS EOI was successfully sent to 8259.
> + @retval EFI_INVALID_PARAMETER The Irq isnot valid.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_END_OF_INTERRUPT)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq
> + );
> +
> +/**
> + @par Protocol Description:
> + Abstracts the 8259 and APIC hardware control between EFI usage and
> + Compatibility16 usage.
> +
> + @param SetVectorBase
> + Sets the vector bases for master and slave PICs.
> +
> + @param GetMask
> + Gets IRQ and edge/level masks for 16-bit real mode and 32-bit protected
> mode.
> +
> + @param SetMask
> + Sets the IRQ and edge\level masks for 16-bit real mode and 32-bit protected
> mode.
> +
> + @param SetMode
> + Sets PIC mode to 16-bit real mode or 32-bit protected mode.
> +
> + @param GetVector
> + Gets the base vector assigned to an IRQ.
> +
> + @param EnableIrq
> + Enables an IRQ.
> +
> + @param DisableIrq
> + Disables an IRQ.
> +
> + @param GetInterruptLine
> + Gets an IRQ that is assigned to a PCI device.
> +
> + @param EndOfInterrupt
> + Issues the end of interrupt command.
> +
> +**/
> +struct _EFI_LEGACY_8259_PROTOCOL {
> + EFI_LEGACY_8259_SET_VECTOR_BASE SetVectorBase;
> + EFI_LEGACY_8259_GET_MASK GetMask;
> + EFI_LEGACY_8259_SET_MASK SetMask;
> + EFI_LEGACY_8259_SET_MODE SetMode;
> + EFI_LEGACY_8259_GET_VECTOR GetVector;
> + EFI_LEGACY_8259_ENABLE_IRQ EnableIrq;
> + EFI_LEGACY_8259_DISABLE_IRQ DisableIrq;
> + EFI_LEGACY_8259_GET_INTERRUPT_LINE GetInterruptLine;
> + EFI_LEGACY_8259_END_OF_INTERRUPT EndOfInterrupt;
> +};
> +
> +extern EFI_GUID gEfiLegacy8259ProtocolGuid;
> +
> +#endif
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateM
> ap.h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateM
> ap.h
> new file mode 100644
> index 0000000000..640ac4943d
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateM
> ap.h
> @@ -0,0 +1,178 @@
> +/** @file
> +SMRAM Save State Map Definitions.
> +
> +SMRAM Save State Map definitions based on contents of the
> +Intel(R) 64 and IA-32 Architectures Software Developer's Manual
> + Volume 3C, Section 34.4 SMRAM
> + Volume 3C, Section 34.5 SMI Handler Execution Environment
> + Volume 3C, Section 34.7 Managing Synchronous and Asynchronous SMIs
> +
> +and the AMD64 Architecture Programmer's Manual
> + Volume 2, Section 10.2 SMM Resources
> +
> +Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2015, Red Hat, Inc.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __X58_SMRAM_SAVE_STATE_MAP_H__
> +#define __X58_SMRAM_SAVE_STATE_MAP_H__
> +
> +#pragma pack (1)
> +
> +///
> +/// 32-bit SMRAM Save State Map
> +///
> +typedef struct {
> + UINT8 Reserved0[0x200]; // 7c00h
> + UINT8 Reserved1[0xf8]; // 7e00h
> + UINT32 SMBASE; // 7ef8h
> + UINT32 SMMRevId; // 7efch
> + UINT16 IORestart; // 7f00h
> + UINT16 AutoHALTRestart; // 7f02h
> + UINT8 Reserved2[0x9C]; // 7f08h
> + UINT32 IOMemAddr; // 7fa0h
> + UINT32 IOMisc; // 7fa4h
> + UINT32 _ES; // 7fa8h
> + UINT32 _CS; // 7fach
> + UINT32 _SS; // 7fb0h
> + UINT32 _DS; // 7fb4h
> + UINT32 _FS; // 7fb8h
> + UINT32 _GS; // 7fbch
> + UINT32 Reserved3; // 7fc0h
> + UINT32 _TR; // 7fc4h
> + UINT32 _DR7; // 7fc8h
> + UINT32 _DR6; // 7fcch
> + UINT32 _EAX; // 7fd0h
> + UINT32 _ECX; // 7fd4h
> + UINT32 _EDX; // 7fd8h
> + UINT32 _EBX; // 7fdch
> + UINT32 _ESP; // 7fe0h
> + UINT32 _EBP; // 7fe4h
> + UINT32 _ESI; // 7fe8h
> + UINT32 _EDI; // 7fech
> + UINT32 _EIP; // 7ff0h
> + UINT32 _EFLAGS; // 7ff4h
> + UINT32 _CR3; // 7ff8h
> + UINT32 _CR0; // 7ffch
> +} X58_SMRAM_SAVE_STATE_MAP32;
> +
> +///
> +/// 64-bit SMRAM Save State Map
> +///
> +typedef struct {
> + UINT8 Reserved0[0x200]; // 7c00h
> +
> + UINT16 _ES; // 7e00h
> + UINT16 _ESAccessRights; // 7e02h
> + UINT32 _ESLimit; // 7e04h
> + UINT64 _ESBase; // 7e08h
> +
> + UINT16 _CS; // 7e10h
> + UINT16 _CSAccessRights; // 7e12h
> + UINT32 _CSLimit; // 7e14h
> + UINT64 _CSBase; // 7e18h
> +
> + UINT16 _SS; // 7e20h
> + UINT16 _SSAccessRights; // 7e22h
> + UINT32 _SSLimit; // 7e24h
> + UINT64 _SSBase; // 7e28h
> +
> + UINT16 _DS; // 7e30h
> + UINT16 _DSAccessRights; // 7e32h
> + UINT32 _DSLimit; // 7e34h
> + UINT64 _DSBase; // 7e38h
> +
> + UINT16 _FS; // 7e40h
> + UINT16 _FSAccessRights; // 7e42h
> + UINT32 _FSLimit; // 7e44h
> + UINT64 _FSBase; // 7e48h
> +
> + UINT16 _GS; // 7e50h
> + UINT16 _GSAccessRights; // 7e52h
> + UINT32 _GSLimit; // 7e54h
> + UINT64 _GSBase; // 7e58h
> +
> + UINT32 _GDTRReserved1; // 7e60h
> + UINT16 _GDTRLimit; // 7e64h
> + UINT16 _GDTRReserved2; // 7e66h
> + UINT64 _GDTRBase; // 7e68h
> +
> + UINT16 _LDTR; // 7e70h
> + UINT16 _LDTRAccessRights; // 7e72h
> + UINT32 _LDTRLimit; // 7e74h
> + UINT64 _LDTRBase; // 7e78h
> +
> + UINT32 _IDTRReserved1; // 7e80h
> + UINT16 _IDTRLimit; // 7e84h
> + UINT16 _IDTRReserved2; // 7e86h
> + UINT64 _IDTRBase; // 7e88h
> +
> + UINT16 _TR; // 7e90h
> + UINT16 _TRAccessRights; // 7e92h
> + UINT32 _TRLimit; // 7e94h
> + UINT64 _TRBase; // 7e98h
> +
> + UINT64 IO_RIP; // 7ea0h
> + UINT64 IO_RCX; // 7ea8h
> + UINT64 IO_RSI; // 7eb0h
> + UINT64 IO_RDI; // 7eb8h
> + UINT32 IO_DWord; // 7ec0h
> + UINT8 Reserved1[0x04]; // 7ec4h
> + UINT8 IORestart; // 7ec8h
> + UINT8 AutoHALTRestart; // 7ec9h
> + UINT8 Reserved2[0x06]; // 7ecah
> +
> + UINT64 IA32_EFER; // 7ed0h
> + UINT64 SVM_Guest; // 7ed8h
> + UINT64 SVM_GuestVMCB; // 7ee0h
> + UINT64 SVM_GuestVIntr; // 7ee8h
> + UINT8 Reserved3[0x0c]; // 7ef0h
> +
> + UINT32 SMMRevId; // 7efch
> + UINT32 SMBASE; // 7f00h
> +
> + UINT8 Reserved4[0x1c]; // 7f04h
> + UINT64 SVM_GuestPAT; // 7f20h
> + UINT64 SVM_HostIA32_EFER; // 7f28h
> + UINT64 SVM_HostCR4; // 7f30h
> + UINT64 SVM_HostCR3; // 7f38h
> + UINT64 SVM_HostCR0; // 7f40h
> +
> + UINT64 _CR4; // 7f48h
> + UINT64 _CR3; // 7f50h
> + UINT64 _CR0; // 7f58h
> + UINT64 _DR7; // 7f60h
> + UINT64 _DR6; // 7f68h
> + UINT64 _RFLAGS; // 7f70h
> + UINT64 _RIP; // 7f78h
> + UINT64 _R15; // 7f80h
> + UINT64 _R14; // 7f88h
> + UINT64 _R13; // 7f90h
> + UINT64 _R12; // 7f98h
> + UINT64 _R11; // 7fa0h
> + UINT64 _R10; // 7fa8h
> + UINT64 _R9; // 7fb0h
> + UINT64 _R8; // 7fb8h
> + UINT64 _RDI; // 7fc0h
> + UINT64 _RSI; // 7fc8h
> + UINT64 _RBP; // 7fd0h
> + UINT64 _RSP; // 7fd8h
> + UINT64 _RBX; // 7fe0h
> + UINT64 _RDX; // 7fe8h
> + UINT64 _RCX; // 7ff0h
> + UINT64 _RAX; // 7ff8h
> +} X58_SMRAM_SAVE_STATE_MAP64;
> +
> +///
> +/// Union of 32-bit and 64-bit SMRAM Save State Maps
> +///
> +typedef union {
> + X58_SMRAM_SAVE_STATE_MAP32 x86;
> + X58_SMRAM_SAVE_STATE_MAP64 x64;
> +} X58_SMRAM_SAVE_STATE_MAP;
> +
> +#pragma pack ()
> +
> +#endif
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
> new file mode 100644
> index 0000000000..c79111d811
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
> @@ -0,0 +1,54 @@
> +/** @file
> + OVMF Platform definitions
> +
> + Copyright (C) 2015, Red Hat, Inc.
> + Copyright (c) 2014, Gabriel L. Somlo <somlo@cmu.edu>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __OVMF_PLATFORMS_H__
> +#define __OVMF_PLATFORMS_H__
> +
> +#include <Library/PciLib.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <IndustryStandard/X58Ich10.h>
> +#include <IndustryStandard/I440FxPiix4.h> // TODO: remove
> +
> +//
> +// Simics Host Bridge DID Address
> +//
> +#define SIMICS_HOSTBRIDGE_DID \
> + PCI_LIB_ADDRESS (0, 0, 0, PCI_DEVICE_ID_OFFSET)
> +
> +//
> +// Simics SideBand PCI device registers
> +//
> +#define SIMICS_SIDEBANDPCI_DEV 0
> +#define SIMICS_SIDEBANDPCI_FUNC 7
> +#define SIMICS_SIDEBANDPCI_SVID \
> + PCI_LIB_ADDRESS (0, 0, 7, PCI_SVID_OFFSET)
> +#define SIMICS_SIDEBANDPCI_SDID \
> + PCI_LIB_ADDRESS (0, 0, 7, PCI_SID_OFFSET)
> +#define SIMICS_SIDEBANDPCI_CAP \
> + PCI_LIB_ADDRESS (0, 0, 7, PCI_CAPBILITY_POINTER_OFFSET)
> +#define SIMICS_SIDEBANDPCI_CAP_Offset 0x40
> +#define SIMICS_SIDEBANDPCI_CAP_ID 0xFF
> +
> +//
> +// Values we program into the PM base address registers
> +//
> +#define PIIX4_PMBA_VALUE 0xB000
> +#define ICH10_PMBASE_VALUE 0x0400
> +
> +//
> +// Common bits in same-purpose registers
> +//
> +#define PMBA_RTE BIT0
> +
> +//
> +// Common IO ports relative to the Power Management Base Address
> +//
> +#define ACPI_TIMER_OFFSET 0x8
> +
> +#endif
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKern
> el.nasm
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKern
> el.nasm
> new file mode 100644
> index 0000000000..3f3cd33c8a
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKern
> el.nasm
> @@ -0,0 +1,41 @@
> +; @file
> +; Copyright (c) 2006 - 2013 Intel Corporation. All rights reserved. <BR>
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +
> + SECTION .text
> +
> +;------------------------------------------------------------------------------
> +; VOID
> +; EFIAPI
> +; JumpToKernel (
> +; VOID *KernelStart,
> +; VOID *KernelBootParams
> +; );
> +;------------------------------------------------------------------------------
> +global ASM_PFX(JumpToKernel)
> +ASM_PFX(JumpToKernel):
> +
> + mov esi, [esp + 8]
> + call DWORD [esp + 4]
> + ret
> +
> +;------------------------------------------------------------------------------
> +; VOID
> +; EFIAPI
> +; JumpToUefiKernel (
> +; EFI_HANDLE ImageHandle,
> +; EFI_SYSTEM_TABLE *SystemTable,
> +; VOID *KernelBootParams,
> +; VOID *KernelStart
> +; );
> +;------------------------------------------------------------------------------
> +global ASM_PFX(JumpToUefiKernel)
> +ASM_PFX(JumpToUefiKernel):
> +
> + mov eax, [esp + 12]
> + mov eax, [eax + 0x264]
> + add eax, [esp + 16]
> + jmp eax
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h
> new file mode 100644
> index 0000000000..c4cc4dd8e7
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h
> @@ -0,0 +1,52 @@
> +/** @file
> + Boot UEFI Linux.
> +
> + Copyright (c) 2008 - 2013 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _LOAD_LINUX_LIB_INCLUDED_
> +#define _LOAD_LINUX_LIB_INCLUDED_
> +
> +#include <Uefi.h>
> +#include <Library/LoadLinuxLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +
> +#include <IndustryStandard/LinuxBzimage.h>
> +
> +#include <Protocol/GraphicsOutput.h>
> +
> +VOID
> +EFIAPI
> +JumpToKernel (
> + VOID *KernelStart,
> + VOID *KernelBootParams
> + );
> +
> +VOID
> +EFIAPI
> +JumpToUefiKernel (
> + EFI_HANDLE ImageHandle,
> + EFI_SYSTEM_TABLE *SystemTable,
> + VOID *KernelBootParams,
> + VOID *KernelStart
> + );
> +
> +VOID
> +InitLinuxDescriptorTables (
> + VOID
> + );
> +
> +VOID
> +SetLinuxDescriptorTables (
> + VOID
> + );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
> new file mode 100644
> index 0000000000..89664f4e42
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
> @@ -0,0 +1,42 @@
> +## @file
> +#
> +# Copyright (c) 2008 - 2012 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = LoadLinuxLib
> + FILE_GUID = 63CC8497-C9D0-46A8-AC08-49DF92A2FF62
> + MODULE_TYPE = BASE
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = LoadLinuxLib
> +
> +#
> +# The following information is for reference only and not required by the build
> tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64
> +#
> +
> +[Sources.common]
> + Linux.c
> + LinuxGdt.c
> +
> +[Sources.IA32]
> + Ia32/JumpToKernel.nasm
> +
> +[Sources.X64]
> + X64/JumpToKernel.nasm
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + OvmfPkg/OvmfPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + DebugLib
> + MemoryAllocationLib
> + BaseMemoryLib
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKerne
> l.nasm
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKerne
> l.nasm
> new file mode 100644
> index 0000000000..79e6b8e7ba
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKerne
> l.nasm
> @@ -0,0 +1,85 @@
> +; @file
> +; Copyright (c) 2006 - 2013 Intel Corporation. All rights reserved. <BR>
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +
> + DEFAULT REL
> + SECTION .text
> +
> +;------------------------------------------------------------------------------
> +; VOID
> +; EFIAPI
> +; JumpToKernel (
> +; VOID *KernelStart, // rcx
> +; VOID *KernelBootParams // rdx
> +; );
> +;------------------------------------------------------------------------------
> +global ASM_PFX(JumpToKernel)
> +ASM_PFX(JumpToKernel):
> +
> + ; Set up for executing kernel. BP in %esi, entry point on the stack
> + ; (64-bit when the 'ret' will use it as 32-bit, but we're little-endian)
> + mov rsi, rdx
> + push rcx
> +
> + ; Jump into the compatibility mode CS
> + push 0x10
> + lea rax, [.0]
> + push rax
> + DB 0x48, 0xcb ; retfq
> +
> +.0:
> + ; Now in compatibility mode.
> +
> + DB 0xb8, 0x18, 0x0, 0x0, 0x0 ; movl $0x18, %eax
> + DB 0x8e, 0xd8 ; movl %eax, %ds
> + DB 0x8e, 0xc0 ; movl %eax, %es
> + DB 0x8e, 0xe0 ; movl %eax, %fs
> + DB 0x8e, 0xe8 ; movl %eax, %gs
> + DB 0x8e, 0xd0 ; movl %eax, %ss
> +
> + ; Disable paging
> + DB 0xf, 0x20, 0xc0 ; movl %cr0, %eax
> + DB 0xf, 0xba, 0xf8, 0x1f ; btcl $31, %eax
> + DB 0xf, 0x22, 0xc0 ; movl %eax, %cr0
> +
> + ; Disable long mode in EFER
> + DB 0xb9, 0x80, 0x0, 0x0, 0xc0 ; movl $0x0c0000080, %ecx
> + DB 0xf, 0x32 ; rdmsr
> + DB 0xf, 0xba, 0xf8, 0x8 ; btcl $8, %eax
> + DB 0xf, 0x30 ; wrmsr
> +
> + ; Disable PAE
> + DB 0xf, 0x20, 0xe0 ; movl %cr4, %eax
> + DB 0xf, 0xba, 0xf8, 0x5 ; btcl $5, %eax
> + DB 0xf, 0x22, 0xe0 ; movl %eax, %cr4
> +
> + DB 0x31, 0xed ; xor %ebp, %ebp
> + DB 0x31, 0xff ; xor %edi, %edi
> + DB 0x31, 0xdb ; xor %ebx, %ebx
> + DB 0xc3 ; ret
> +
> +;------------------------------------------------------------------------------
> +; VOID
> +; EFIAPI
> +; JumpToUefiKernel (
> +; EFI_HANDLE ImageHandle, // rcx
> +; EFI_SYSTEM_TABLE *SystemTable, // rdx
> +; VOID *KernelBootParams // r8
> +; VOID *KernelStart, // r9
> +; );
> +;------------------------------------------------------------------------------
> +global ASM_PFX(JumpToUefiKernel)
> +ASM_PFX(JumpToUefiKernel):
> +
> + mov rdi, rcx
> + mov rsi, rdx
> + mov rdx, r8
> + xor rax, rax
> + mov eax, [r8 + 0x264]
> + add r9, rax
> + add r9, 0x200
> + call r9
> + ret
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.h
> b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.h
> new file mode 100644
> index 0000000000..92aa038cdd
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.h
> @@ -0,0 +1,55 @@
> +/** @file
> + Save Non-Volatile Variables to a file system.
> +
> + Copyright (c) 2009 - 2011 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __NV_VARS_FILE_LIB_INSTANCE__
> +#define __NV_VARS_FILE_LIB_INSTANCE__
> +
> +#include <Uefi.h>
> +
> +#include <Guid/FileInfo.h>
> +
> +#include <Protocol/SimpleFileSystem.h>
> +
> +#include <Library/BaseLib.h>
> +#include <Library/FileHandleLib.h>
> +#include <Library/SerializeVariablesLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +
> +/**
> + Loads the non-volatile variables from the NvVars file on the
> + given file system.
> +
> + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid
> instance
> +
> + @return EFI_STATUS based on the success or failure of load operation
> +
> +**/
> +EFI_STATUS
> +LoadNvVarsFromFs (
> + EFI_HANDLE FsHandle
> + );
> +
> +
> +/**
> + Saves the non-volatile variables into the NvVars file on the
> + given file system.
> +
> + @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid
> instance
> +
> + @return EFI_STATUS based on the success or failure of load operation
> +
> +**/
> +EFI_STATUS
> +SaveNvVarsToFs (
> + EFI_HANDLE FsHandle
> + );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.inf
> new file mode 100644
> index 0000000000..e4c3b7ccff
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.inf
> @@ -0,0 +1,53 @@
> +## @file
> +# NvVarsFileLib
> +#
> +# This library saves and restores non-volatile variables in a
> +# file within a file system.
> +#
> +# Copyright (c) 2006 - 2018 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = NvVarsFileLib
> + FILE_GUID = 8ECD4CC0-1772-4583-8A74-83633A15FAA0
> + MODULE_TYPE = UEFI_DRIVER
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = NvVarsFileLib|DXE_DRIVER
> DXE_RUNTIME_DRIVER UEFI_DRIVER
> +
> +#
> +# The following information is for reference only and not required by the build
> tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 EBC
> +#
> +
> +[Sources]
> + FsAccess.c
> + NvVarsFileLib.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + ShellPkg/ShellPkg.dec
> + OvmfPkg/OvmfPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + BaseMemoryLib
> + DebugLib
> + FileHandleLib
> + MemoryAllocationLib
> + SerializeVariablesLib
> +
> +[Protocols]
> + gEfiSimpleFileSystemProtocolGuid ## CONSUMES
> +
> +[Guids]
> + gEfiFileInfoGuid
> +
> +[Depex]
> + gEfiVariableWriteArchProtocolGuid
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> riablesLib.h
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> riablesLib.h
> new file mode 100644
> index 0000000000..7e78cd4b21
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> riablesLib.h
> @@ -0,0 +1,33 @@
> +/** @file
> + Serialize Variables Library implementation
> +
> + Copyright (c) 2009 - 2011 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __SERIALIZE_VARIABLES_LIB_INSTANCE__
> +#define __SERIALIZE_VARIABLES_LIB_INSTANCE__
> +
> +#include <Uefi.h>
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/SerializeVariablesLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +
> +#define SV_FROM_HANDLE(a) CR (a, SV_INSTANCE, Signature,
> SV_SIGNATURE)
> +#define SV_SIGNATURE SIGNATURE_32 ('S', 'V', 'A', 'R')
> +
> +typedef struct {
> + UINT32 Signature;
> + VOID *BufferPtr;
> + UINTN BufferSize;
> + UINTN DataSize;
> +} SV_INSTANCE;
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> riablesLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> riablesLib.inf
> new file mode 100644
> index 0000000000..25901192b2
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> riablesLib.inf
> @@ -0,0 +1,36 @@
> +## @file
> +# Serialize Variables Library implementation
> +#
> +# This library serializes and deserializes UEFI variables
> +#
> +# Copyright (c) 2006 - 2018 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = DxeSerializeVariablesLib
> + FILE_GUID = 266A1434-6B22-441F-A8D2-D54AA8FDF95C
> + MODULE_TYPE = UEFI_DRIVER
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = SerializeVariablesLib|DXE_DRIVER
> DXE_RUNTIME_DRIVER UEFI_DRIVER
> +
> +[Sources]
> + SerializeVariablesLib.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + ShellPkg/ShellPkg.dec
> + OvmfPkg/OvmfPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + BaseMemoryLib
> + DebugLib
> + MemoryAllocationLib
> + UefiBootServicesTableLib
> + UefiRuntimeServicesTableLib
> +
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h
> new file mode 100644
> index 0000000000..63b5e52575
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h
> @@ -0,0 +1,37 @@
> +/** @file
> + This driver effectuates OVMF's platform configuration settings and exposes
> + them via HII.
> +
> + Copyright (C) 2014, Red Hat, Inc.
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PLATFORM_H_
> +#define _PLATFORM_H_
> +
> +//
> +// Macro and type definitions that connect the form with the HII driver code.
> +//
> +#define FORMSTATEID_MAIN_FORM 1
> +#define FORMID_MAIN_FORM 1
> +
> +#define QUESTION_RES_CUR 1
> +#define MAXSIZE_RES_CUR 16
> +
> +#define LABEL_RES_NEXT 1
> +#define QUESTION_RES_NEXT 2
> +
> +#define QUESTION_SAVE_EXIT 3
> +#define QUESTION_DISCARD_EXIT 4
> +
> +//
> +// This structure describes the form state. Its fields relate strictly to the
> +// visual widgets on the form.
> +//
> +typedef struct {
> + UINT16 CurrentPreferredResolution[MAXSIZE_RES_CUR];
> + UINT32 NextPreferredResolution;
> +} MAIN_FORM_STATE;
> +
> +#endif // _PLATFORM_H_
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.inf
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.inf
> new file mode 100644
> index 0000000000..804ab59610
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.inf
> @@ -0,0 +1,65 @@
> +## @file
> +# This driver effectuates Simics X58 platform configuration settings and
> exposes
> +# them via HII.
> +#
> +# Copyright (C) 2014, Red Hat, Inc.
> +# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = PlatformDxe
> + FILE_GUID = 74B64DC1-B0B6-4853-A6BD-C6426059AB1E
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + ENTRY_POINT = PlatformInit
> + UNLOAD_IMAGE = PlatformUnload
> +
> +[Sources]
> + Platform.c
> + Platform.uni
> + PlatformConfig.c
> + PlatformForms.vfr
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> + MinPlatformPkg/MinPlatformPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + BaseMemoryLib
> + DebugLib
> + DevicePathLib
> + HiiLib
> + MemoryAllocationLib
> + PrintLib
> + UefiBootServicesTableLib
> + UefiHiiServicesLib
> + UefiLib
> + UefiRuntimeServicesTableLib
> + UefiDriverEntryPoint
> + DxeServicesTableLib
> +
> +[Pcd]
> + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution
> + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution
> +
> +[Protocols]
> + gEfiDevicePathProtocolGuid ## PRODUCES
> + gEfiGraphicsOutputProtocolGuid ## CONSUMES
> + gEfiHiiConfigAccessProtocolGuid ## PRODUCES
> +
> +[Guids]
> + gEfiIfrTianoGuid
> + gSimicsX58PlatformConfigGuid
> +
> +[Depex]
> + gEfiHiiConfigRoutingProtocolGuid AND
> + gEfiHiiDatabaseProtocolGuid AND
> + gEfiVariableArchProtocolGuid AND
> + gEfiVariableWriteArchProtocolGuid
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni
> new file mode 100644
> index 0000000000..6d68cbeb4f
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni
> @@ -0,0 +1,31 @@
> +// *++
> +//
> +// Copyright (C) 2014, Red Hat, Inc.
> +// Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// Module Name:
> +//
> +// Platform.uni
> +//
> +// Abstract:
> +//
> +// String definitions for PlatformForms.vfr
> +//
> +// --*/
> +
> +/=#
> +
> +#langdef en-US "English"
> +
> +#string STR_FORMSET_TITLE #language en-US "QSP Platform
> Configuration"
> +#string STR_FORMSET_HELP #language en-US "Change various QSP
> platform settings."
> +#string STR_MAIN_FORM_TITLE #language en-US "QSP Settings"
> +#string STR_RES_CUR #language en-US "Preferred Resolution at Next
> Boot"
> +#string STR_RES_CUR_HELP #language en-US "The preferred resolution of
> the Graphics Console at next boot. It might be unset, or even invalid (hence
> ignored) wrt. the video RAM size."
> +#string STR_RES_NEXT #language en-US "Change Preferred Resolution
> for Next Boot"
> +#string STR_RES_NEXT_HELP #language en-US "You can specify a new
> preference for the Graphics Console here. The list is filtered against the video
> RAM size."
> +#string STR_SAVE_EXIT #language en-US "Commit Changes and Exit"
> +#string STR_DISCARD_EXIT #language en-US "Discard Changes and Exit"
> +
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.h
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.h
> new file mode 100644
> index 0000000000..d3f041ddea
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.h
> @@ -0,0 +1,51 @@
> +/** @file
> + Utility functions for serializing (persistently storing) and deserializing
> + OVMF's platform configuration.
> +
> + Copyright (C) 2014, Red Hat, Inc.
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PLATFORM_CONFIG_H_
> +#define _PLATFORM_CONFIG_H_
> +
> +#include <Base.h>
> +
> +//
> +// This structure participates in driver configuration. It does not
> +// (necessarily) reflect the wire format in the persistent store.
> +//
> +#pragma pack(1)
> +typedef struct {
> + //
> + // preferred graphics console resolution when booting
> + //
> + UINT32 HorizontalResolution;
> + UINT32 VerticalResolution;
> +} PLATFORM_CONFIG;
> +#pragma pack()
> +
> +//
> +// Please see the API documentation near the function definitions.
> +//
> +EFI_STATUS
> +EFIAPI
> +PlatformConfigSave (
> + IN PLATFORM_CONFIG *PlatformConfig
> + );
> +
> +EFI_STATUS
> +EFIAPI
> +PlatformConfigLoad (
> + OUT PLATFORM_CONFIG *PlatformConfig,
> + OUT UINT64 *OptionalElements
> + );
> +
> +//
> +// Feature flags for OptionalElements.
> +//
> +#define PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION BIT0
> +#define PLATFORM_CONFIG_F_DOWNGRADE BIT63
> +
> +#endif // _PLATFORM_CONFIG_H_
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformForms.vfr
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformForms.vfr
> new file mode 100644
> index 0000000000..1c02565ebb
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformForms.vfr
> @@ -0,0 +1,67 @@
> +// *++
> +//
> +// Copyright (C) 2014, Red Hat, Inc.
> +// Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// Module Name:
> +//
> +// PlatformForms.vfr
> +//
> +// Abstract:
> +//
> +// Form definitions for exposing some of OVMF's platform knobs via HII.
> +//
> +// --*/
> +
> +#include <Guid/SimicsX58PlatformConfig.h>
> +#include "Platform.h"
> +
> +formset
> + guid = SIMICSX58_PLATFORM_CONFIG_GUID,
> + title = STRING_TOKEN(STR_FORMSET_TITLE),
> + help = STRING_TOKEN(STR_FORMSET_HELP),
> +
> + varstore MAIN_FORM_STATE,
> + varid = FORMSTATEID_MAIN_FORM,
> + name = MainFormState,
> + guid = SIMICSX58_PLATFORM_CONFIG_GUID;
> +
> + form
> + formid = FORMID_MAIN_FORM,
> + title = STRING_TOKEN(STR_MAIN_FORM_TITLE);
> +
> + //
> + // Display the current preference in a read-only string field.
> + //
> + string
> + varid = MainFormState.CurrentPreferredResolution,
> + questionid = QUESTION_RES_CUR,
> + prompt = STRING_TOKEN(STR_RES_CUR),
> + help = STRING_TOKEN(STR_RES_CUR_HELP),
> + flags = READ_ONLY,
> + minsize = 0,
> + maxsize = MAXSIZE_RES_CUR,
> + endstring;
> +
> + //
> + // We'll dynamically generate a one-of-many selection at this label.
> + //
> + label LABEL_RES_NEXT;
> +
> + text
> + help = STRING_TOKEN(STR_SAVE_EXIT),
> + text = STRING_TOKEN(STR_SAVE_EXIT),
> + flags = INTERACTIVE,
> + key = QUESTION_SAVE_EXIT;
> +
> + text
> + help = STRING_TOKEN(STR_DISCARD_EXIT),
> + text = STRING_TOKEN(STR_DISCARD_EXIT),
> + flags = INTERACTIVE,
> + key = QUESTION_DISCARD_EXIT;
> +
> + endform;
> +
> +endformset;
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h
> new file mode 100644
> index 0000000000..616d2d74cb
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h
> @@ -0,0 +1,50 @@
> +/** @file
> + PC/AT CMOS access routines
> +
> + Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __CMOS_H__
> +#define __CMOS_H__
> +
> +/**
> + Reads 8-bits of CMOS data.
> +
> + Reads the 8-bits of CMOS data at the location specified by Index.
> + The 8-bit read value is returned.
> +
> + @param Index The CMOS location to read.
> +
> + @return The value read.
> +
> +**/
> +UINT8
> +EFIAPI
> +CmosRead8 (
> + IN UINTN Index
> + );
> +
> +/**
> + Writes 8-bits of CMOS data.
> +
> + Writes 8-bits of CMOS data to the location specified by Index
> + with the value specified by Value and returns Value.
> +
> + @param Index The CMOS location to write.
> + @param Value The value to write to CMOS.
> +
> + @return The value written to CMOS.
> +
> +**/
> +UINT8
> +EFIAPI
> +CmosWrite8 (
> + IN UINTN Index,
> + IN UINT8 Value
> + );
> +
> +
> +#endif
> +
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h
> new file mode 100644
> index 0000000000..5b1a9b5f57
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h
> @@ -0,0 +1,93 @@
> +/** @file
> + Platform PEI module include file.
> +
> + Copyright (c) 2006 - 2016 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PLATFORM_PEI_H_INCLUDED_
> +#define _PLATFORM_PEI_H_INCLUDED_
> +
> +VOID
> +AddIoMemoryBaseSizeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + UINT64 MemorySize
> + );
> +
> +VOID
> +AddIoMemoryRangeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + EFI_PHYSICAL_ADDRESS MemoryLimit
> + );
> +
> +VOID
> +AddMemoryBaseSizeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + UINT64 MemorySize
> + );
> +
> +VOID
> +AddMemoryRangeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + EFI_PHYSICAL_ADDRESS MemoryLimit
> + );
> +
> +VOID
> +AddUntestedMemoryBaseSizeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + UINT64 MemorySize
> + );
> +
> +VOID
> +AddReservedMemoryBaseSizeHob (
> + EFI_PHYSICAL_ADDRESS MemoryBase,
> + UINT64 MemorySize,
> + BOOLEAN Cacheable
> + );
> +
> +VOID
> +AddressWidthInitialization (
> + VOID
> + );
> +
> +VOID
> +X58TsegMbytesInitialization (
> + VOID
> + );
> +
> +EFI_STATUS
> +PublishPeiMemory (
> + VOID
> + );
> +
> +UINT32
> +GetSystemMemorySizeBelow4gb (
> + VOID
> + );
> +
> +VOID
> +InitializeRamRegions (
> + VOID
> + );
> +
> +EFI_STATUS
> +PeiFvInitialization (
> + VOID
> + );
> +
> +VOID
> +InstallFeatureControlCallback (
> + VOID
> + );
> +
> +extern EFI_BOOT_MODE mBootMode;
> +
> +extern BOOLEAN mS3Supported;
> +
> +extern UINT8 mPhysMemAddressWidth;
> +
> +extern UINT32 mMaxCpuCount;
> +
> +extern UINT16 mHostBridgeDevId;
> +#endif // _PLATFORM_PEI_H_INCLUDED_
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf
> new file mode 100644
> index 0000000000..eb8048c655
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf
> @@ -0,0 +1,109 @@
> +## @file
> +# Platform PEI driver
> +#
> +# This module provides platform specific function to detect boot mode.
> +# Copyright (c) 2006 - 2018 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = PlatformPei
> + FILE_GUID = 05116218-f9f1-41f8-8d17-c2207006ffff
> + MODULE_TYPE = PEIM
> + VERSION_STRING = 1.0
> + ENTRY_POINT = InitializePlatform
> +
> +#
> +# The following information is for reference only and not required by the build
> tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 EBC
> +#
> +
> +[Sources]
> + Cmos.c
> + FeatureControl.c
> + Fv.c
> + MemDetect.c
> + Platform.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + UefiCpuPkg/UefiCpuPkg.dec
> + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> + MinPlatformPkg/MinPlatformPkg.dec
> + OvmfPkg/OvmfPkg.dec
> +
> +[Guids]
> + gEfiMemoryTypeInformationGuid
> + gEfiSmmPeiSmramMemoryReserveGuid ## CONSUMES
> +
> +[LibraryClasses]
> + BaseLib
> + DebugLib
> + HobLib
> + IoLib
> + PciLib
> + PeiResourcePublicationLib
> + PeiServicesLib
> + PeiServicesTablePointerLib
> + PeimEntryPoint
> + MtrrLib
> + PcdLib
> +
> +[Pcd]
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
> + gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
> + gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
> + gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase
> + gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
> + gSimicsX58PkgTokenSpaceGuid.PcdX58TsegMbytes
> + gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
> + gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize
> + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
> + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
> + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved
> + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode
> + gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable
> + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable
> + gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress
> + gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber
> + gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds
> + gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES
> + gMinPlatformPkgTokenSpaceGuid.PcdIoApicId
> +
> +[FixedPcd]
> + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +
> +
> +[Ppis]
> + gEfiPeiMasterBootModePpiGuid
> + gEfiPeiMpServicesPpiGuid
> +
> +[Depex]
> + TRUE
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.inf
> new file mode 100644
> index 0000000000..b9bcb5d2bd
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.inf
> @@ -0,0 +1,38 @@
> +## @file
> +#
> +# Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = SiliconPolicyInitLib
> + FILE_GUID = B494DF39-A5F8-48A1-B2D0-EF523AD91C55
> + MODULE_TYPE = PEIM
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = SiliconPolicyInitLib
> +
> +[Sources]
> + SiliconPolicyInitLib.c
> +
> +############################################################
> ####################
> +#
> +# Package Dependency Section - list of Package files that are required for
> +# this module.
> +#
> +############################################################
> ####################
> +[Packages]
> + MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> + BaseMemoryLib
> + BaseLib
> + DebugLib
> + DebugPrintErrorLevelLib
> + HobLib
> + IoLib
> + MemoryAllocationLib
> + PeiServicesLib
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sil
> iconPolicyUpdateLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sil
> iconPolicyUpdateLib.inf
> new file mode 100644
> index 0000000000..da165ac947
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sil
> iconPolicyUpdateLib.inf
> @@ -0,0 +1,35 @@
> +## @file
> +#
> +# Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = SiliconPolicyUpdateLib
> + FILE_GUID = 6EA9585C-3C15-47da-9FFC-25E9E4EA4D0C
> + MODULE_TYPE = PEIM
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = SiliconPolicyUpdateLib
> +
> +[Sources]
> + SiliconPolicyUpdateLib.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> +
> +[LibraryClasses]
> + HobLib
> + IoLib
> + PcdLib
> +
> +[Pcd]
> +
> +[FixedPcd]
> +
> +[Ppis]
> +
> +[Guids]
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> b/Platform/Intel/SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> new file mode 100644
> index 0000000000..17c87aca8c
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> @@ -0,0 +1,168 @@
> +## @file
> +# EFI/Framework Simics X58 platform
> +#
> +# Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + DEC_SPECIFICATION = 0x00010005
> + PACKAGE_NAME = SimicsX58Pkg
> + PACKAGE_GUID = E6A03E0D-5944-4dc6-9292-090D609EDD3A
> + PACKAGE_VERSION = 0.1
> +
> +[Includes]
> + Include
> +
> +[Guids]
> + gSimicsX58PkgTokenSpaceGuid = {0x5b276d20, 0x37d0, 0x4af0, {0x8d,
> 0x04, 0x47, 0x91, 0x2b, 0x7c, 0x1d, 0x44}}
> + gSimicsX58PlatformConfigGuid = {0xeed35f57, 0x4ff2, 0x4244, {0xb8, 0x3a,
> 0xea, 0x71, 0x5f, 0xd3, 0x59, 0xa5}}
> +
> +[Protocols]
> + gEfiLegacy8259ProtocolGuid = {0x38321dba, 0x4fe0, 0x4e17, {0x8a,
> 0xec, 0x41, 0x30, 0x55, 0xea, 0xed, 0xc1}}
> + gEfiIsaAcpiProtocolGuid = {0x64a892dc, 0x5561, 0x4536, {0x92, 0xc7,
> 0x79, 0x9b, 0xfc, 0x18, 0x33, 0x55}}
> + gEfiIsaIoProtocolGuid = {0x7ee2bd44, 0x3da0, 0x11d4, {0x9a, 0x38,
> 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d}}
> +
> +[PcdsFixedAtBuild]
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase|0x0|UINT32|0
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize|0x0|UINT32|1
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase|0x0|UINT32|0x15
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize|0x0|UINT32|0x16
> +
> + #TODO: Remove these two when we integrate new PlatformPei
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsMemFvBase|0x00800000|UINT32|2
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsMemFvSize|0x00500000|UINT32|3
> +
> + ## The following setting controls how many megabytes we configure as TSEG
> on
> + # X58, for SMRAM purposes. Permitted values are: 1, 2, 8. Other values
> cause
> + # undefined behavior.
> + #
> + # This PCD is only consulted if PcdSmmSmramRequire is TRUE (see below).
> + gSimicsX58PkgTokenSpaceGuid.PcdX58TsegMbytes|8|UINT8|0x20
> +
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase|0x0|UI
> NT32|0x8
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize|0x0|UI
> NT32|0x9
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareFdSize|0x0|UINT32|0xa
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareBlockSize|0|UINT32|0xb
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase|0x0|UI
> NT32|0xc
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwSpareBase|0x0|UI
> NT32|0xd
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase|0x0
> |UINT32|0xe
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsFdBaseAddress|0x0|UINT32|0xf
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase|0x0|UINT32|0x1
> 1
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesSize|0x0|UINT32|0x1
> 2
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase|0x0|UINT32|0
> x13
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize|0x0|UINT32|0x
> 14
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageBase|0x0|UINT32|0x
> 18
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageSize|0x0|UINT32|0x
> 19
> +
> gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize|0x0|UINT3
> 2|0x1a
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd|0x0|UINT
> 32|0x1f
> +
> +[PcdsDynamic, PcdsDynamicEx]
> +
> + # TODO: investigate whether next two Pcds are needed
> + gSimicsX58PkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|0x28
> +
> gSimicsX58PkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEA
> N|0x10
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId|0|UINT16|0
> x1b
> +
> + ## The IO port aperture shared by all PCI root bridges.
> + #
> + gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase|0x0|UINT64|0x22
> + gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize|0x0|UINT64|0x23
> +
> + ## The 32-bit MMIO aperture shared by all PCI root bridges.
> + #
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base|0x0|UINT64|0x24
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size|0x0|UINT64|0x25
> +
> + ## The 64-bit MMIO aperture shared by all PCI root bridges.
> + #
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base|0x0|UINT64|0x26
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size|0x0|UINT64|0x27
> +
> +[PcdsFeatureFlag]
> + ## This feature flag enables SMM/SMRAM support. Note that it also requires
> + # such support from the underlying QEMU instance; if that support is not
> + # present, the firmware will reject continuing after a certain point.
> + #
> + # The flag also acts as a general "security switch"; when TRUE, many
> + # components will change behavior, with the goal of preventing a malicious
> + # runtime OS from tampering with firmware structures (special memory
> ranges
> + # used by OVMF, the varstore pflash chip, LockBox etc).
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire|FALSE|BOOLEAN|0x1
> e
> +
> +
> +[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|UIN
> T16|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|0x0
> 0000003
> +
> + ## 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|0x0
> 0000004
> +
> + ## 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|BOOLE
> AN|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|BOOLEAN
> |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|0
> x00000007
> +
> + ## 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|0
> x00000008
> +
> +[PcdsFixedAtBuild, PcdsPatchableInModule]
> + ## FFS filename to find the shell application.
> + # @Prompt FFS Name of Shell Application
> + gSimicsX58PkgTokenSpaceGuid.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 |
> (gSimicsX58PkgTokenSpaceGuid.PcdIsaBusSupportedFeatures & 0xF8) == 0
> +
> gSimicsX58PkgTokenSpaceGuid.PcdIsaBusSupportedFeatures|0x05|UINT8|0x0
> 0010040
> \ No newline at end of file
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> .h
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> .h
> new file mode 100644
> index 0000000000..38a71a3527
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> .h
> @@ -0,0 +1,38 @@
> +/** @file
> + This driver installs SMBIOS information for OVMF
> +
> + Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>
> + Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SMBIOS_PLATFORM_DXE_H_
> +#define _SMBIOS_PLATFORM_DXE_H_
> +
> +#include <PiDxe.h>
> +
> +#include <Protocol/Smbios.h>
> +#include <IndustryStandard/SmBios.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/IoLib.h>
> +
> +/**
> + Validates the SMBIOS entry point structure
> +
> + @param EntryPointStructure SMBIOS entry point structure
> +
> + @retval TRUE The entry point structure is valid
> + @retval FALSE The entry point structure is not valid
> +
> +**/
> +BOOLEAN
> +IsEntryPointStructureValid (
> + IN SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure
> + );
> +
> +#endif
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> .inf
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> .inf
> new file mode 100644
> index 0000000000..6adaf0beb7
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> .inf
> @@ -0,0 +1,51 @@
> +## @file
> +# This driver installs SMBIOS information for OVMF
> +#
> +# Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>
> +# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = SmbiosPlatformDxe
> + FILE_GUID = 4b18323d-2d42-4afa-b9e5-91516a6fe505
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> +
> + ENTRY_POINT = SmbiosTablePublishEntry
> +
> +#
> +# The following information is for reference only and not required by the build
> tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64
> +#
> +
> +[Sources]
> + SmbiosPlatformDxe.h
> + SmbiosPlatformDxe.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> + AdvancedFeaturePkg/AdvancedFeaturePkg.dec
> +
> +[LibraryClasses]
> + UefiBootServicesTableLib
> + BaseMemoryLib
> + BaseLib
> + UefiDriverEntryPoint
> + DebugLib
> + HobLib
> + MemoryAllocationLib
> + IoLib
> +
> +[Protocols]
> + gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED
> +
> +[Depex]
> + gEfiSmbiosProtocolGuid
> +
> --
> 2.16.2.windows.1
next prev parent reply other threads:[~2019-08-23 16:58 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-09 22:46 [edk2-platform patch 0/7] Add Initial QSP MinPlatform Pkg for SIMICS David Wei
2019-08-09 22:46 ` [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58 David Wei
2019-08-15 8:34 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
2019-08-22 22:31 ` David Wei
2019-08-26 22:48 ` Kubacki, Michael A
2019-08-09 22:46 ` [edk2-platform patch 2/7] SimicsICH10Pkg: Add PCH Pkg for SimicsICH10 David Wei
2019-08-13 2:01 ` Nate DeSimone
2019-08-15 8:39 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
2019-08-23 16:40 ` David Wei
2019-08-26 22:49 ` Kubacki, Michael A
2019-08-09 22:46 ` [edk2-platform patch 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules David Wei
2019-08-15 18:35 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
2019-08-23 16:57 ` David Wei [this message]
2019-08-26 23:13 ` Kubacki, Michael A
2019-08-09 22:46 ` [edk2-platform patch 4/7] SimicsOpenBoardPkg: Add DXE driver for Legacy Sio David Wei
2019-08-15 19:01 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
2019-08-09 22:46 ` [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform David Wei
2019-08-15 19:38 ` Nate DeSimone
2019-08-15 22:28 ` Nate DeSimone
2019-08-15 22:52 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
2019-08-23 17:09 ` David Wei
2019-08-26 22:51 ` Kubacki, Michael A
2019-08-09 22:46 ` [edk2-platform patch 6/7] SimicsOpenBoardPkg: Add board module for QSP Build tip David Wei
2019-08-20 1:04 ` Kubacki, Michael A
2019-08-23 17:04 ` David Wei
2019-08-26 22:59 ` Kubacki, Michael A
2019-08-09 22:46 ` [edk2-platform patch 7/7] Platform/Intel: Add build option for SIMICS QSP Platform David Wei
2019-08-15 19:28 ` Nate DeSimone
2019-08-19 23:21 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
2019-08-23 17:06 ` David Wei
2019-08-26 23:00 ` Kubacki, Michael A
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=BB06729C0DFAF049B2572591F2D0B0F5095D9908@fmsmsx121.amr.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