public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Nate DeSimone" <nathaniel.l.desimone@intel.com>
To: "Wei, David Y" <david.y.wei@intel.com>,
	"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Wu, Hao A" <hao.a.wu@intel.com>,
	"Gao, Liming" <liming.gao@intel.com>,
	"Sinha, Ankit" <ankit.sinha@intel.com>,
	"Agyeman, Prince" <prince.agyeman@intel.com>,
	"Kubacki, Michael A" <michael.a.kubacki@intel.com>,
	"Kinney, Michael D" <michael.d.kinney@intel.com>
Subject: Re: [edk2-platform patch 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules
Date: Thu, 15 Aug 2019 18:35:18 +0000	[thread overview]
Message-ID: <02A34F284D1DA44BB705E61F7180EF0AAEE0C175@ORSMSX114.amr.corp.intel.com> (raw)
In-Reply-To: <28fad95137c6aecfbf593a14191bdb4d0819951e.1565389186.git.david.y.wei@intel.com>

Hi David,

Here are my comments:

1. All of the copyright years need to be updated to 2019.
2. Please remove " Contributed-under: TianoCore Contribution Agreement 1.0" from your commit message as it is no longer needed.
3. Please remove interspersed trailing white-space from the following files:

  * Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl
  * Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h
  * Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateMap.h
  * Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.c
  * Platform/Intel/SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec

4. Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c - Line 2 - " This driver effectuates OVMF's platform..." - This is not OVMF, this is Simics, please update.
5. Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf - Line 2 - " This driver installs SMBIOS information for OVMF" - This is not OVMF, this is Simics, please update.

Other than that, looks good! Please send an updated patch.

Thanks,
Nate

-----Original Message-----
From: Wei, David Y 
Sent: Friday, August 9, 2019 3:47 PM
To: devel@edk2.groups.io
Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince <prince.agyeman@intel.com>; Kubacki, Michael A <michael.a.kubacki@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: [edk2-platform patch 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/SerializeVariablesLib.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/SiliconPolicyInitLib.c
 create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.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/SerializeVariablesLib.h
 create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.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/SiliconPolicyInitLib.inf
 create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.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.inf

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/SerializeVariablesLib.c b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c
new file mode 100644
index 0000000000..c32a978550
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.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/SiliconPolicyInitLib.c b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.c
new file mode 100644
index 0000000000..01a9ed40d5
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.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/SiliconPolicyUpdateLib.c b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.c
new file mode 100644
index 0000000000..6d9da67975
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.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/X58SmramSaveStateMap.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateMap.h
new file mode 100644
index 0000000000..640ac4943d
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateMap.h
@@ -0,0 +1,178 @@
+/** @file
+SMRAM Save State Map Definitions.
+
+SMRAM Save State Map definitions based on contents of the 
+Intel(R) 64 and IA-32 Architectures Software Developer's Manual
+  Volume 3C, Section 34.4 SMRAM
+  Volume 3C, Section 34.5 SMI Handler Execution Environment
+  Volume 3C, Section 34.7 Managing Synchronous and Asynchronous SMIs
+
+and the AMD64 Architecture Programmer's Manual
+  Volume 2, Section 10.2 SMM Resources
+
+Copyright (c) 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/JumpToKernel.nasm b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.nasm
new file mode 100644
index 0000000000..3f3cd33c8a
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.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/JumpToKernel.nasm b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKernel.nasm
new file mode 100644
index 0000000000..79e6b8e7ba
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKernel.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/SerializeVariablesLib.h b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.h
new file mode 100644
index 0000000000..7e78cd4b21
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.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/SerializeVariablesLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
new file mode 100644
index 0000000000..25901192b2
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.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/SiliconPolicyInitLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf
new file mode 100644
index 0000000000..b9bcb5d2bd
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.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/SiliconPolicyUpdateLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.inf
new file mode 100644
index 0000000000..da165ac947
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.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|UINT32|0x8
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize|0x0|UINT32|0x9
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareFdSize|0x0|UINT32|0xa
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareBlockSize|0|UINT32|0xb
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase|0x0|UINT32|0xc
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwSpareBase|0x0|UINT32|0xd
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase|0x0|UINT32|0xe
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsFdBaseAddress|0x0|UINT32|0xf
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase|0x0|UINT32|0x11
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesSize|0x0|UINT32|0x12
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase|0x0|UINT32|0x13
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize|0x0|UINT32|0x14
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageBase|0x0|UINT32|0x18
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageSize|0x0|UINT32|0x19
+  gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize|0x0|UINT32|0x1a
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd|0x0|UINT32|0x1f
+
+[PcdsDynamic, PcdsDynamicEx]
+
+  # TODO: investigate whether next two Pcds are needed
+  gSimicsX58PkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|0x28
+  gSimicsX58PkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId|0|UINT16|0x1b
+  
+  ## 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|0x1e
+
+
+[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|UINT16|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|0x00000003
+
+  ## 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|0x00000004
+
+  ## 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|BOOLEAN|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|0x00000007
+
+  ## Indicates if we need enable IsaAcpiFloppyB device.<BR><BR>
+  #   TRUE  - Enables IsaAcpiFloppyB device.<BR>
+  #   FALSE - Doesn't enable IsaAcpiFloppyB device.<BR>
+  # @Prompt Enable IsaAcpiFloppyB device.
+  gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiFloppyBEnable|TRUE|BOOLEAN|0x00000008
+
+[PcdsFixedAtBuild, PcdsPatchableInModule]
+  ## FFS filename to find the shell application.
+  # @Prompt FFS Name of Shell Application
+  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|0x00010040
\ 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


  reply	other threads:[~2019-08-15 18:35 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 [this message]
2019-08-20  1:04   ` Kubacki, Michael A
2019-08-23 16:57     ` David Wei
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=02A34F284D1DA44BB705E61F7180EF0AAEE0C175@ORSMSX114.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