diff --git a/.gitignore b/.gitignore
index 101dced..0a20017 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,5 @@
 /edk2-buildtools-r2670.tar.xz
 /edk2-buildtools-r17469.tar.xz
 /edk2-buildtools-r18975.tar.xz
+/edk2-20160418-a8c39ba.tar.gz
+/openssl-1.0.2g.tar.gz
diff --git a/0001-BaseTools-LzmaCompress-eliminate-_maxMode-and-bogus-.patch b/0001-BaseTools-LzmaCompress-eliminate-_maxMode-and-bogus-.patch
deleted file mode 100644
index fdace7c..0000000
--- a/0001-BaseTools-LzmaCompress-eliminate-_maxMode-and-bogus-.patch
+++ /dev/null
@@ -1,137 +0,0 @@
-From eb58c41d497a229f4412d9afd212978943d12c0e Mon Sep 17 00:00:00 2001
-From: Laszlo Ersek <lersek@redhat.com>
-Date: Sun, 14 Feb 2016 08:17:16 +0100
-Subject: [PATCH] BaseTools: LzmaCompress: eliminate _maxMode and bogus
- indentation
-
-The "_maxMode" variable doesn't exist in edk2's variant of LzmaCompress,
-but the way one of the old uses of the variable is commented out (i.e.,
-together with the enclosing "if" statement) triggers the
-"misleading-indentation" warning that is new in gcc-6.0, for the block of
-code that originally depended on the "if" statement. Gcc believes
-(mistakenly) that the programmer believes (mistakenly) that the block
-depends on (repIndex == 0) higher up.
-
-Remove the commented out uses of "_maxMode", and unindent the block in
-question.
-
-This patch is best viewed with "git show -b".
-
-Cc: Cole Robinson <crobinso@redhat.com>
-Cc: Yonghong Zhu <yonghong.zhu@intel.com>
-Cc: Liming Gao <liming.gao@intel.com>
-Reported-by: Cole Robinson <crobinso@redhat.com>
-Contributed-under: TianoCore Contribution Agreement 1.0
-Signed-off-by: Laszlo Ersek <lersek@redhat.com>
----
- BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c | 81 ++++++++++----------
- 1 file changed, 40 insertions(+), 41 deletions(-)
-
-diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c
-index 9b2dd16ffa48..1eb9898b5291 100644
---- a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c
-+++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c
-@@ -1367,52 +1367,51 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
-       if (repIndex == 0)
-         startLen = lenTest + 1;
-         
--      /* if (_maxMode) */
-+      {
-+        UInt32 lenTest2 = lenTest + 1;
-+        UInt32 limit = lenTest2 + p->numFastBytes;
-+        UInt32 nextRepMatchPrice;
-+        if (limit > numAvailFull)
-+          limit = numAvailFull;
-+        for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
-+        lenTest2 -= lenTest + 1;
-+        if (lenTest2 >= 2)
-         {
--          UInt32 lenTest2 = lenTest + 1;
--          UInt32 limit = lenTest2 + p->numFastBytes;
--          UInt32 nextRepMatchPrice;
--          if (limit > numAvailFull)
--            limit = numAvailFull;
--          for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
--          lenTest2 -= lenTest + 1;
--          if (lenTest2 >= 2)
-+          UInt32 state2 = kRepNextStates[state];
-+          UInt32 posStateNext = (position + lenTest) & p->pbMask;
-+          UInt32 curAndLenCharPrice =
-+              price + p->repLenEnc.prices[posState][lenTest - 2] +
-+              GET_PRICE_0(p->isMatch[state2][posStateNext]) +
-+              LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
-+                  data[lenTest], data2[lenTest], p->ProbPrices);
-+          state2 = kLiteralNextStates[state2];
-+          posStateNext = (position + lenTest + 1) & p->pbMask;
-+          nextRepMatchPrice = curAndLenCharPrice +
-+              GET_PRICE_1(p->isMatch[state2][posStateNext]) +
-+              GET_PRICE_1(p->isRep[state2]);
-+
-+          /* for (; lenTest2 >= 2; lenTest2--) */
-           {
--            UInt32 state2 = kRepNextStates[state];
--            UInt32 posStateNext = (position + lenTest) & p->pbMask;
--            UInt32 curAndLenCharPrice =
--                price + p->repLenEnc.prices[posState][lenTest - 2] +
--                GET_PRICE_0(p->isMatch[state2][posStateNext]) +
--                LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
--                    data[lenTest], data2[lenTest], p->ProbPrices);
--            state2 = kLiteralNextStates[state2];
--            posStateNext = (position + lenTest + 1) & p->pbMask;
--            nextRepMatchPrice = curAndLenCharPrice +
--                GET_PRICE_1(p->isMatch[state2][posStateNext]) +
--                GET_PRICE_1(p->isRep[state2]);
--            
--            /* for (; lenTest2 >= 2; lenTest2--) */
-+            UInt32 curAndLenPrice;
-+            COptimal *opt;
-+            UInt32 offset = cur + lenTest + 1 + lenTest2;
-+            while (lenEnd < offset)
-+              p->opt[++lenEnd].price = kInfinityPrice;
-+            curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
-+            opt = &p->opt[offset];
-+            if (curAndLenPrice < opt->price)
-             {
--              UInt32 curAndLenPrice;
--              COptimal *opt;
--              UInt32 offset = cur + lenTest + 1 + lenTest2;
--              while (lenEnd < offset)
--                p->opt[++lenEnd].price = kInfinityPrice;
--              curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
--              opt = &p->opt[offset];
--              if (curAndLenPrice < opt->price)
--              {
--                opt->price = curAndLenPrice;
--                opt->posPrev = cur + lenTest + 1;
--                opt->backPrev = 0;
--                opt->prev1IsChar = True;
--                opt->prev2 = True;
--                opt->posPrev2 = cur;
--                opt->backPrev2 = repIndex;
--              }
-+              opt->price = curAndLenPrice;
-+              opt->posPrev = cur + lenTest + 1;
-+              opt->backPrev = 0;
-+              opt->prev1IsChar = True;
-+              opt->prev2 = True;
-+              opt->posPrev2 = cur;
-+              opt->backPrev2 = repIndex;
-             }
-           }
-         }
-+      }
-     }
-     }
-     /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */
-@@ -1456,7 +1455,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
-           opt->prev1IsChar = False;
-         }
- 
--        if (/*_maxMode && */lenTest == matches[offs])
-+        if (lenTest == matches[offs])
-         {
-           /* Try Match + Literal + Rep0 */
-           const Byte *data2 = data - (curBack + 1);
--- 
-1.8.3.1
-
diff --git a/0001-EXCLUDE_SHELL_FROM_FD.patch b/0001-EXCLUDE_SHELL_FROM_FD.patch
new file mode 100644
index 0000000..d084003
--- /dev/null
+++ b/0001-EXCLUDE_SHELL_FROM_FD.patch
@@ -0,0 +1,68 @@
+From 144ac2186d46a9a6cbf4d4174b6db1865d7de1d7 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Thu, 18 Feb 2016 10:52:44 +0100
+Subject: [PATCH] EXCLUDE_SHELL_FROM_FD
+
+---
+ OvmfPkg/OvmfPkgIa32.fdf    | 2 ++
+ OvmfPkg/OvmfPkgIa32X64.fdf | 2 ++
+ OvmfPkg/OvmfPkgX64.fdf     | 2 ++
+ 3 files changed, 6 insertions(+)
+
+diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf
+index 93a51a5..9ae7982 100644
+--- a/OvmfPkg/OvmfPkgIa32.fdf
++++ b/OvmfPkg/OvmfPkgIa32.fdf
+@@ -273,11 +273,13 @@ INF  MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
+ 
+ INF  FatPkg/EnhancedFatDxe/Fat.inf
+ 
++!ifndef $(EXCLUDE_SHELL_FROM_FD)
+ !ifndef $(USE_OLD_SHELL)
+ INF  ShellPkg/Application/Shell/Shell.inf
+ !else
+ INF  RuleOverride = BINARY EdkShellBinPkg/FullShell/FullShell.inf
+ !endif
++!endif
+ 
+ FILE FREEFORM = PCD(gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile) {
+   SECTION RAW = MdeModulePkg/Logo/Logo.bmp
+diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf
+index aad16a6..f58f18a 100644
+--- a/OvmfPkg/OvmfPkgIa32X64.fdf
++++ b/OvmfPkg/OvmfPkgIa32X64.fdf
+@@ -273,11 +273,13 @@ INF  MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
+ 
+ INF  FatPkg/EnhancedFatDxe/Fat.inf
+ 
++!ifndef $(EXCLUDE_SHELL_FROM_FD)
+ !ifndef $(USE_OLD_SHELL)
+ INF  ShellPkg/Application/Shell/Shell.inf
+ !else
+ INF  RuleOverride = BINARY USE = X64 EdkShellBinPkg/FullShell/FullShell.inf
+ !endif
++!endif
+ 
+ FILE FREEFORM = PCD(gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile) {
+   SECTION RAW = MdeModulePkg/Logo/Logo.bmp
+diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
+index 387b808..4e0c0ab 100644
+--- a/OvmfPkg/OvmfPkgX64.fdf
++++ b/OvmfPkg/OvmfPkgX64.fdf
+@@ -273,11 +273,13 @@ INF  MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
+ 
+ INF  FatPkg/EnhancedFatDxe/Fat.inf
+ 
++!ifndef $(EXCLUDE_SHELL_FROM_FD)
+ !ifndef $(USE_OLD_SHELL)
+ INF  ShellPkg/Application/Shell/Shell.inf
+ !else
+ INF  RuleOverride = BINARY EdkShellBinPkg/FullShell/FullShell.inf
+ !endif
++!endif
+ 
+ FILE FREEFORM = PCD(gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile) {
+   SECTION RAW = MdeModulePkg/Logo/Logo.bmp
+-- 
+1.8.3.1
+
diff --git a/0001-MdeModulePkg-TerminalDxe-add-other-text-resolutions.patch b/0001-MdeModulePkg-TerminalDxe-add-other-text-resolutions.patch
new file mode 100644
index 0000000..1c28761
--- /dev/null
+++ b/0001-MdeModulePkg-TerminalDxe-add-other-text-resolutions.patch
@@ -0,0 +1,113 @@
+From c8e5617ebaaa8be91a32be48dcf3dc7157b00d2c Mon Sep 17 00:00:00 2001
+From: Laszlo Ersek <lersek@redhat.com>
+Date: Tue, 25 Feb 2014 18:40:35 +0100
+Subject: [PATCH] MdeModulePkg: TerminalDxe: add other text resolutions
+
+When the console output is multiplexed to several devices by
+ConSplitterDxe, then ConSplitterDxe builds an intersection of text modes
+supported by all console output devices.
+
+Two notable output devices are provided by:
+(1) MdeModulePkg/Universal/Console/GraphicsConsoleDxe,
+(2) MdeModulePkg/Universal/Console/TerminalDxe.
+
+GraphicsConsoleDxe supports four modes at most -- see
+InitializeGraphicsConsoleTextMode():
+
+(1a) 80x25 (required by the UEFI spec as mode 0),
+(1b) 80x50 (not necessarily supported, but if it is, then the UEFI spec
+     requires the driver to provide it as mode 1),
+(1c) 100x31 (corresponding to graphics resolution 800x600, which the UEFI
+     spec requires from all plug-in graphics devices),
+(1d) "full screen" resolution, derived form the underlying GOP's
+     horizontal and vertical resolutions with division by EFI_GLYPH_WIDTH
+     (8) and EFI_GLYPH_HEIGHT (19), respectively.
+
+The automatic "full screen resolution" makes GraphicsConsoleDxe's
+character console very flexible. However, TerminalDxe (which runs on
+serial ports) only provides the following fixed resolutions -- see
+InitializeTerminalConsoleTextMode():
+
+(2a) 80x25 (required by the UEFI spec as mode 0),
+(2b) 80x50 (since the character resolution of a serial device cannot be
+    interrogated easily, this is added unconditionally as mode 1)
+(2c) modes 2 and above come from "mTerminalConsoleModeData". This table
+     currently only contains one mode, 100x31.
+
+When ConSplitterDxe combines (1) and (2), multiplexing console output to
+both video output and serial terminal, the list of commonly supported text
+modes (ie. the "intersection") comprises:
+
+(3a) 80x25, unconditionally, from (1a) and (2a),
+(3b) 80x50, if the graphics console provides at least 640x950 pixel
+     resolution, from (1b) and (2b)
+(3c) 100x31, if the graphics device is a plug-in one (because in that case
+     800x600 is a mandated pixel resolution), from (1c) and (2c).
+
+Unfortunately, the "full screen resolution" (1d) of the GOP-based text
+console is not available in general.
+
+Mitigate this problem by extending "mTerminalConsoleModeData" with a
+handful of text resolutions that are derived from widespread maximal pixel
+resolutions. This way TerminalDxe won't cause ConSplitterDxe to filter out
+the most frequent (1d) values from the intersection, and eg. the MODE
+command in the UEFI shell will offer the "best" (ie. full screen)
+resolution too.
+
+Contributed-under: TianoCore Contribution Agreement 1.0
+Signed-off-by: Laszlo Ersek <lersek@redhat.com>
+---
+ .../Universal/Console/TerminalDxe/Terminal.c       | 37 +++++++++++++++++++++-
+ 1 file changed, 36 insertions(+), 1 deletion(-)
+
+diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c
+index 6fde3b2..787bd35 100644
+--- a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c
++++ b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c
+@@ -103,7 +103,42 @@ TERMINAL_DEV  mTerminalDevTemplate = {
+ };
+ 
+ TERMINAL_CONSOLE_MODE_DATA mTerminalConsoleModeData[] = {
+-  {100, 31},
++  {  100,  25 }, // from graphics resolution  800 x  480
++  {  100,  31 }, // from graphics resolution  800 x  600
++  {  104,  32 }, // from graphics resolution  832 x  624
++  {  120,  33 }, // from graphics resolution  960 x  640
++  {  128,  31 }, // from graphics resolution 1024 x  600
++  {  128,  40 }, // from graphics resolution 1024 x  768
++  {  144,  45 }, // from graphics resolution 1152 x  864
++  {  144,  45 }, // from graphics resolution 1152 x  870
++  {  160,  37 }, // from graphics resolution 1280 x  720
++  {  160,  40 }, // from graphics resolution 1280 x  760
++  {  160,  40 }, // from graphics resolution 1280 x  768
++  {  160,  42 }, // from graphics resolution 1280 x  800
++  {  160,  50 }, // from graphics resolution 1280 x  960
++  {  160,  53 }, // from graphics resolution 1280 x 1024
++  {  170,  40 }, // from graphics resolution 1360 x  768
++  {  170,  40 }, // from graphics resolution 1366 x  768
++  {  175,  55 }, // from graphics resolution 1400 x 1050
++  {  180,  47 }, // from graphics resolution 1440 x  900
++  {  200,  47 }, // from graphics resolution 1600 x  900
++  {  200,  63 }, // from graphics resolution 1600 x 1200
++  {  210,  55 }, // from graphics resolution 1680 x 1050
++  {  240,  56 }, // from graphics resolution 1920 x 1080
++  {  240,  63 }, // from graphics resolution 1920 x 1200
++  {  240,  75 }, // from graphics resolution 1920 x 1440
++  {  250, 105 }, // from graphics resolution 2000 x 2000
++  {  256,  80 }, // from graphics resolution 2048 x 1536
++  {  256, 107 }, // from graphics resolution 2048 x 2048
++  {  320,  75 }, // from graphics resolution 2560 x 1440
++  {  320,  84 }, // from graphics resolution 2560 x 1600
++  {  320, 107 }, // from graphics resolution 2560 x 2048
++  {  350, 110 }, // from graphics resolution 2800 x 2100
++  {  400, 126 }, // from graphics resolution 3200 x 2400
++  {  480, 113 }, // from graphics resolution 3840 x 2160
++  {  512, 113 }, // from graphics resolution 4096 x 2160
++  {  960, 227 }, // from graphics resolution 7680 x 4320
++  { 1024, 227 }, // from graphics resolution 8192 x 4320
+   //
+   // New modes can be added here.
+   //
+-- 
+1.8.3.1
+
diff --git a/0001-OvmfPkg-EnrollDefaultKeys-application-for-enrolling-.patch b/0001-OvmfPkg-EnrollDefaultKeys-application-for-enrolling-.patch
new file mode 100644
index 0000000..2e927e9
--- /dev/null
+++ b/0001-OvmfPkg-EnrollDefaultKeys-application-for-enrolling-.patch
@@ -0,0 +1,1126 @@
+From 89d722b43fba95708ba16ef676a989a6e02a55f5 Mon Sep 17 00:00:00 2001
+From: Laszlo Ersek <lersek@redhat.com>
+Date: Mon, 6 Jul 2015 20:22:02 +0200
+Subject: [PATCH] OvmfPkg: EnrollDefaultKeys: application for enrolling default
+ keys
+
+(A port of the <https://bugzilla.redhat.com/show_bug.cgi?id=1148296> patch
+to Gerd's public RPMs.)
+
+This application is meant to be invoked by the management layer, after
+booting the UEFI shell and getting a shell prompt on the serial console.
+The app enrolls a number of certificates (see below), and then reports
+status to the serial console as well. The expected output is "info:
+success":
+
+> Shell> EnrollDefaultKeys.efi
+> info: SetupMode=1 SecureBoot=0 SecureBootEnable=0 CustomMode=0 VendorKeys=1
+> info: SetupMode=0 SecureBoot=1 SecureBootEnable=1 CustomMode=0 VendorKeys=0
+> info: success
+> Shell>
+
+In case of success, the management layer can force off or reboot the VM
+(for example with the "reset -s" or "reset -c" UEFI shell commands,
+respectively), and start the guest installation with SecureBoot enabled.
+
+PK:
+- A unique, static, ad-hoc certificate whose private half has been
+  destroyed (more precisely, never saved) and is therefore unusable for
+  signing. (The command for creating this certificate is saved in the
+  source code.)
+
+KEK:
+- same ad-hoc certificate as used for the PK,
+- "Microsoft Corporation KEK CA 2011" -- the dbx data in Fedora's dbxtool
+  package is signed (indirectly, through a chain) with this; enrolling
+  such a KEK should allow guests to install those updates.
+
+DB:
+- "Microsoft Windows Production PCA 2011" -- to load Windows 8 and Windows
+  Server 2012 R2,
+- "Microsoft Corporation UEFI CA 2011" -- to load Linux and signed PCI
+  oproms.
+
+Contributed-under: TianoCore Contribution Agreement 1.0
+Signed-off-by: Laszlo Ersek <lersek@redhat.com>
+---
+ OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.c   | 960 ++++++++++++++++++++++++
+ OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf |  51 ++
+ OvmfPkg/OvmfPkgIa32.dsc                         |   4 +
+ OvmfPkg/OvmfPkgIa32X64.dsc                      |   4 +
+ OvmfPkg/OvmfPkgX64.dsc                          |   4 +
+ 5 files changed, 1023 insertions(+)
+ create mode 100644 OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.c
+ create mode 100644 OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf
+
+diff --git a/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.c b/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.c
+new file mode 100644
+index 000000000000..a1dddb2fb5be
+--- /dev/null
++++ b/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.c
+@@ -0,0 +1,960 @@
++/** @file
++  Enroll default PK, KEK, DB.
++
++  Copyright (C) 2014, Red Hat, Inc.
++
++  This program and the accompanying materials are licensed and made available
++  under the terms and conditions of the BSD License which accompanies this
++  distribution. The full text of the license may be found at
++  http://opensource.org/licenses/bsd-license.
++
++  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
++  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
++**/
++#include <Guid/AuthenticatedVariableFormat.h>    // gEfiCustomModeEnableGuid
++#include <Guid/GlobalVariable.h>                 // EFI_SETUP_MODE_NAME
++#include <Guid/ImageAuthentication.h>            // EFI_IMAGE_SECURITY_DATABASE
++#include <Library/BaseMemoryLib.h>               // CopyGuid()
++#include <Library/DebugLib.h>                    // ASSERT()
++#include <Library/MemoryAllocationLib.h>         // FreePool()
++#include <Library/ShellCEntryLib.h>              // ShellAppMain()
++#include <Library/UefiLib.h>                     // AsciiPrint()
++#include <Library/UefiRuntimeServicesTableLib.h> // gRT
++
++//
++// The example self-signed certificate below, which we'll use for both Platform
++// Key, and first Key Exchange Key, has been generated with the following
++// non-interactive openssl command. The passphrase is read from /dev/urandom,
++// and not saved, and the private key is written to /dev/null. In other words,
++// we can't sign anything else against this certificate, which is our purpose.
++//
++/*
++   openssl req \
++     -passout file:<(head -c 16 /dev/urandom) \
++     -x509 \
++     -newkey rsa:2048 \
++     -keyout /dev/null \
++     -outform DER \
++     -subj $(
++       printf /C=US
++       printf /ST=TestStateOrProvince
++       printf /L=TestLocality
++       printf /O=TestOrganization
++       printf /OU=TestOrganizationalUnit
++       printf /CN=TestCommonName
++       printf /emailAddress=test@example.com
++     ) \
++     2>/dev/null \
++   | xxd -i
++*/
++STATIC CONST UINT8 ExampleCert[] = {
++  0x30, 0x82, 0x04, 0x45, 0x30, 0x82, 0x03, 0x2d, 0xa0, 0x03, 0x02, 0x01, 0x02,
++  0x02, 0x09, 0x00, 0xcf, 0x9f, 0x51, 0xa3, 0x07, 0xdb, 0x54, 0xa1, 0x30, 0x0d,
++  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
++  0x30, 0x81, 0xb8, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
++  0x02, 0x55, 0x53, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c,
++  0x13, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4f, 0x72, 0x50,
++  0x72, 0x6f, 0x76, 0x69, 0x6e, 0x63, 0x65, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03,
++  0x55, 0x04, 0x07, 0x0c, 0x0c, 0x54, 0x65, 0x73, 0x74, 0x4c, 0x6f, 0x63, 0x61,
++  0x6c, 0x69, 0x74, 0x79, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a,
++  0x0c, 0x10, 0x54, 0x65, 0x73, 0x74, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a,
++  0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04,
++  0x0b, 0x0c, 0x16, 0x54, 0x65, 0x73, 0x74, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69,
++  0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x55, 0x6e, 0x69, 0x74, 0x31,
++  0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0e, 0x54, 0x65, 0x73,
++  0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x31, 0x1f,
++  0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01,
++  0x16, 0x10, 0x74, 0x65, 0x73, 0x74, 0x40, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
++  0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x31, 0x30,
++  0x30, 0x39, 0x31, 0x33, 0x32, 0x38, 0x32, 0x32, 0x5a, 0x17, 0x0d, 0x31, 0x34,
++  0x31, 0x31, 0x30, 0x38, 0x31, 0x33, 0x32, 0x38, 0x32, 0x32, 0x5a, 0x30, 0x81,
++  0xb8, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
++  0x53, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x13, 0x54,
++  0x65, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4f, 0x72, 0x50, 0x72, 0x6f,
++  0x76, 0x69, 0x6e, 0x63, 0x65, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04,
++  0x07, 0x0c, 0x0c, 0x54, 0x65, 0x73, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x69,
++  0x74, 0x79, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x10,
++  0x54, 0x65, 0x73, 0x74, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74,
++  0x69, 0x6f, 0x6e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c,
++  0x16, 0x54, 0x65, 0x73, 0x74, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61,
++  0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x55, 0x6e, 0x69, 0x74, 0x31, 0x17, 0x30,
++  0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0e, 0x54, 0x65, 0x73, 0x74, 0x43,
++  0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x31, 0x1f, 0x30, 0x1d,
++  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10,
++  0x74, 0x65, 0x73, 0x74, 0x40, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e,
++  0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
++  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
++  0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbf, 0xf1, 0xce,
++  0x17, 0x32, 0xac, 0xc4, 0x4b, 0xb2, 0xed, 0x84, 0x76, 0xe5, 0xd0, 0xf8, 0x21,
++  0xac, 0x10, 0xf8, 0x18, 0x09, 0x0e, 0x07, 0x13, 0x76, 0x21, 0x5c, 0xc4, 0xcc,
++  0xd5, 0xe6, 0x25, 0xa7, 0x26, 0x53, 0x79, 0x2f, 0x16, 0x4b, 0x85, 0xbd, 0xae,
++  0x42, 0x64, 0x58, 0xcb, 0x5e, 0xe8, 0x6e, 0x5a, 0xd0, 0xc4, 0x0f, 0x38, 0x16,
++  0xbe, 0xd3, 0x22, 0xa7, 0x3c, 0x9b, 0x8b, 0x5e, 0xcb, 0x62, 0x35, 0xc5, 0x9b,
++  0xe2, 0x8e, 0x4c, 0x65, 0x57, 0x4f, 0xcb, 0x27, 0xad, 0xe7, 0x63, 0xa7, 0x77,
++  0x2b, 0xd5, 0x02, 0x42, 0x70, 0x46, 0xac, 0xba, 0xb6, 0x60, 0x57, 0xd9, 0xce,
++  0x31, 0xc5, 0x12, 0x03, 0x4a, 0xf7, 0x2a, 0x2b, 0x40, 0x06, 0xb4, 0xdb, 0x31,
++  0xb7, 0x83, 0x6c, 0x67, 0x87, 0x98, 0x8b, 0xce, 0x1b, 0x30, 0x7a, 0xfa, 0x35,
++  0x6c, 0x86, 0x20, 0x74, 0xc5, 0x7d, 0x32, 0x31, 0x18, 0xeb, 0x69, 0xf7, 0x2d,
++  0x20, 0xc4, 0xf0, 0xd2, 0xfa, 0x67, 0x81, 0xc1, 0xbb, 0x23, 0xbb, 0x75, 0x1a,
++  0xe4, 0xb4, 0x49, 0x99, 0xdf, 0x12, 0x4c, 0xe3, 0x6d, 0x76, 0x24, 0x85, 0x24,
++  0xae, 0x5a, 0x9e, 0xbd, 0x54, 0x1c, 0xf9, 0x0e, 0xed, 0x96, 0xb5, 0xd8, 0xa2,
++  0x0d, 0x2a, 0x38, 0x5d, 0x12, 0x97, 0xb0, 0x4d, 0x75, 0x85, 0x1e, 0x47, 0x6d,
++  0xe1, 0x25, 0x59, 0xcb, 0xe9, 0x33, 0x86, 0x6a, 0xef, 0x98, 0x24, 0xa0, 0x2b,
++  0x02, 0x7b, 0xc0, 0x9f, 0x88, 0x03, 0xb0, 0xbe, 0x22, 0x65, 0x83, 0x77, 0xb3,
++  0x30, 0xba, 0xe0, 0x3b, 0x54, 0x31, 0x3a, 0x45, 0x81, 0x9c, 0x48, 0xaf, 0xc1,
++  0x11, 0x5b, 0xf2, 0x3a, 0x1e, 0x33, 0x1b, 0x8f, 0x0e, 0x04, 0xa4, 0x16, 0xd4,
++  0x6b, 0x57, 0xee, 0xe7, 0xba, 0xf5, 0xee, 0xaf, 0xe2, 0x4c, 0x50, 0xf8, 0x68,
++  0x57, 0x88, 0xfb, 0x7f, 0xa3, 0xcf, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x50,
++  0x30, 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
++  0x1e, 0x44, 0xe5, 0xef, 0xcd, 0x6e, 0x1f, 0xdb, 0xcb, 0x4f, 0x94, 0x8f, 0xe3,
++  0x3b, 0x1a, 0x8c, 0xe6, 0x95, 0x29, 0x61, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
++  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x1e, 0x44, 0xe5, 0xef, 0xcd, 0x6e,
++  0x1f, 0xdb, 0xcb, 0x4f, 0x94, 0x8f, 0xe3, 0x3b, 0x1a, 0x8c, 0xe6, 0x95, 0x29,
++  0x61, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01,
++  0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
++  0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x12, 0x9c, 0x3e, 0x38,
++  0xfc, 0x26, 0xea, 0x6d, 0xb7, 0x5c, 0x29, 0x3c, 0x76, 0x20, 0x0c, 0xb2, 0xa9,
++  0x0f, 0xdf, 0xc0, 0x85, 0xfe, 0xeb, 0xec, 0x1d, 0x5d, 0x73, 0x84, 0xac, 0x8a,
++  0xb4, 0x2a, 0x86, 0x38, 0x30, 0xaf, 0xd2, 0x2d, 0x2a, 0xde, 0x54, 0xc8, 0x5c,
++  0x29, 0x90, 0x24, 0xf2, 0x39, 0xc1, 0xa5, 0x00, 0xb4, 0xb7, 0xd8, 0xdc, 0x59,
++  0x64, 0x50, 0x62, 0x5f, 0x54, 0xf1, 0x73, 0x02, 0x4d, 0x43, 0xc5, 0xc3, 0xc4,
++  0x0e, 0x62, 0x60, 0x8c, 0x53, 0x66, 0x57, 0x77, 0xb5, 0x81, 0xda, 0x1f, 0x81,
++  0xda, 0xe9, 0xd6, 0x5e, 0x82, 0xce, 0xa7, 0x5c, 0xc0, 0xa6, 0xbe, 0x9c, 0x5c,
++  0x7b, 0xa5, 0x15, 0xc8, 0xd7, 0x14, 0x53, 0xd3, 0x5c, 0x1c, 0x9f, 0x8a, 0x9f,
++  0x66, 0x15, 0xd5, 0xd3, 0x2a, 0x27, 0x0c, 0xee, 0x9f, 0x80, 0x39, 0x88, 0x7b,
++  0x24, 0xde, 0x0c, 0x61, 0xa3, 0x44, 0xd8, 0x8d, 0x2e, 0x79, 0xf8, 0x1e, 0x04,
++  0x5a, 0xcb, 0xd6, 0x9c, 0xa3, 0x22, 0x8f, 0x09, 0x32, 0x1e, 0xe1, 0x65, 0x8f,
++  0x10, 0x5f, 0xd8, 0x52, 0x56, 0xd5, 0x77, 0xac, 0x58, 0x46, 0x60, 0xba, 0x2e,
++  0xe2, 0x3f, 0x58, 0x7d, 0x60, 0xfc, 0x31, 0x4a, 0x3a, 0xaf, 0x61, 0x55, 0x5f,
++  0xfb, 0x68, 0x14, 0x74, 0xda, 0xdc, 0x42, 0x78, 0xcc, 0xee, 0xff, 0x5c, 0x03,
++  0x24, 0x26, 0x2c, 0xb8, 0x3a, 0x81, 0xad, 0xdb, 0xe7, 0xed, 0xe1, 0x62, 0x84,
++  0x07, 0x1a, 0xc8, 0xa4, 0x4e, 0xb0, 0x87, 0xf7, 0x96, 0xd8, 0x33, 0x9b, 0x0d,
++  0xa7, 0x77, 0xae, 0x5b, 0xaf, 0xad, 0xe6, 0x5a, 0xc9, 0xfa, 0xa4, 0xe4, 0xe5,
++  0x57, 0xbb, 0x97, 0xdd, 0x92, 0x85, 0xd8, 0x03, 0x45, 0xfe, 0xd8, 0x6b, 0xb1,
++  0xdb, 0x85, 0x36, 0xb9, 0xd9, 0x28, 0xbf, 0x17, 0xae, 0x11, 0xde, 0x10, 0x19,
++  0x26, 0x5b, 0xc0, 0x3d, 0xc7
++};
++
++//
++// Second KEK: "Microsoft Corporation KEK CA 2011".
++// SHA1: 31:59:0b:fd:89:c9:d7:4e:d0:87:df:ac:66:33:4b:39:31:25:4b:30
++//
++// "dbx" updates in "dbxtool" are signed with a key derived from this KEK.
++//
++STATIC CONST UINT8 MicrosoftKEK[] = {
++  0x30, 0x82, 0x05, 0xe8, 0x30, 0x82, 0x03, 0xd0, 0xa0, 0x03, 0x02, 0x01, 0x02,
++  0x02, 0x0a, 0x61, 0x0a, 0xd1, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x30,
++  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
++  0x00, 0x30, 0x81, 0x91, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
++  0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
++  0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31,
++  0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64,
++  0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a,
++  0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43,
++  0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x3b, 0x30,
++  0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x32, 0x4d, 0x69, 0x63, 0x72, 0x6f,
++  0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74,
++  0x69, 0x6f, 0x6e, 0x20, 0x54, 0x68, 0x69, 0x72, 0x64, 0x20, 0x50, 0x61, 0x72,
++  0x74, 0x79, 0x20, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x70, 0x6c, 0x61, 0x63,
++  0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x30,
++  0x36, 0x32, 0x34, 0x32, 0x30, 0x34, 0x31, 0x32, 0x39, 0x5a, 0x17, 0x0d, 0x32,
++  0x36, 0x30, 0x36, 0x32, 0x34, 0x32, 0x30, 0x35, 0x31, 0x32, 0x39, 0x5a, 0x30,
++  0x81, 0x80, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
++  0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a,
++  0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30,
++  0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, 0x6d, 0x6f,
++  0x6e, 0x64, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x15,
++  0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72,
++  0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x2a, 0x30, 0x28, 0x06,
++  0x03, 0x55, 0x04, 0x03, 0x13, 0x21, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f,
++  0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f,
++  0x6e, 0x20, 0x4b, 0x45, 0x4b, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x31,
++  0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
++  0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82,
++  0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc4, 0xe8, 0xb5, 0x8a, 0xbf, 0xad,
++  0x57, 0x26, 0xb0, 0x26, 0xc3, 0xea, 0xe7, 0xfb, 0x57, 0x7a, 0x44, 0x02, 0x5d,
++  0x07, 0x0d, 0xda, 0x4a, 0xe5, 0x74, 0x2a, 0xe6, 0xb0, 0x0f, 0xec, 0x6d, 0xeb,
++  0xec, 0x7f, 0xb9, 0xe3, 0x5a, 0x63, 0x32, 0x7c, 0x11, 0x17, 0x4f, 0x0e, 0xe3,
++  0x0b, 0xa7, 0x38, 0x15, 0x93, 0x8e, 0xc6, 0xf5, 0xe0, 0x84, 0xb1, 0x9a, 0x9b,
++  0x2c, 0xe7, 0xf5, 0xb7, 0x91, 0xd6, 0x09, 0xe1, 0xe2, 0xc0, 0x04, 0xa8, 0xac,
++  0x30, 0x1c, 0xdf, 0x48, 0xf3, 0x06, 0x50, 0x9a, 0x64, 0xa7, 0x51, 0x7f, 0xc8,
++  0x85, 0x4f, 0x8f, 0x20, 0x86, 0xce, 0xfe, 0x2f, 0xe1, 0x9f, 0xff, 0x82, 0xc0,
++  0xed, 0xe9, 0xcd, 0xce, 0xf4, 0x53, 0x6a, 0x62, 0x3a, 0x0b, 0x43, 0xb9, 0xe2,
++  0x25, 0xfd, 0xfe, 0x05, 0xf9, 0xd4, 0xc4, 0x14, 0xab, 0x11, 0xe2, 0x23, 0x89,
++  0x8d, 0x70, 0xb7, 0xa4, 0x1d, 0x4d, 0xec, 0xae, 0xe5, 0x9c, 0xfa, 0x16, 0xc2,
++  0xd7, 0xc1, 0xcb, 0xd4, 0xe8, 0xc4, 0x2f, 0xe5, 0x99, 0xee, 0x24, 0x8b, 0x03,
++  0xec, 0x8d, 0xf2, 0x8b, 0xea, 0xc3, 0x4a, 0xfb, 0x43, 0x11, 0x12, 0x0b, 0x7e,
++  0xb5, 0x47, 0x92, 0x6c, 0xdc, 0xe6, 0x04, 0x89, 0xeb, 0xf5, 0x33, 0x04, 0xeb,
++  0x10, 0x01, 0x2a, 0x71, 0xe5, 0xf9, 0x83, 0x13, 0x3c, 0xff, 0x25, 0x09, 0x2f,
++  0x68, 0x76, 0x46, 0xff, 0xba, 0x4f, 0xbe, 0xdc, 0xad, 0x71, 0x2a, 0x58, 0xaa,
++  0xfb, 0x0e, 0xd2, 0x79, 0x3d, 0xe4, 0x9b, 0x65, 0x3b, 0xcc, 0x29, 0x2a, 0x9f,
++  0xfc, 0x72, 0x59, 0xa2, 0xeb, 0xae, 0x92, 0xef, 0xf6, 0x35, 0x13, 0x80, 0xc6,
++  0x02, 0xec, 0xe4, 0x5f, 0xcc, 0x9d, 0x76, 0xcd, 0xef, 0x63, 0x92, 0xc1, 0xaf,
++  0x79, 0x40, 0x84, 0x79, 0x87, 0x7f, 0xe3, 0x52, 0xa8, 0xe8, 0x9d, 0x7b, 0x07,
++  0x69, 0x8f, 0x15, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x4f, 0x30,
++  0x82, 0x01, 0x4b, 0x30, 0x10, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82,
++  0x37, 0x15, 0x01, 0x04, 0x03, 0x02, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55,
++  0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x62, 0xfc, 0x43, 0xcd, 0xa0, 0x3e, 0xa4,
++  0xcb, 0x67, 0x12, 0xd2, 0x5b, 0xd9, 0x55, 0xac, 0x7b, 0xcc, 0xb6, 0x8a, 0x5f,
++  0x30, 0x19, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02,
++  0x04, 0x0c, 0x1e, 0x0a, 0x00, 0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43, 0x00,
++  0x41, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01,
++  0x86, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05,
++  0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
++  0x18, 0x30, 0x16, 0x80, 0x14, 0x45, 0x66, 0x52, 0x43, 0xe1, 0x7e, 0x58, 0x11,
++  0xbf, 0xd6, 0x4e, 0x9e, 0x23, 0x55, 0x08, 0x3b, 0x3a, 0x22, 0x6a, 0xa8, 0x30,
++  0x5c, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x55, 0x30, 0x53, 0x30, 0x51, 0xa0,
++  0x4f, 0xa0, 0x4d, 0x86, 0x4b, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63,
++  0x72, 0x6c, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e,
++  0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x70,
++  0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x2f, 0x4d, 0x69, 0x63, 0x43, 0x6f,
++  0x72, 0x54, 0x68, 0x69, 0x50, 0x61, 0x72, 0x4d, 0x61, 0x72, 0x52, 0x6f, 0x6f,
++  0x5f, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x30, 0x2d, 0x30, 0x35, 0x2e, 0x63,
++  0x72, 0x6c, 0x30, 0x60, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01,
++  0x01, 0x04, 0x54, 0x30, 0x52, 0x30, 0x50, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
++  0x05, 0x07, 0x30, 0x02, 0x86, 0x44, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
++  0x77, 0x77, 0x77, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74,
++  0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x63, 0x65, 0x72, 0x74,
++  0x73, 0x2f, 0x4d, 0x69, 0x63, 0x43, 0x6f, 0x72, 0x54, 0x68, 0x69, 0x50, 0x61,
++  0x72, 0x4d, 0x61, 0x72, 0x52, 0x6f, 0x6f, 0x5f, 0x32, 0x30, 0x31, 0x30, 0x2d,
++  0x31, 0x30, 0x2d, 0x30, 0x35, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06, 0x09,
++  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82,
++  0x02, 0x01, 0x00, 0xd4, 0x84, 0x88, 0xf5, 0x14, 0x94, 0x18, 0x02, 0xca, 0x2a,
++  0x3c, 0xfb, 0x2a, 0x92, 0x1c, 0x0c, 0xd7, 0xa0, 0xd1, 0xf1, 0xe8, 0x52, 0x66,
++  0xa8, 0xee, 0xa2, 0xb5, 0x75, 0x7a, 0x90, 0x00, 0xaa, 0x2d, 0xa4, 0x76, 0x5a,
++  0xea, 0x79, 0xb7, 0xb9, 0x37, 0x6a, 0x51, 0x7b, 0x10, 0x64, 0xf6, 0xe1, 0x64,
++  0xf2, 0x02, 0x67, 0xbe, 0xf7, 0xa8, 0x1b, 0x78, 0xbd, 0xba, 0xce, 0x88, 0x58,
++  0x64, 0x0c, 0xd6, 0x57, 0xc8, 0x19, 0xa3, 0x5f, 0x05, 0xd6, 0xdb, 0xc6, 0xd0,
++  0x69, 0xce, 0x48, 0x4b, 0x32, 0xb7, 0xeb, 0x5d, 0xd2, 0x30, 0xf5, 0xc0, 0xf5,
++  0xb8, 0xba, 0x78, 0x07, 0xa3, 0x2b, 0xfe, 0x9b, 0xdb, 0x34, 0x56, 0x84, 0xec,
++  0x82, 0xca, 0xae, 0x41, 0x25, 0x70, 0x9c, 0x6b, 0xe9, 0xfe, 0x90, 0x0f, 0xd7,
++  0x96, 0x1f, 0xe5, 0xe7, 0x94, 0x1f, 0xb2, 0x2a, 0x0c, 0x8d, 0x4b, 0xff, 0x28,
++  0x29, 0x10, 0x7b, 0xf7, 0xd7, 0x7c, 0xa5, 0xd1, 0x76, 0xb9, 0x05, 0xc8, 0x79,
++  0xed, 0x0f, 0x90, 0x92, 0x9c, 0xc2, 0xfe, 0xdf, 0x6f, 0x7e, 0x6c, 0x0f, 0x7b,
++  0xd4, 0xc1, 0x45, 0xdd, 0x34, 0x51, 0x96, 0x39, 0x0f, 0xe5, 0x5e, 0x56, 0xd8,
++  0x18, 0x05, 0x96, 0xf4, 0x07, 0xa6, 0x42, 0xb3, 0xa0, 0x77, 0xfd, 0x08, 0x19,
++  0xf2, 0x71, 0x56, 0xcc, 0x9f, 0x86, 0x23, 0xa4, 0x87, 0xcb, 0xa6, 0xfd, 0x58,
++  0x7e, 0xd4, 0x69, 0x67, 0x15, 0x91, 0x7e, 0x81, 0xf2, 0x7f, 0x13, 0xe5, 0x0d,
++  0x8b, 0x8a, 0x3c, 0x87, 0x84, 0xeb, 0xe3, 0xce, 0xbd, 0x43, 0xe5, 0xad, 0x2d,
++  0x84, 0x93, 0x8e, 0x6a, 0x2b, 0x5a, 0x7c, 0x44, 0xfa, 0x52, 0xaa, 0x81, 0xc8,
++  0x2d, 0x1c, 0xbb, 0xe0, 0x52, 0xdf, 0x00, 0x11, 0xf8, 0x9a, 0x3d, 0xc1, 0x60,
++  0xb0, 0xe1, 0x33, 0xb5, 0xa3, 0x88, 0xd1, 0x65, 0x19, 0x0a, 0x1a, 0xe7, 0xac,
++  0x7c, 0xa4, 0xc1, 0x82, 0x87, 0x4e, 0x38, 0xb1, 0x2f, 0x0d, 0xc5, 0x14, 0x87,
++  0x6f, 0xfd, 0x8d, 0x2e, 0xbc, 0x39, 0xb6, 0xe7, 0xe6, 0xc3, 0xe0, 0xe4, 0xcd,
++  0x27, 0x84, 0xef, 0x94, 0x42, 0xef, 0x29, 0x8b, 0x90, 0x46, 0x41, 0x3b, 0x81,
++  0x1b, 0x67, 0xd8, 0xf9, 0x43, 0x59, 0x65, 0xcb, 0x0d, 0xbc, 0xfd, 0x00, 0x92,
++  0x4f, 0xf4, 0x75, 0x3b, 0xa7, 0xa9, 0x24, 0xfc, 0x50, 0x41, 0x40, 0x79, 0xe0,
++  0x2d, 0x4f, 0x0a, 0x6a, 0x27, 0x76, 0x6e, 0x52, 0xed, 0x96, 0x69, 0x7b, 0xaf,
++  0x0f, 0xf7, 0x87, 0x05, 0xd0, 0x45, 0xc2, 0xad, 0x53, 0x14, 0x81, 0x1f, 0xfb,
++  0x30, 0x04, 0xaa, 0x37, 0x36, 0x61, 0xda, 0x4a, 0x69, 0x1b, 0x34, 0xd8, 0x68,
++  0xed, 0xd6, 0x02, 0xcf, 0x6c, 0x94, 0x0c, 0xd3, 0xcf, 0x6c, 0x22, 0x79, 0xad,
++  0xb1, 0xf0, 0xbc, 0x03, 0xa2, 0x46, 0x60, 0xa9, 0xc4, 0x07, 0xc2, 0x21, 0x82,
++  0xf1, 0xfd, 0xf2, 0xe8, 0x79, 0x32, 0x60, 0xbf, 0xd8, 0xac, 0xa5, 0x22, 0x14,
++  0x4b, 0xca, 0xc1, 0xd8, 0x4b, 0xeb, 0x7d, 0x3f, 0x57, 0x35, 0xb2, 0xe6, 0x4f,
++  0x75, 0xb4, 0xb0, 0x60, 0x03, 0x22, 0x53, 0xae, 0x91, 0x79, 0x1d, 0xd6, 0x9b,
++  0x41, 0x1f, 0x15, 0x86, 0x54, 0x70, 0xb2, 0xde, 0x0d, 0x35, 0x0f, 0x7c, 0xb0,
++  0x34, 0x72, 0xba, 0x97, 0x60, 0x3b, 0xf0, 0x79, 0xeb, 0xa2, 0xb2, 0x1c, 0x5d,
++  0xa2, 0x16, 0xb8, 0x87, 0xc5, 0xe9, 0x1b, 0xf6, 0xb5, 0x97, 0x25, 0x6f, 0x38,
++  0x9f, 0xe3, 0x91, 0xfa, 0x8a, 0x79, 0x98, 0xc3, 0x69, 0x0e, 0xb7, 0xa3, 0x1c,
++  0x20, 0x05, 0x97, 0xf8, 0xca, 0x14, 0xae, 0x00, 0xd7, 0xc4, 0xf3, 0xc0, 0x14,
++  0x10, 0x75, 0x6b, 0x34, 0xa0, 0x1b, 0xb5, 0x99, 0x60, 0xf3, 0x5c, 0xb0, 0xc5,
++  0x57, 0x4e, 0x36, 0xd2, 0x32, 0x84, 0xbf, 0x9e
++};
++
++//
++// First DB entry: "Microsoft Windows Production PCA 2011"
++// SHA1: 58:0a:6f:4c:c4:e4:b6:69:b9:eb:dc:1b:2b:3e:08:7b:80:d0:67:8d
++//
++// Windows 8 and Windows Server 2012 R2 boot loaders are signed with a chain
++// rooted in this certificate.
++//
++STATIC CONST UINT8 MicrosoftPCA[] = {
++  0x30, 0x82, 0x05, 0xd7, 0x30, 0x82, 0x03, 0xbf, 0xa0, 0x03, 0x02, 0x01, 0x02,
++  0x02, 0x0a, 0x61, 0x07, 0x76, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x30,
++  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
++  0x00, 0x30, 0x81, 0x88, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
++  0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
++  0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31,
++  0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64,
++  0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a,
++  0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43,
++  0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x32, 0x30,
++  0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x4d, 0x69, 0x63, 0x72, 0x6f,
++  0x73, 0x6f, 0x66, 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72,
++  0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68,
++  0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x30, 0x30, 0x1e, 0x17,
++  0x0d, 0x31, 0x31, 0x31, 0x30, 0x31, 0x39, 0x31, 0x38, 0x34, 0x31, 0x34, 0x32,
++  0x5a, 0x17, 0x0d, 0x32, 0x36, 0x31, 0x30, 0x31, 0x39, 0x31, 0x38, 0x35, 0x31,
++  0x34, 0x32, 0x5a, 0x30, 0x81, 0x84, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
++  0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
++  0x04, 0x08, 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f,
++  0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52,
++  0x65, 0x64, 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55,
++  0x04, 0x0a, 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74,
++  0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31,
++  0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x4d, 0x69, 0x63,
++  0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77,
++  0x73, 0x20, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20,
++  0x50, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x31, 0x30, 0x82, 0x01, 0x22, 0x30,
++  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
++  0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01,
++  0x01, 0x00, 0xdd, 0x0c, 0xbb, 0xa2, 0xe4, 0x2e, 0x09, 0xe3, 0xe7, 0xc5, 0xf7,
++  0x96, 0x69, 0xbc, 0x00, 0x21, 0xbd, 0x69, 0x33, 0x33, 0xef, 0xad, 0x04, 0xcb,
++  0x54, 0x80, 0xee, 0x06, 0x83, 0xbb, 0xc5, 0x20, 0x84, 0xd9, 0xf7, 0xd2, 0x8b,
++  0xf3, 0x38, 0xb0, 0xab, 0xa4, 0xad, 0x2d, 0x7c, 0x62, 0x79, 0x05, 0xff, 0xe3,
++  0x4a, 0x3f, 0x04, 0x35, 0x20, 0x70, 0xe3, 0xc4, 0xe7, 0x6b, 0xe0, 0x9c, 0xc0,
++  0x36, 0x75, 0xe9, 0x8a, 0x31, 0xdd, 0x8d, 0x70, 0xe5, 0xdc, 0x37, 0xb5, 0x74,
++  0x46, 0x96, 0x28, 0x5b, 0x87, 0x60, 0x23, 0x2c, 0xbf, 0xdc, 0x47, 0xa5, 0x67,
++  0xf7, 0x51, 0x27, 0x9e, 0x72, 0xeb, 0x07, 0xa6, 0xc9, 0xb9, 0x1e, 0x3b, 0x53,
++  0x35, 0x7c, 0xe5, 0xd3, 0xec, 0x27, 0xb9, 0x87, 0x1c, 0xfe, 0xb9, 0xc9, 0x23,
++  0x09, 0x6f, 0xa8, 0x46, 0x91, 0xc1, 0x6e, 0x96, 0x3c, 0x41, 0xd3, 0xcb, 0xa3,
++  0x3f, 0x5d, 0x02, 0x6a, 0x4d, 0xec, 0x69, 0x1f, 0x25, 0x28, 0x5c, 0x36, 0xff,
++  0xfd, 0x43, 0x15, 0x0a, 0x94, 0xe0, 0x19, 0xb4, 0xcf, 0xdf, 0xc2, 0x12, 0xe2,
++  0xc2, 0x5b, 0x27, 0xee, 0x27, 0x78, 0x30, 0x8b, 0x5b, 0x2a, 0x09, 0x6b, 0x22,
++  0x89, 0x53, 0x60, 0x16, 0x2c, 0xc0, 0x68, 0x1d, 0x53, 0xba, 0xec, 0x49, 0xf3,
++  0x9d, 0x61, 0x8c, 0x85, 0x68, 0x09, 0x73, 0x44, 0x5d, 0x7d, 0xa2, 0x54, 0x2b,
++  0xdd, 0x79, 0xf7, 0x15, 0xcf, 0x35, 0x5d, 0x6c, 0x1c, 0x2b, 0x5c, 0xce, 0xbc,
++  0x9c, 0x23, 0x8b, 0x6f, 0x6e, 0xb5, 0x26, 0xd9, 0x36, 0x13, 0xc3, 0x4f, 0xd6,
++  0x27, 0xae, 0xb9, 0x32, 0x3b, 0x41, 0x92, 0x2c, 0xe1, 0xc7, 0xcd, 0x77, 0xe8,
++  0xaa, 0x54, 0x4e, 0xf7, 0x5c, 0x0b, 0x04, 0x87, 0x65, 0xb4, 0x43, 0x18, 0xa8,
++  0xb2, 0xe0, 0x6d, 0x19, 0x77, 0xec, 0x5a, 0x24, 0xfa, 0x48, 0x03, 0x02, 0x03,
++  0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x43, 0x30, 0x82, 0x01, 0x3f, 0x30, 0x10,
++  0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x01, 0x04, 0x03,
++  0x02, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
++  0x14, 0xa9, 0x29, 0x02, 0x39, 0x8e, 0x16, 0xc4, 0x97, 0x78, 0xcd, 0x90, 0xf9,
++  0x9e, 0x4f, 0x9a, 0xe1, 0x7c, 0x55, 0xaf, 0x53, 0x30, 0x19, 0x06, 0x09, 0x2b,
++  0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x0c, 0x1e, 0x0a, 0x00,
++  0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43, 0x00, 0x41, 0x30, 0x0b, 0x06, 0x03,
++  0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0f, 0x06, 0x03,
++  0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff,
++  0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
++  0xd5, 0xf6, 0x56, 0xcb, 0x8f, 0xe8, 0xa2, 0x5c, 0x62, 0x68, 0xd1, 0x3d, 0x94,
++  0x90, 0x5b, 0xd7, 0xce, 0x9a, 0x18, 0xc4, 0x30, 0x56, 0x06, 0x03, 0x55, 0x1d,
++  0x1f, 0x04, 0x4f, 0x30, 0x4d, 0x30, 0x4b, 0xa0, 0x49, 0xa0, 0x47, 0x86, 0x45,
++  0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x6d, 0x69,
++  0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70,
++  0x6b, 0x69, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63,
++  0x74, 0x73, 0x2f, 0x4d, 0x69, 0x63, 0x52, 0x6f, 0x6f, 0x43, 0x65, 0x72, 0x41,
++  0x75, 0x74, 0x5f, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x33,
++  0x2e, 0x63, 0x72, 0x6c, 0x30, 0x5a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
++  0x07, 0x01, 0x01, 0x04, 0x4e, 0x30, 0x4c, 0x30, 0x4a, 0x06, 0x08, 0x2b, 0x06,
++  0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x3e, 0x68, 0x74, 0x74, 0x70, 0x3a,
++  0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f,
++  0x66, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x63, 0x65,
++  0x72, 0x74, 0x73, 0x2f, 0x4d, 0x69, 0x63, 0x52, 0x6f, 0x6f, 0x43, 0x65, 0x72,
++  0x41, 0x75, 0x74, 0x5f, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x36, 0x2d, 0x32,
++  0x33, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
++  0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x14,
++  0xfc, 0x7c, 0x71, 0x51, 0xa5, 0x79, 0xc2, 0x6e, 0xb2, 0xef, 0x39, 0x3e, 0xbc,
++  0x3c, 0x52, 0x0f, 0x6e, 0x2b, 0x3f, 0x10, 0x13, 0x73, 0xfe, 0xa8, 0x68, 0xd0,
++  0x48, 0xa6, 0x34, 0x4d, 0x8a, 0x96, 0x05, 0x26, 0xee, 0x31, 0x46, 0x90, 0x61,
++  0x79, 0xd6, 0xff, 0x38, 0x2e, 0x45, 0x6b, 0xf4, 0xc0, 0xe5, 0x28, 0xb8, 0xda,
++  0x1d, 0x8f, 0x8a, 0xdb, 0x09, 0xd7, 0x1a, 0xc7, 0x4c, 0x0a, 0x36, 0x66, 0x6a,
++  0x8c, 0xec, 0x1b, 0xd7, 0x04, 0x90, 0xa8, 0x18, 0x17, 0xa4, 0x9b, 0xb9, 0xe2,
++  0x40, 0x32, 0x36, 0x76, 0xc4, 0xc1, 0x5a, 0xc6, 0xbf, 0xe4, 0x04, 0xc0, 0xea,
++  0x16, 0xd3, 0xac, 0xc3, 0x68, 0xef, 0x62, 0xac, 0xdd, 0x54, 0x6c, 0x50, 0x30,
++  0x58, 0xa6, 0xeb, 0x7c, 0xfe, 0x94, 0xa7, 0x4e, 0x8e, 0xf4, 0xec, 0x7c, 0x86,
++  0x73, 0x57, 0xc2, 0x52, 0x21, 0x73, 0x34, 0x5a, 0xf3, 0xa3, 0x8a, 0x56, 0xc8,
++  0x04, 0xda, 0x07, 0x09, 0xed, 0xf8, 0x8b, 0xe3, 0xce, 0xf4, 0x7e, 0x8e, 0xae,
++  0xf0, 0xf6, 0x0b, 0x8a, 0x08, 0xfb, 0x3f, 0xc9, 0x1d, 0x72, 0x7f, 0x53, 0xb8,
++  0xeb, 0xbe, 0x63, 0xe0, 0xe3, 0x3d, 0x31, 0x65, 0xb0, 0x81, 0xe5, 0xf2, 0xac,
++  0xcd, 0x16, 0xa4, 0x9f, 0x3d, 0xa8, 0xb1, 0x9b, 0xc2, 0x42, 0xd0, 0x90, 0x84,
++  0x5f, 0x54, 0x1d, 0xff, 0x89, 0xea, 0xba, 0x1d, 0x47, 0x90, 0x6f, 0xb0, 0x73,
++  0x4e, 0x41, 0x9f, 0x40, 0x9f, 0x5f, 0xe5, 0xa1, 0x2a, 0xb2, 0x11, 0x91, 0x73,
++  0x8a, 0x21, 0x28, 0xf0, 0xce, 0xde, 0x73, 0x39, 0x5f, 0x3e, 0xab, 0x5c, 0x60,
++  0xec, 0xdf, 0x03, 0x10, 0xa8, 0xd3, 0x09, 0xe9, 0xf4, 0xf6, 0x96, 0x85, 0xb6,
++  0x7f, 0x51, 0x88, 0x66, 0x47, 0x19, 0x8d, 0xa2, 0xb0, 0x12, 0x3d, 0x81, 0x2a,
++  0x68, 0x05, 0x77, 0xbb, 0x91, 0x4c, 0x62, 0x7b, 0xb6, 0xc1, 0x07, 0xc7, 0xba,
++  0x7a, 0x87, 0x34, 0x03, 0x0e, 0x4b, 0x62, 0x7a, 0x99, 0xe9, 0xca, 0xfc, 0xce,
++  0x4a, 0x37, 0xc9, 0x2d, 0xa4, 0x57, 0x7c, 0x1c, 0xfe, 0x3d, 0xdc, 0xb8, 0x0f,
++  0x5a, 0xfa, 0xd6, 0xc4, 0xb3, 0x02, 0x85, 0x02, 0x3a, 0xea, 0xb3, 0xd9, 0x6e,
++  0xe4, 0x69, 0x21, 0x37, 0xde, 0x81, 0xd1, 0xf6, 0x75, 0x19, 0x05, 0x67, 0xd3,
++  0x93, 0x57, 0x5e, 0x29, 0x1b, 0x39, 0xc8, 0xee, 0x2d, 0xe1, 0xcd, 0xe4, 0x45,
++  0x73, 0x5b, 0xd0, 0xd2, 0xce, 0x7a, 0xab, 0x16, 0x19, 0x82, 0x46, 0x58, 0xd0,
++  0x5e, 0x9d, 0x81, 0xb3, 0x67, 0xaf, 0x6c, 0x35, 0xf2, 0xbc, 0xe5, 0x3f, 0x24,
++  0xe2, 0x35, 0xa2, 0x0a, 0x75, 0x06, 0xf6, 0x18, 0x56, 0x99, 0xd4, 0x78, 0x2c,
++  0xd1, 0x05, 0x1b, 0xeb, 0xd0, 0x88, 0x01, 0x9d, 0xaa, 0x10, 0xf1, 0x05, 0xdf,
++  0xba, 0x7e, 0x2c, 0x63, 0xb7, 0x06, 0x9b, 0x23, 0x21, 0xc4, 0xf9, 0x78, 0x6c,
++  0xe2, 0x58, 0x17, 0x06, 0x36, 0x2b, 0x91, 0x12, 0x03, 0xcc, 0xa4, 0xd9, 0xf2,
++  0x2d, 0xba, 0xf9, 0x94, 0x9d, 0x40, 0xed, 0x18, 0x45, 0xf1, 0xce, 0x8a, 0x5c,
++  0x6b, 0x3e, 0xab, 0x03, 0xd3, 0x70, 0x18, 0x2a, 0x0a, 0x6a, 0xe0, 0x5f, 0x47,
++  0xd1, 0xd5, 0x63, 0x0a, 0x32, 0xf2, 0xaf, 0xd7, 0x36, 0x1f, 0x2a, 0x70, 0x5a,
++  0xe5, 0x42, 0x59, 0x08, 0x71, 0x4b, 0x57, 0xba, 0x7e, 0x83, 0x81, 0xf0, 0x21,
++  0x3c, 0xf4, 0x1c, 0xc1, 0xc5, 0xb9, 0x90, 0x93, 0x0e, 0x88, 0x45, 0x93, 0x86,
++  0xe9, 0xb1, 0x20, 0x99, 0xbe, 0x98, 0xcb, 0xc5, 0x95, 0xa4, 0x5d, 0x62, 0xd6,
++  0xa0, 0x63, 0x08, 0x20, 0xbd, 0x75, 0x10, 0x77, 0x7d, 0x3d, 0xf3, 0x45, 0xb9,
++  0x9f, 0x97, 0x9f, 0xcb, 0x57, 0x80, 0x6f, 0x33, 0xa9, 0x04, 0xcf, 0x77, 0xa4,
++  0x62, 0x1c, 0x59, 0x7e
++};
++
++//
++// Second DB entry: "Microsoft Corporation UEFI CA 2011"
++// SHA1: 46:de:f6:3b:5c:e6:1c:f8:ba:0d:e2:e6:63:9c:10:19:d0:ed:14:f3
++//
++// To verify the "shim" binary and PCI expansion ROMs with.
++//
++STATIC CONST UINT8 MicrosoftUefiCA[] = {
++  0x30, 0x82, 0x06, 0x10, 0x30, 0x82, 0x03, 0xf8, 0xa0, 0x03, 0x02, 0x01, 0x02,
++  0x02, 0x0a, 0x61, 0x08, 0xd3, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30,
++  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
++  0x00, 0x30, 0x81, 0x91, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
++  0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
++  0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31,
++  0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64,
++  0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a,
++  0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43,
++  0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x3b, 0x30,
++  0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x32, 0x4d, 0x69, 0x63, 0x72, 0x6f,
++  0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74,
++  0x69, 0x6f, 0x6e, 0x20, 0x54, 0x68, 0x69, 0x72, 0x64, 0x20, 0x50, 0x61, 0x72,
++  0x74, 0x79, 0x20, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x70, 0x6c, 0x61, 0x63,
++  0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x30,
++  0x36, 0x32, 0x37, 0x32, 0x31, 0x32, 0x32, 0x34, 0x35, 0x5a, 0x17, 0x0d, 0x32,
++  0x36, 0x30, 0x36, 0x32, 0x37, 0x32, 0x31, 0x33, 0x32, 0x34, 0x35, 0x5a, 0x30,
++  0x81, 0x81, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
++  0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a,
++  0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30,
++  0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, 0x6d, 0x6f,
++  0x6e, 0x64, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x15,
++  0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72,
++  0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x2b, 0x30, 0x29, 0x06,
++  0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f,
++  0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f,
++  0x6e, 0x20, 0x55, 0x45, 0x46, 0x49, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31,
++  0x31, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
++  0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
++  0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa5, 0x08, 0x6c, 0x4c, 0xc7,
++  0x45, 0x09, 0x6a, 0x4b, 0x0c, 0xa4, 0xc0, 0x87, 0x7f, 0x06, 0x75, 0x0c, 0x43,
++  0x01, 0x54, 0x64, 0xe0, 0x16, 0x7f, 0x07, 0xed, 0x92, 0x7d, 0x0b, 0xb2, 0x73,
++  0xbf, 0x0c, 0x0a, 0xc6, 0x4a, 0x45, 0x61, 0xa0, 0xc5, 0x16, 0x2d, 0x96, 0xd3,
++  0xf5, 0x2b, 0xa0, 0xfb, 0x4d, 0x49, 0x9b, 0x41, 0x80, 0x90, 0x3c, 0xb9, 0x54,
++  0xfd, 0xe6, 0xbc, 0xd1, 0x9d, 0xc4, 0xa4, 0x18, 0x8a, 0x7f, 0x41, 0x8a, 0x5c,
++  0x59, 0x83, 0x68, 0x32, 0xbb, 0x8c, 0x47, 0xc9, 0xee, 0x71, 0xbc, 0x21, 0x4f,
++  0x9a, 0x8a, 0x7c, 0xff, 0x44, 0x3f, 0x8d, 0x8f, 0x32, 0xb2, 0x26, 0x48, 0xae,
++  0x75, 0xb5, 0xee, 0xc9, 0x4c, 0x1e, 0x4a, 0x19, 0x7e, 0xe4, 0x82, 0x9a, 0x1d,
++  0x78, 0x77, 0x4d, 0x0c, 0xb0, 0xbd, 0xf6, 0x0f, 0xd3, 0x16, 0xd3, 0xbc, 0xfa,
++  0x2b, 0xa5, 0x51, 0x38, 0x5d, 0xf5, 0xfb, 0xba, 0xdb, 0x78, 0x02, 0xdb, 0xff,
++  0xec, 0x0a, 0x1b, 0x96, 0xd5, 0x83, 0xb8, 0x19, 0x13, 0xe9, 0xb6, 0xc0, 0x7b,
++  0x40, 0x7b, 0xe1, 0x1f, 0x28, 0x27, 0xc9, 0xfa, 0xef, 0x56, 0x5e, 0x1c, 0xe6,
++  0x7e, 0x94, 0x7e, 0xc0, 0xf0, 0x44, 0xb2, 0x79, 0x39, 0xe5, 0xda, 0xb2, 0x62,
++  0x8b, 0x4d, 0xbf, 0x38, 0x70, 0xe2, 0x68, 0x24, 0x14, 0xc9, 0x33, 0xa4, 0x08,
++  0x37, 0xd5, 0x58, 0x69, 0x5e, 0xd3, 0x7c, 0xed, 0xc1, 0x04, 0x53, 0x08, 0xe7,
++  0x4e, 0xb0, 0x2a, 0x87, 0x63, 0x08, 0x61, 0x6f, 0x63, 0x15, 0x59, 0xea, 0xb2,
++  0x2b, 0x79, 0xd7, 0x0c, 0x61, 0x67, 0x8a, 0x5b, 0xfd, 0x5e, 0xad, 0x87, 0x7f,
++  0xba, 0x86, 0x67, 0x4f, 0x71, 0x58, 0x12, 0x22, 0x04, 0x22, 0x22, 0xce, 0x8b,
++  0xef, 0x54, 0x71, 0x00, 0xce, 0x50, 0x35, 0x58, 0x76, 0x95, 0x08, 0xee, 0x6a,
++  0xb1, 0xa2, 0x01, 0xd5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x76,
++  0x30, 0x82, 0x01, 0x72, 0x30, 0x12, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01,
++  0x82, 0x37, 0x15, 0x01, 0x04, 0x05, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x23,
++  0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x02, 0x04, 0x16,
++  0x04, 0x14, 0xf8, 0xc1, 0x6b, 0xb7, 0x7f, 0x77, 0x53, 0x4a, 0xf3, 0x25, 0x37,
++  0x1d, 0x4e, 0xa1, 0x26, 0x7b, 0x0f, 0x20, 0x70, 0x80, 0x30, 0x1d, 0x06, 0x03,
++  0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x13, 0xad, 0xbf, 0x43, 0x09, 0xbd,
++  0x82, 0x70, 0x9c, 0x8c, 0xd5, 0x4f, 0x31, 0x6e, 0xd5, 0x22, 0x98, 0x8a, 0x1b,
++  0xd4, 0x30, 0x19, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14,
++  0x02, 0x04, 0x0c, 0x1e, 0x0a, 0x00, 0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43,
++  0x00, 0x41, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02,
++  0x01, 0x86, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04,
++  0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23,
++  0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x45, 0x66, 0x52, 0x43, 0xe1, 0x7e, 0x58,
++  0x11, 0xbf, 0xd6, 0x4e, 0x9e, 0x23, 0x55, 0x08, 0x3b, 0x3a, 0x22, 0x6a, 0xa8,
++  0x30, 0x5c, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x55, 0x30, 0x53, 0x30, 0x51,
++  0xa0, 0x4f, 0xa0, 0x4d, 0x86, 0x4b, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
++  0x63, 0x72, 0x6c, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74,
++  0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x63, 0x72, 0x6c, 0x2f,
++  0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x2f, 0x4d, 0x69, 0x63, 0x43,
++  0x6f, 0x72, 0x54, 0x68, 0x69, 0x50, 0x61, 0x72, 0x4d, 0x61, 0x72, 0x52, 0x6f,
++  0x6f, 0x5f, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x30, 0x2d, 0x30, 0x35, 0x2e,
++  0x63, 0x72, 0x6c, 0x30, 0x60, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
++  0x01, 0x01, 0x04, 0x54, 0x30, 0x52, 0x30, 0x50, 0x06, 0x08, 0x2b, 0x06, 0x01,
++  0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x44, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
++  0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66,
++  0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x63, 0x65, 0x72,
++  0x74, 0x73, 0x2f, 0x4d, 0x69, 0x63, 0x43, 0x6f, 0x72, 0x54, 0x68, 0x69, 0x50,
++  0x61, 0x72, 0x4d, 0x61, 0x72, 0x52, 0x6f, 0x6f, 0x5f, 0x32, 0x30, 0x31, 0x30,
++  0x2d, 0x31, 0x30, 0x2d, 0x30, 0x35, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06,
++  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
++  0x82, 0x02, 0x01, 0x00, 0x35, 0x08, 0x42, 0xff, 0x30, 0xcc, 0xce, 0xf7, 0x76,
++  0x0c, 0xad, 0x10, 0x68, 0x58, 0x35, 0x29, 0x46, 0x32, 0x76, 0x27, 0x7c, 0xef,
++  0x12, 0x41, 0x27, 0x42, 0x1b, 0x4a, 0xaa, 0x6d, 0x81, 0x38, 0x48, 0x59, 0x13,
++  0x55, 0xf3, 0xe9, 0x58, 0x34, 0xa6, 0x16, 0x0b, 0x82, 0xaa, 0x5d, 0xad, 0x82,
++  0xda, 0x80, 0x83, 0x41, 0x06, 0x8f, 0xb4, 0x1d, 0xf2, 0x03, 0xb9, 0xf3, 0x1a,
++  0x5d, 0x1b, 0xf1, 0x50, 0x90, 0xf9, 0xb3, 0x55, 0x84, 0x42, 0x28, 0x1c, 0x20,
++  0xbd, 0xb2, 0xae, 0x51, 0x14, 0xc5, 0xc0, 0xac, 0x97, 0x95, 0x21, 0x1c, 0x90,
++  0xdb, 0x0f, 0xfc, 0x77, 0x9e, 0x95, 0x73, 0x91, 0x88, 0xca, 0xbd, 0xbd, 0x52,
++  0xb9, 0x05, 0x50, 0x0d, 0xdf, 0x57, 0x9e, 0xa0, 0x61, 0xed, 0x0d, 0xe5, 0x6d,
++  0x25, 0xd9, 0x40, 0x0f, 0x17, 0x40, 0xc8, 0xce, 0xa3, 0x4a, 0xc2, 0x4d, 0xaf,
++  0x9a, 0x12, 0x1d, 0x08, 0x54, 0x8f, 0xbd, 0xc7, 0xbc, 0xb9, 0x2b, 0x3d, 0x49,
++  0x2b, 0x1f, 0x32, 0xfc, 0x6a, 0x21, 0x69, 0x4f, 0x9b, 0xc8, 0x7e, 0x42, 0x34,
++  0xfc, 0x36, 0x06, 0x17, 0x8b, 0x8f, 0x20, 0x40, 0xc0, 0xb3, 0x9a, 0x25, 0x75,
++  0x27, 0xcd, 0xc9, 0x03, 0xa3, 0xf6, 0x5d, 0xd1, 0xe7, 0x36, 0x54, 0x7a, 0xb9,
++  0x50, 0xb5, 0xd3, 0x12, 0xd1, 0x07, 0xbf, 0xbb, 0x74, 0xdf, 0xdc, 0x1e, 0x8f,
++  0x80, 0xd5, 0xed, 0x18, 0xf4, 0x2f, 0x14, 0x16, 0x6b, 0x2f, 0xde, 0x66, 0x8c,
++  0xb0, 0x23, 0xe5, 0xc7, 0x84, 0xd8, 0xed, 0xea, 0xc1, 0x33, 0x82, 0xad, 0x56,
++  0x4b, 0x18, 0x2d, 0xf1, 0x68, 0x95, 0x07, 0xcd, 0xcf, 0xf0, 0x72, 0xf0, 0xae,
++  0xbb, 0xdd, 0x86, 0x85, 0x98, 0x2c, 0x21, 0x4c, 0x33, 0x2b, 0xf0, 0x0f, 0x4a,
++  0xf0, 0x68, 0x87, 0xb5, 0x92, 0x55, 0x32, 0x75, 0xa1, 0x6a, 0x82, 0x6a, 0x3c,
++  0xa3, 0x25, 0x11, 0xa4, 0xed, 0xad, 0xd7, 0x04, 0xae, 0xcb, 0xd8, 0x40, 0x59,
++  0xa0, 0x84, 0xd1, 0x95, 0x4c, 0x62, 0x91, 0x22, 0x1a, 0x74, 0x1d, 0x8c, 0x3d,
++  0x47, 0x0e, 0x44, 0xa6, 0xe4, 0xb0, 0x9b, 0x34, 0x35, 0xb1, 0xfa, 0xb6, 0x53,
++  0xa8, 0x2c, 0x81, 0xec, 0xa4, 0x05, 0x71, 0xc8, 0x9d, 0xb8, 0xba, 0xe8, 0x1b,
++  0x44, 0x66, 0xe4, 0x47, 0x54, 0x0e, 0x8e, 0x56, 0x7f, 0xb3, 0x9f, 0x16, 0x98,
++  0xb2, 0x86, 0xd0, 0x68, 0x3e, 0x90, 0x23, 0xb5, 0x2f, 0x5e, 0x8f, 0x50, 0x85,
++  0x8d, 0xc6, 0x8d, 0x82, 0x5f, 0x41, 0xa1, 0xf4, 0x2e, 0x0d, 0xe0, 0x99, 0xd2,
++  0x6c, 0x75, 0xe4, 0xb6, 0x69, 0xb5, 0x21, 0x86, 0xfa, 0x07, 0xd1, 0xf6, 0xe2,
++  0x4d, 0xd1, 0xda, 0xad, 0x2c, 0x77, 0x53, 0x1e, 0x25, 0x32, 0x37, 0xc7, 0x6c,
++  0x52, 0x72, 0x95, 0x86, 0xb0, 0xf1, 0x35, 0x61, 0x6a, 0x19, 0xf5, 0xb2, 0x3b,
++  0x81, 0x50, 0x56, 0xa6, 0x32, 0x2d, 0xfe, 0xa2, 0x89, 0xf9, 0x42, 0x86, 0x27,
++  0x18, 0x55, 0xa1, 0x82, 0xca, 0x5a, 0x9b, 0xf8, 0x30, 0x98, 0x54, 0x14, 0xa6,
++  0x47, 0x96, 0x25, 0x2f, 0xc8, 0x26, 0xe4, 0x41, 0x94, 0x1a, 0x5c, 0x02, 0x3f,
++  0xe5, 0x96, 0xe3, 0x85, 0x5b, 0x3c, 0x3e, 0x3f, 0xbb, 0x47, 0x16, 0x72, 0x55,
++  0xe2, 0x25, 0x22, 0xb1, 0xd9, 0x7b, 0xe7, 0x03, 0x06, 0x2a, 0xa3, 0xf7, 0x1e,
++  0x90, 0x46, 0xc3, 0x00, 0x0d, 0xd6, 0x19, 0x89, 0xe3, 0x0e, 0x35, 0x27, 0x62,
++  0x03, 0x71, 0x15, 0xa6, 0xef, 0xd0, 0x27, 0xa0, 0xa0, 0x59, 0x37, 0x60, 0xf8,
++  0x38, 0x94, 0xb8, 0xe0, 0x78, 0x70, 0xf8, 0xba, 0x4c, 0x86, 0x87, 0x94, 0xf6,
++  0xe0, 0xae, 0x02, 0x45, 0xee, 0x65, 0xc2, 0xb6, 0xa3, 0x7e, 0x69, 0x16, 0x75,
++  0x07, 0x92, 0x9b, 0xf5, 0xa6, 0xbc, 0x59, 0x83, 0x58
++};
++
++//
++// The most important thing about the variable payload is that it is a list of
++// lists, where the element size of any given *inner* list is constant.
++//
++// Since X509 certificates vary in size, each of our *inner* lists will contain
++// one element only (one X.509 certificate). This is explicitly mentioned in
++// the UEFI specification, in "28.4.1 Signature Database", in a Note.
++//
++// The list structure looks as follows:
++//
++// struct EFI_VARIABLE_AUTHENTICATION_2 {                           |
++//   struct EFI_TIME {                                              |
++//     UINT16 Year;                                                 |
++//     UINT8  Month;                                                |
++//     UINT8  Day;                                                  |
++//     UINT8  Hour;                                                 |
++//     UINT8  Minute;                                               |
++//     UINT8  Second;                                               |
++//     UINT8  Pad1;                                                 |
++//     UINT32 Nanosecond;                                           |
++//     INT16  TimeZone;                                             |
++//     UINT8  Daylight;                                             |
++//     UINT8  Pad2;                                                 |
++//   } TimeStamp;                                                   |
++//                                                                  |
++//   struct WIN_CERTIFICATE_UEFI_GUID {                           | |
++//     struct WIN_CERTIFICATE {                                   | |
++//       UINT32 dwLength; ----------------------------------------+ |
++//       UINT16 wRevision;                                        | |
++//       UINT16 wCertificateType;                                 | |
++//     } Hdr;                                                     | +- DataSize
++//                                                                | |
++//     EFI_GUID CertType;                                         | |
++//     UINT8    CertData[1] = { <--- "struct hack"                | |
++//       struct EFI_SIGNATURE_LIST {                            | | |
++//         EFI_GUID SignatureType;                              | | |
++//         UINT32   SignatureListSize; -------------------------+ | |
++//         UINT32   SignatureHeaderSize;                        | | |
++//         UINT32   SignatureSize; ---------------------------+ | | |
++//         UINT8    SignatureHeader[SignatureHeaderSize];     | | | |
++//                                                            v | | |
++//         struct EFI_SIGNATURE_DATA {                        | | | |
++//           EFI_GUID SignatureOwner;                         | | | |
++//           UINT8    SignatureData[1] = { <--- "struct hack" | | | |
++//             X.509 payload                                  | | | |
++//           }                                                | | | |
++//         } Signatures[];                                      | | |
++//       } SigLists[];                                            | |
++//     };                                                         | |
++//   } AuthInfo;                                                  | |
++// };                                                               |
++//
++// Given that the "struct hack" invokes undefined behavior (which is why C99
++// introduced the flexible array member), and because subtracting those pesky
++// sizes of 1 is annoying, and because the format is fully specified in the
++// UEFI specification, we'll introduce two matching convenience structures that
++// are customized for our X.509 purposes.
++//
++#pragma pack(1)
++typedef struct {
++  EFI_TIME TimeStamp;
++
++  //
++  // dwLength covers data below
++  //
++  UINT32   dwLength;
++  UINT16   wRevision;
++  UINT16   wCertificateType;
++  EFI_GUID CertType;
++} SINGLE_HEADER;
++
++typedef struct {
++  //
++  // SignatureListSize covers data below
++  //
++  EFI_GUID SignatureType;
++  UINT32   SignatureListSize;
++  UINT32   SignatureHeaderSize; // constant 0
++  UINT32   SignatureSize;
++
++  //
++  // SignatureSize covers data below
++  //
++  EFI_GUID SignatureOwner;
++
++  //
++  // X.509 certificate follows
++  //
++} REPEATING_HEADER;
++#pragma pack()
++
++/**
++  Enroll a set of DER-formatted X.509 certificates in a global variable,
++  overwriting it.
++
++  The variable will be rewritten with NV+BS+RT+AT attributes.
++
++  @param[in] VariableName  The name of the variable to overwrite.
++
++  @param[in] VendorGuid    The namespace (ie. vendor GUID) of the variable to
++                           overwrite.
++
++  @param[in] ...           A list of
++
++                             IN CONST UINT8    *Cert,
++                             IN UINTN          CertSize,
++                             IN CONST EFI_GUID *OwnerGuid
++
++                           triplets. If the first component of a triplet is
++                           NULL, then the other two components are not
++                           accessed, and processing is terminated. The list of
++                           X.509 certificates is enrolled in the variable
++                           specified, overwriting it. The OwnerGuid component
++                           identifies the agent installing the certificate.
++
++  @retval EFI_INVALID_PARAMETER  The triplet list is empty (ie. the first Cert
++                                 value is NULL), or one of the CertSize values
++                                 is 0, or one of the CertSize values would
++                                 overflow the accumulated UINT32 data size.
++
++  @retval EFI_OUT_OF_RESOURCES   Out of memory while formatting variable
++                                 payload.
++
++  @retval EFI_SUCCESS            Enrollment successful; the variable has been
++                                 overwritten (or created).
++
++  @return                        Error codes from gRT->GetTime() and
++                                 gRT->SetVariable().
++**/
++STATIC
++EFI_STATUS
++EFIAPI
++EnrollListOfX509Certs (
++  IN CHAR16   *VariableName,
++  IN EFI_GUID *VendorGuid,
++  ...
++  )
++{
++  UINTN            DataSize;
++  SINGLE_HEADER    *SingleHeader;
++  REPEATING_HEADER *RepeatingHeader;
++  VA_LIST          Marker;
++  CONST UINT8      *Cert;
++  EFI_STATUS       Status;
++  UINT8            *Data;
++  UINT8            *Position;
++
++  //
++  // compute total size first, for UINT32 range check, and allocation
++  //
++  DataSize = sizeof *SingleHeader;
++  VA_START (Marker, VendorGuid);
++  for (Cert = VA_ARG (Marker, CONST UINT8 *);
++       Cert != NULL;
++       Cert = VA_ARG (Marker, CONST UINT8 *)) {
++    UINTN          CertSize;
++
++    CertSize = VA_ARG (Marker, UINTN);
++    (VOID)VA_ARG (Marker, CONST EFI_GUID *);
++
++    if (CertSize == 0 ||
++        CertSize > MAX_UINT32 - sizeof *RepeatingHeader ||
++        DataSize > MAX_UINT32 - sizeof *RepeatingHeader - CertSize) {
++      Status = EFI_INVALID_PARAMETER;
++      break;
++    }
++    DataSize += sizeof *RepeatingHeader + CertSize;
++  }
++  VA_END (Marker);
++
++  if (DataSize == sizeof *SingleHeader) {
++    Status = EFI_INVALID_PARAMETER;
++  }
++  if (EFI_ERROR (Status)) {
++    goto Out;
++  }
++
++  Data = AllocatePool (DataSize);
++  if (Data == NULL) {
++    Status = EFI_OUT_OF_RESOURCES;
++    goto Out;
++  }
++
++  Position = Data;
++
++  SingleHeader = (SINGLE_HEADER *)Position;
++  Status = gRT->GetTime (&SingleHeader->TimeStamp, NULL);
++  if (EFI_ERROR (Status)) {
++    goto FreeData;
++  }
++  SingleHeader->TimeStamp.Pad1       = 0;
++  SingleHeader->TimeStamp.Nanosecond = 0;
++  SingleHeader->TimeStamp.TimeZone   = 0;
++  SingleHeader->TimeStamp.Daylight   = 0;
++  SingleHeader->TimeStamp.Pad2       = 0;
++#if 0
++  SingleHeader->dwLength         = DataSize - sizeof SingleHeader->TimeStamp;
++#else
++  //
++  // This looks like a bug in edk2. According to the UEFI specification,
++  // dwLength is "The length of the entire certificate, including the length of
++  // the header, in bytes". That shouldn't stop right after CertType -- it
++  // should include everything below it.
++  //
++  SingleHeader->dwLength         = sizeof *SingleHeader
++                                     - sizeof SingleHeader->TimeStamp;
++#endif
++  SingleHeader->wRevision        = 0x0200;
++  SingleHeader->wCertificateType = WIN_CERT_TYPE_EFI_GUID;
++  CopyGuid (&SingleHeader->CertType, &gEfiCertPkcs7Guid);
++  Position += sizeof *SingleHeader;
++
++  VA_START (Marker, VendorGuid);
++  for (Cert = VA_ARG (Marker, CONST UINT8 *);
++       Cert != NULL;
++       Cert = VA_ARG (Marker, CONST UINT8 *)) {
++    UINTN            CertSize;
++    CONST EFI_GUID   *OwnerGuid;
++
++    CertSize  = VA_ARG (Marker, UINTN);
++    OwnerGuid = VA_ARG (Marker, CONST EFI_GUID *);
++
++    RepeatingHeader = (REPEATING_HEADER *)Position;
++    CopyGuid (&RepeatingHeader->SignatureType, &gEfiCertX509Guid);
++    RepeatingHeader->SignatureListSize   = sizeof *RepeatingHeader + CertSize;
++    RepeatingHeader->SignatureHeaderSize = 0;
++    RepeatingHeader->SignatureSize       =
++      sizeof RepeatingHeader->SignatureOwner + CertSize;
++    CopyGuid (&RepeatingHeader->SignatureOwner, OwnerGuid);
++    Position += sizeof *RepeatingHeader;
++
++    CopyMem (Position, Cert, CertSize);
++    Position += CertSize;
++  }
++  VA_END (Marker);
++
++  ASSERT (Data + DataSize == Position);
++
++  Status = gRT->SetVariable (VariableName, VendorGuid,
++                  (EFI_VARIABLE_NON_VOLATILE |
++                   EFI_VARIABLE_BOOTSERVICE_ACCESS |
++                   EFI_VARIABLE_RUNTIME_ACCESS |
++                   EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS),
++                  DataSize, Data);
++
++FreeData:
++  FreePool (Data);
++
++Out:
++  if (EFI_ERROR (Status)) {
++    AsciiPrint ("error: %a(\"%s\", %g): %r\n", __FUNCTION__, VariableName,
++      VendorGuid, Status);
++  }
++  return Status;
++}
++
++
++STATIC
++EFI_STATUS
++EFIAPI
++GetExact (
++  IN CHAR16   *VariableName,
++  IN EFI_GUID *VendorGuid,
++  OUT VOID    *Data,
++  IN UINTN    DataSize,
++  IN BOOLEAN  AllowMissing
++  )
++{
++  UINTN      Size;
++  EFI_STATUS Status;
++
++  Size = DataSize;
++  Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &Size, Data);
++  if (EFI_ERROR (Status)) {
++    if (Status == EFI_NOT_FOUND && AllowMissing) {
++      ZeroMem (Data, DataSize);
++      return EFI_SUCCESS;
++    }
++
++    AsciiPrint ("error: GetVariable(\"%s\", %g): %r\n", VariableName,
++      VendorGuid, Status);
++    return Status;
++  }
++
++  if (Size != DataSize) {
++    AsciiPrint ("error: GetVariable(\"%s\", %g): expected size 0x%Lx, "
++      "got 0x%Lx\n", VariableName, VendorGuid, (UINT64)DataSize, (UINT64)Size);
++    return EFI_PROTOCOL_ERROR;
++  }
++
++  return EFI_SUCCESS;
++}
++
++typedef struct {
++  UINT8 SetupMode;
++  UINT8 SecureBoot;
++  UINT8 SecureBootEnable;
++  UINT8 CustomMode;
++  UINT8 VendorKeys;
++} SETTINGS;
++
++STATIC
++EFI_STATUS
++EFIAPI
++GetSettings (
++  OUT SETTINGS *Settings
++  )
++{
++  EFI_STATUS Status;
++
++  Status = GetExact (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid,
++             &Settings->SetupMode, sizeof Settings->SetupMode, FALSE);
++  if (EFI_ERROR (Status)) {
++    return Status;
++  }
++
++  Status = GetExact (EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid,
++             &Settings->SecureBoot, sizeof Settings->SecureBoot, FALSE);
++  if (EFI_ERROR (Status)) {
++    return Status;
++  }
++
++  Status = GetExact (EFI_SECURE_BOOT_ENABLE_NAME,
++             &gEfiSecureBootEnableDisableGuid, &Settings->SecureBootEnable,
++             sizeof Settings->SecureBootEnable, TRUE);
++  if (EFI_ERROR (Status)) {
++    return Status;
++  }
++
++  Status = GetExact (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid,
++             &Settings->CustomMode, sizeof Settings->CustomMode, FALSE);
++  if (EFI_ERROR (Status)) {
++    return Status;
++  }
++
++  Status = GetExact (EFI_VENDOR_KEYS_VARIABLE_NAME, &gEfiGlobalVariableGuid,
++             &Settings->VendorKeys, sizeof Settings->VendorKeys, FALSE);
++  return Status;
++}
++
++STATIC
++VOID
++EFIAPI
++PrintSettings (
++  IN CONST SETTINGS *Settings
++  )
++{
++  AsciiPrint ("info: SetupMode=%d SecureBoot=%d SecureBootEnable=%d "
++    "CustomMode=%d VendorKeys=%d\n", Settings->SetupMode, Settings->SecureBoot,
++    Settings->SecureBootEnable, Settings->CustomMode, Settings->VendorKeys);
++}
++
++
++INTN
++EFIAPI
++ShellAppMain (
++  IN UINTN  Argc,
++  IN CHAR16 **Argv
++  )
++{
++  EFI_STATUS Status;
++  SETTINGS   Settings;
++
++  Status = GetSettings (&Settings);
++  if (EFI_ERROR (Status)) {
++    return 1;
++  }
++  PrintSettings (&Settings);
++
++  if (Settings.SetupMode != 1) {
++    AsciiPrint ("error: already in User Mode\n");
++    return 1;
++  }
++
++  if (Settings.CustomMode != CUSTOM_SECURE_BOOT_MODE) {
++    Settings.CustomMode = CUSTOM_SECURE_BOOT_MODE;
++    Status = gRT->SetVariable (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid,
++                    (EFI_VARIABLE_NON_VOLATILE |
++                     EFI_VARIABLE_BOOTSERVICE_ACCESS),
++                    sizeof Settings.CustomMode, &Settings.CustomMode);
++    if (EFI_ERROR (Status)) {
++      AsciiPrint ("error: SetVariable(\"%s\", %g): %r\n", EFI_CUSTOM_MODE_NAME,
++        &gEfiCustomModeEnableGuid, Status);
++      return 1;
++    }
++  }
++
++  Status = EnrollListOfX509Certs (
++             EFI_IMAGE_SECURITY_DATABASE,
++             &gEfiImageSecurityDatabaseGuid,
++             MicrosoftPCA,    sizeof MicrosoftPCA,    &gEfiCallerIdGuid,
++             MicrosoftUefiCA, sizeof MicrosoftUefiCA, &gEfiCallerIdGuid,
++             NULL);
++  if (EFI_ERROR (Status)) {
++    return 1;
++  }
++
++  Status = EnrollListOfX509Certs (
++             EFI_KEY_EXCHANGE_KEY_NAME,
++             &gEfiGlobalVariableGuid,
++             ExampleCert,  sizeof ExampleCert,  &gEfiCallerIdGuid,
++             MicrosoftKEK, sizeof MicrosoftKEK, &gEfiCallerIdGuid,
++             NULL);
++  if (EFI_ERROR (Status)) {
++    return 1;
++  }
++
++  Status = EnrollListOfX509Certs (
++             EFI_PLATFORM_KEY_NAME,
++             &gEfiGlobalVariableGuid,
++             ExampleCert, sizeof ExampleCert, &gEfiGlobalVariableGuid,
++             NULL);
++  if (EFI_ERROR (Status)) {
++    return 1;
++  }
++
++  Settings.CustomMode = STANDARD_SECURE_BOOT_MODE;
++  Status = gRT->SetVariable (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid,
++                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
++                  sizeof Settings.CustomMode, &Settings.CustomMode);
++  if (EFI_ERROR (Status)) {
++    AsciiPrint ("error: SetVariable(\"%s\", %g): %r\n", EFI_CUSTOM_MODE_NAME,
++      &gEfiCustomModeEnableGuid, Status);
++    return 1;
++  }
++
++  Status = GetSettings (&Settings);
++  if (EFI_ERROR (Status)) {
++    return 1;
++  }
++  PrintSettings (&Settings);
++
++  if (Settings.SetupMode != 0 || Settings.SecureBoot != 1 ||
++      Settings.SecureBootEnable != 1 || Settings.CustomMode != 0 ||
++      Settings.VendorKeys != 0) {
++    AsciiPrint ("error: unexpected\n");
++    return 1;
++  }
++
++  AsciiPrint ("info: success\n");
++  return 0;
++}
+diff --git a/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf b/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf
+new file mode 100644
+index 000000000000..30c127f2ecb4
+--- /dev/null
++++ b/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf
+@@ -0,0 +1,51 @@
++## @file
++#  Enroll default PK, KEK, DB.
++#
++#  Copyright (C) 2014, Red Hat, Inc.
++#
++#  This program and the accompanying materials are licensed and made available
++#  under the terms and conditions of the BSD License which accompanies this
++#  distribution. The full text of the license may be found at
++#  http://opensource.org/licenses/bsd-license.
++#
++#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
++#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
++#  IMPLIED.
++##
++
++[Defines]
++  INF_VERSION                    = 0x00010006
++  BASE_NAME                      = EnrollDefaultKeys
++  FILE_GUID                      = D5C1DF0B-1BAC-4EDF-BA48-08834009CA5A
++  MODULE_TYPE                    = UEFI_APPLICATION
++  VERSION_STRING                 = 0.1
++  ENTRY_POINT                    = ShellCEntryLib
++
++#
++#  VALID_ARCHITECTURES           = IA32 X64
++#
++
++[Sources]
++  EnrollDefaultKeys.c
++
++[Packages]
++  MdePkg/MdePkg.dec
++  MdeModulePkg/MdeModulePkg.dec
++  SecurityPkg/SecurityPkg.dec
++  ShellPkg/ShellPkg.dec
++
++[Guids]
++  gEfiCertPkcs7Guid
++  gEfiCertX509Guid
++  gEfiCustomModeEnableGuid
++  gEfiGlobalVariableGuid
++  gEfiImageSecurityDatabaseGuid
++  gEfiSecureBootEnableDisableGuid
++
++[LibraryClasses]
++  BaseMemoryLib
++  DebugLib
++  MemoryAllocationLib
++  ShellCEntryLib
++  UefiLib
++  UefiRuntimeServicesTableLib
+diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
+index 012e24817e5a..1e0e71aea606 100644
+--- a/OvmfPkg/OvmfPkgIa32.dsc
++++ b/OvmfPkg/OvmfPkgIa32.dsc
+@@ -743,6 +743,10 @@ [Components]
+ 
+ !if $(SECURE_BOOT_ENABLE) == TRUE
+   SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
++  OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf {
++    <LibraryClasses>
++      ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
++  }
+ !endif
+ 
+   OvmfPkg/PlatformDxe/Platform.inf
+diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
+index 23c09d1e6083..6346f2db0006 100644
+--- a/OvmfPkg/OvmfPkgIa32X64.dsc
++++ b/OvmfPkg/OvmfPkgIa32X64.dsc
+@@ -752,6 +752,10 @@ [Components.X64]
+ 
+ !if $(SECURE_BOOT_ENABLE) == TRUE
+   SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
++  OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf {
++    <LibraryClasses>
++      ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
++  }
+ !endif
+ 
+   OvmfPkg/PlatformDxe/Platform.inf
+diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
+index b0b6b3770e84..7a0d7eb7a75f 100644
+--- a/OvmfPkg/OvmfPkgX64.dsc
++++ b/OvmfPkg/OvmfPkgX64.dsc
+@@ -750,6 +750,10 @@ [Components]
+ 
+ !if $(SECURE_BOOT_ENABLE) == TRUE
+   SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
++  OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf {
++    <LibraryClasses>
++      ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
++  }
+ !endif
+ 
+   OvmfPkg/PlatformDxe/Platform.inf
+-- 
+1.8.3.1
+
diff --git a/0001-OvmfPkg-SmbiosPlatformDxe-install-legacy-QEMU-tables.patch b/0001-OvmfPkg-SmbiosPlatformDxe-install-legacy-QEMU-tables.patch
new file mode 100644
index 0000000..43fa070
--- /dev/null
+++ b/0001-OvmfPkg-SmbiosPlatformDxe-install-legacy-QEMU-tables.patch
@@ -0,0 +1,1084 @@
+From 0e182f2305a84fdf62ff2631de6e363a5a881287 Mon Sep 17 00:00:00 2001
+From: Laszlo Ersek <lersek@redhat.com>
+Date: Wed, 5 Jun 2013 10:14:34 +0200
+Subject: [PATCH 1/3] OvmfPkg/SmbiosPlatformDxe: install legacy QEMU tables and
+ save fields (X86)
+
+Introduce basic legacy SMBIOS machinery for the QEMU platform:
+- Install SMBIOS tables that QEMU passes down in complete form via fw_cfg.
+- Stash individual fields that QEMU passes down to override the boot
+  firmware's default SMBIOS tables.
+- Add helper functions that OVMF's default SMBIOS tables will need.
+
+Contributed-under: TianoCore Contribution Agreement 1.0
+Signed-off-by: Laszlo Ersek <lersek@redhat.com>
+---
+ OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c          | 694 ++++++++++++++++++++++++
+ OvmfPkg/SmbiosPlatformDxe/QemuLegacy.h          |  52 ++
+ OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h  | 221 ++++++++
+ OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c   |  17 +-
+ OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf |   2 +
+ 5 files changed, 983 insertions(+), 3 deletions(-)
+ create mode 100644 OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c
+ create mode 100644 OvmfPkg/SmbiosPlatformDxe/QemuLegacy.h
+ create mode 100644 OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h
+
+diff --git a/OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c b/OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c
+new file mode 100644
+index 0000000..9c57558
+--- /dev/null
++++ b/OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c
+@@ -0,0 +1,694 @@
++/** @file
++  This file fetches and installs SMBIOS tables on the QEMU hypervisor.
++
++  Copyright (C) 2013, Red Hat, Inc.
++
++  This program and the accompanying materials are licensed and made available
++  under the terms and conditions of the BSD License which accompanies this
++  distribution.  The full text of the license may be found at
++  http://opensource.org/licenses/bsd-license.php
++
++  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
++  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
++**/
++
++#include <Library/MemoryAllocationLib.h>
++
++#include "QemuLegacy.h"
++#include "QemuLegacyInternal.h"
++
++
++//
++// An SMBIOS entry exported by QEMU over fw_cfg can have one of the following
++// types.
++//
++typedef enum
++{
++  ET_FIELD, // defines one field in some SMBIOS table
++  ET_TABLE  // defines an SMBIOS table instance in entirety
++} FW_CFG_SMBIOS_ENTRY_TYPE;
++
++//
++// Header type introducing each entry in the QemuFwCfgItemX86SmbiosTables
++// fw_cfg blob.
++//
++#pragma pack(1)
++typedef struct {
++  UINT16 Size; // including payload and this header
++  UINT8  Type; // value from FW_CFG_SMBIOS_ENTRY_TYPE
++} FW_CFG_SMBIOS_ENTRY_HDR;
++#pragma pack()
++
++//
++// Fields included at the beginning of the the payload in QEMU SMBIOS entries
++// with ET_FIELD type.
++//
++#pragma pack(1)
++typedef struct {
++  UINT8  TableType; // SMBIOS table type to patch
++  UINT16 Offset;    // offset of a field in the formatted area
++} FW_CFG_SMBIOS_FIELD;
++#pragma pack()
++
++
++/**
++  Initialize a context object tracking SMBIOS table installation and patches
++  for fields.
++
++  @param[out] Context  A BUILD_CONTEXT object allocated dynamically and
++                       initialized.
++
++  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
++  @retval EFI_SUCCESS           Allocation and initialization successful.
++**/
++STATIC
++EFI_STATUS
++EFIAPI
++InitSmbiosContext (
++  OUT BUILD_CONTEXT **Context
++  )
++{
++  *Context = AllocateZeroPool (sizeof **Context);
++  if (*Context == NULL) {
++    DEBUG ((DEBUG_ERROR, "%a: out of memory\n", __FUNCTION__));
++    return EFI_OUT_OF_RESOURCES;
++  }
++  return EFI_SUCCESS;
++}
++
++
++/**
++  Release a context object tracking SMBIOS table installation and patches for
++  fields.
++
++  @param[in,out] Context  The BUILD_CONTEXT object to tear down.
++**/
++STATIC
++VOID
++EFIAPI
++UninitSmbiosContext (
++  IN OUT BUILD_CONTEXT *Context
++  )
++{
++  INT32 Type;
++  INT32 Idx;
++
++  //
++  // free all patches
++  //
++  for (Type = 0; Type < TABLE_TYPE_LIMIT; ++Type) {
++    for (Idx = 0; Idx < PATCH_SUBSCRIPT_LIMIT; ++Idx) {
++      PATCH *Patch;
++
++      Patch = &Context->Table[Type].Patch[Idx];
++      if (Patch->Base != NULL) {
++        FreePool (Patch->Base);
++      }
++    }
++  }
++  FreePool (Context);
++}
++
++
++/**
++  Save a patch targeting an SMBIOS field in dynamically allocated memory.
++
++  @param[in,out] Context      The initialized BUILD_CONTEXT object to save the
++                              patch in.
++  @param[in]     TableType    The patch to be saved targets this table type.
++                              Patches for table types equal to or greater than
++                              TABLE_TYPE_LIMIT are ignored.
++  @param[in]     FieldOffset  The patch to be saved targets the field that
++                              begins at offset FieldOffset in SMBIOS table type
++                              TableType. FieldOffset is enforced not to point
++                              into the SMBIOS table header. A FieldOffset value
++                              equal to or greater than 255 is rejected, since
++                              the formatted area of an SMBIOS table never
++                              exceeds 255 bytes. FieldOffset is not validated
++                              against actual field offsets here, it is only
++                              saved for later lookup.
++  @param[in]     PatchData    Byte array constituting the patch body.
++  @param[in]     PatchSize    Number of bytes in PatchData.
++
++  @retval EFI_SUCCESS            Patch has been either ignored due to not
++                                 meeting the criterion on TableType, or it has
++                                 been saved successfully.
++  @retval EFI_INVALID_PARAMETER  FieldOffset is invalid.
++  @retval EFI_OUT_OF_RESOURCES   Couldn't allocate memory for the patch.
++**/
++STATIC
++EFI_STATUS
++EFIAPI
++SaveSmbiosPatch (
++  IN OUT BUILD_CONTEXT *Context,
++  IN     UINT8         TableType,
++  IN     UINT16        FieldOffset,
++  IN     UINT8         *PatchData,
++  IN     UINT16        PatchSize
++)
++{
++  UINT8 *NewBase;
++  PATCH *Patch;
++
++  if (TableType >= TABLE_TYPE_LIMIT) {
++    DEBUG ((DEBUG_VERBOSE,
++      "%a: ignoring patch for unsupported table type %d\n",
++      __FUNCTION__, TableType));
++    return EFI_SUCCESS;
++  }
++
++  if (FieldOffset < FIELD_OFFSET_MINIMUM
++      || FieldOffset - FIELD_OFFSET_MINIMUM >= PATCH_SUBSCRIPT_LIMIT) {
++    DEBUG ((DEBUG_ERROR,
++      "%a: invalid patch for table type %d field offset %d\n",
++      __FUNCTION__, TableType, FieldOffset));
++    return EFI_INVALID_PARAMETER;
++  }
++
++  NewBase = AllocateCopyPool (PatchSize, PatchData);
++  if (PatchSize > 0 && NewBase == NULL) {
++    DEBUG ((DEBUG_ERROR, "%a: table type %d field offset %d: out of memory\n",
++      __FUNCTION__, TableType, FieldOffset));
++    return EFI_OUT_OF_RESOURCES;
++  }
++
++  Patch = &Context->Table[TableType].Patch[FieldOffset - FIELD_OFFSET_MINIMUM];
++  //
++  // replace previous patch if it exists
++  //
++  if (Patch->Base != NULL) {
++    DEBUG ((DEBUG_VERBOSE,
++      "%a: replacing prior patch for table type %d field offset %d\n",
++      __FUNCTION__, TableType, FieldOffset));
++    FreePool (Patch->Base);
++  }
++
++  Patch->Base = NewBase;
++  Patch->Size = PatchSize;
++  return EFI_SUCCESS;
++}
++
++
++/**
++  Apply a saved patch to a field located in the formatted are of a not yet
++  installed SMBIOS table.
++
++  The patch is looked up based on (Context, TableType, FieldOffset).
++
++  @param[in]  Context      The BUILD_CONTEXT object storing saved patches.
++  @param[in]  TableType    Selects the table type for which the patch has been
++                           saved. It is assumed that the caller has validated
++                           TableType against TABLE_TYPE_LIMIT (upper
++                           exclusive).
++  @param[in]  FieldOffset  Selects the SMBIOS field for which the patch has
++                           been saved. It is assumed that the caller has
++                           validated FieldOffset against FIELD_OFFSET_MINIMUM
++                           (lower inclusive) and 255 (upper exclusive).
++  @param[in]  FieldSize    The caller supplies the size of the field to patch
++                           in FieldSize. The patch saved for
++                           TableType:FieldOffset, if any, is only applied if
++                           its size equals FieldSize.
++  @param[out] TableBase    Base of the SMBIOS table of type TableType in which
++                           the field starting at FieldOffset needs to be
++                           patched.
++
++  @retval EFI_NOT_FOUND          No patch found for TableType:FieldOffset in
++                                 Context. This return value is considered
++                                 informative (ie. non-fatal).
++  @retval EFI_INVALID_PARAMETER  Patch found for TableType:FieldOffset, but its
++                                 size doesn't match FieldSize. This result is
++                                 considered a fatal error of the patch origin.
++  @retval EFI_SUCCESS            The SMBIOS table at TableBase has been patched
++                                 starting at FieldOffset for a length of
++                                 FieldSize.
++**/
++EFI_STATUS
++EFIAPI
++PatchSmbiosFormatted (
++  IN  BUILD_CONTEXT *Context,
++  IN  UINT8         TableType,
++  IN  UINT16        FieldOffset,
++  IN  UINT16        FieldSize,
++  OUT UINT8         *TableBase
++  )
++{
++  PATCH *Patch;
++
++  ASSERT (TableType < TABLE_TYPE_LIMIT);
++  ASSERT (FieldOffset >= FIELD_OFFSET_MINIMUM);
++  ASSERT (FieldOffset - FIELD_OFFSET_MINIMUM < PATCH_SUBSCRIPT_LIMIT);
++
++  Patch = &Context->Table[TableType].Patch[FieldOffset - FIELD_OFFSET_MINIMUM];
++  if (Patch->Base == NULL) {
++    return EFI_NOT_FOUND;
++  }
++
++  if (Patch->Size != FieldSize) {
++    DEBUG ((DEBUG_ERROR, "%a: table type %d, field offset %d: "
++      "patch size %d doesn't match field size %d\n",
++      __FUNCTION__, TableType, FieldOffset, Patch->Size, FieldSize));
++    return EFI_INVALID_PARAMETER;
++  }
++
++  CopyMem (TableBase + FieldOffset, Patch->Base, FieldSize);
++  return EFI_SUCCESS;
++}
++
++
++/**
++  Apply a saved patch to a text string located in the unformatted area of an
++  already installed SMBIOS table.
++
++  The patch is looked up based on (Context, TableType, FieldOffset).
++
++  @param[in]  Smbios        The EFI_SMBIOS_PROTOCOL instance used previously
++                            for installing the SMBIOS table.
++  @param[in]  SmbiosHandle  The EFI_SMBIOS_HANDLE previously returned by
++                            Smbios->Add().
++  @param[in]  Context       The BUILD_CONTEXT object storing saved patches.
++  @param[in]  TableType     Selects the table type for which the patch has been
++                            saved. It is assumed that the caller has validated
++                            TableType against TABLE_TYPE_LIMIT (upper
++                            exclusive).
++  @param[in]  FieldOffset   Selects the SMBIOS field for which the patch has
++                            been saved. It is assumed that the caller has
++                            validated FieldOffset against FIELD_OFFSET_MINIMUM
++                            (lower inclusive) and 255 (upper exclusive).
++                            It is also assumed that TableBase[FieldOffset]
++                            accesses a field of type SMBIOS_TABLE_STRING, ie. a
++                            field in the formatted area that identifies an
++                            existent text string in the unformatted area. Text
++                            string identifiers are one-based.
++  @param[out] TableBase     Base of the SMBIOS table of type TableType in which
++                            the SMBIOS_TABLE_STRING field at FieldOffset
++                            identifies the existent text string to update.
++
++  @retval EFI_NOT_FOUND          No patch found for TableType:FieldOffset in
++                                 Context. This return value is considered
++                                 informative (ie. non-fatal).
++  @retval EFI_INVALID_PARAMETER  Patch found for TableType:FieldOffset, but it
++                                 doesn't end with a NUL character. This result
++                                 is considered a fatal error of the patch
++                                 origin.
++  @retval EFI_SUCCESS            The text string identified by
++                                 TableBase[FieldOffset] has been replaced in
++                                 the installed SMBIOS table under SmbiosHandle.
++  @return                        Error codes returned by
++                                 Smbios->UpdateString(). EFI_NOT_FOUND shall
++                                 not be returned.
++**/
++EFI_STATUS
++EFIAPI
++PatchSmbiosUnformatted (
++  IN  EFI_SMBIOS_PROTOCOL *Smbios,
++  IN  EFI_SMBIOS_HANDLE   SmbiosHandle,
++  IN  BUILD_CONTEXT       *Context,
++  IN  UINT8               TableType,
++  IN  UINT16              FieldOffset,
++  IN  UINT8               *TableBase
++  )
++{
++  PATCH      *Patch;
++  UINTN      StringNumber;
++  EFI_STATUS Status;
++
++  ASSERT (TableType < TABLE_TYPE_LIMIT);
++  ASSERT (FieldOffset >= FIELD_OFFSET_MINIMUM);
++  ASSERT (FieldOffset - FIELD_OFFSET_MINIMUM < PATCH_SUBSCRIPT_LIMIT);
++
++  Patch = &Context->Table[TableType].Patch[FieldOffset - FIELD_OFFSET_MINIMUM];
++  if (Patch->Base == NULL) {
++    return EFI_NOT_FOUND;
++  }
++
++  if (Patch->Size == 0 || Patch->Base[Patch->Size - 1] != '\0') {
++    DEBUG ((DEBUG_ERROR, "%a: table type %d, field offset %d: "
++      "missing terminator, or trailing garbage\n",
++      __FUNCTION__, TableType, FieldOffset));
++    return EFI_INVALID_PARAMETER;
++  }
++
++  StringNumber = TableBase[FieldOffset];
++  ASSERT (StringNumber != 0);
++
++  Status = Smbios->UpdateString (Smbios, &SmbiosHandle, &StringNumber,
++                     (CHAR8 *)Patch->Base);
++  if (EFI_ERROR (Status)) {
++    ASSERT (Status != EFI_NOT_FOUND);
++    DEBUG ((DEBUG_ERROR, "%a: table type %d, field offset %d, "
++      "string number %d: Smbios->UpdateString(): %r\n", __FUNCTION__,
++      TableType, FieldOffset, TableBase[FieldOffset], Status));
++    return Status;
++  }
++  return EFI_SUCCESS;
++}
++
++
++/**
++  Process an SMBIOS firmware configuration entry with ET_FIELD type, exported
++  by QEMU under QemuFwCfgItemX86SmbiosTables.
++
++  Such entries describe patches to be saved with SaveSmbiosPatch().
++
++  @param[in,out] Context      The BUILD_CONTEXT object tracking saved patches.
++  @param[in]     Payload      Points to the buffer to parse as
++                              FW_CFG_SMBIOS_FIELD.
++  @param[in]     PayloadSize  Number of bytes in Payload.
++
++  @retval EFI_INVALID_PARAMETER  PayloadSize is less than the size of
++                                 FW_CFG_SMBIOS_FIELD -- fields describing
++                                 the patch are incomplete.
++  @retval EFI_SUCCESS            Payload has been parsed and patch has been
++                                 saved successfully.
++  @return                        Error codes returned by SaveSmbiosPatch().
++**/
++STATIC
++EFI_STATUS
++EFIAPI
++VisitSmbiosField (
++  IN OUT BUILD_CONTEXT *Context,
++  IN     UINT8         *Payload,
++  IN     UINT16        PayloadSize
++  )
++{
++  FW_CFG_SMBIOS_FIELD *Field;
++
++  if (PayloadSize < (INT32) sizeof *Field) {
++    DEBUG ((DEBUG_ERROR, "%a: required minimum size %d, available %d\n",
++      __FUNCTION__, (INT32) sizeof *Field, PayloadSize));
++    return EFI_INVALID_PARAMETER;
++  }
++
++  Field = (FW_CFG_SMBIOS_FIELD *) Payload;
++  return SaveSmbiosPatch (Context, Field->TableType, Field->Offset,
++           Payload + sizeof *Field, (UINT16) (PayloadSize - sizeof *Field));
++}
++
++
++/**
++  Process an SMBIOS firmware configuration entry with ET_TABLE type, exported
++  by QEMU under QemuFwCfgItemX86SmbiosTables.
++
++  Such entries describe entire SMBIOS table instances to install verbatim. This
++  module never overrides tables installed in this manner with default tables.
++
++  @param[in]     Smbios          The EFI_SMBIOS_PROTOCOL instance used for
++                                 installing SMBIOS tables.
++  @param[in]     ProducerHandle  Passed on to Smbios->Add(), ProducerHandle
++                                 tracks the origin of installed SMBIOS tables.
++  @param[in,out] Context         The BUILD_CONTEXT object tracking installed
++                                 tables.
++  @param[in]     Payload         Points to the buffer to install as an SMBIOS
++                                 table.
++  @param[in]     PayloadSize     Number of bytes in Payload.
++
++  @retval EFI_INVALID_PARAMETER  The buffer at Payload, interpreted as an
++                                 SMBIOS table, failed basic sanity checks.
++  @retval EFI_SUCCESS            Payload has been installed successfully as an
++                                 SMBIOS table.
++  @return                        Error codes returned by Smbios->Add().
++**/
++STATIC
++EFI_STATUS
++EFIAPI
++VisitSmbiosTable (
++  IN     EFI_SMBIOS_PROTOCOL *Smbios,
++  IN     EFI_HANDLE          ProducerHandle,
++  IN OUT BUILD_CONTEXT       *Context,
++  IN     UINT8               *Payload,
++  IN     UINT16              PayloadSize
++  )
++{
++  SMBIOS_STRUCTURE  *SmbiosHeader;
++  UINT16            MinimumSize;
++  EFI_SMBIOS_HANDLE SmbiosHandle;
++  EFI_STATUS        Status;
++
++  //
++  // Basic sanity checks only in order to help debugging and to catch blatantly
++  // invalid data passed with "-smbios file=binary_file" on the QEMU command
++  // line. Beyond these we don't enforce correct, type-specific SMBIOS table
++  // formatting.
++  //
++  if (PayloadSize < (INT32) sizeof *SmbiosHeader) {
++    DEBUG ((DEBUG_ERROR, "%a: required minimum size %d, available %d\n",
++      __FUNCTION__, (INT32) sizeof *SmbiosHeader, PayloadSize));
++    return EFI_INVALID_PARAMETER;
++  }
++
++  SmbiosHeader = (SMBIOS_STRUCTURE *) Payload;
++
++  if (SmbiosHeader->Length < (INT32) sizeof *SmbiosHeader) {
++    DEBUG ((DEBUG_ERROR, "%a: required minimum size %d, stated %d\n",
++      __FUNCTION__, (INT32) sizeof *SmbiosHeader, SmbiosHeader->Length));
++    return EFI_INVALID_PARAMETER;
++  }
++
++  MinimumSize = (UINT16) (SmbiosHeader->Length + 2);
++
++  if (PayloadSize < MinimumSize) {
++    DEBUG ((DEBUG_ERROR,
++      "%a: minimum for formatted area plus terminator is %d, available %d\n",
++      __FUNCTION__, MinimumSize, PayloadSize));
++    return EFI_INVALID_PARAMETER;
++  }
++
++  if (Payload[PayloadSize - 2] != '\0' ||
++      Payload[PayloadSize - 1] != '\0') {
++    DEBUG ((DEBUG_ERROR, "%a: missing terminator, or trailing garbage\n",
++      __FUNCTION__));
++    return EFI_INVALID_PARAMETER;
++  }
++
++  //
++  // request unique handle
++  //
++  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
++  Status = Smbios->Add (Smbios, ProducerHandle, &SmbiosHandle,
++                     (EFI_SMBIOS_TABLE_HEADER *) SmbiosHeader);
++  if (EFI_ERROR (Status)) {
++    DEBUG ((DEBUG_ERROR, "%a: Smbios->Add(): %r\n", __FUNCTION__, Status));
++    return Status;
++  }
++
++  //
++  // track known tables
++  //
++  if (SmbiosHeader->Type < TABLE_TYPE_LIMIT) {
++    Context->Table[SmbiosHeader->Type].Installed = TRUE;
++  }
++  return EFI_SUCCESS;
++}
++
++
++/**
++  Traverse the SMBIOS firmware configuration blob exported by QEMU under
++  QemuFwCfgItemX86SmbiosTables, processing each entry in turn.
++
++  Entries with ET_FIELD type are parsed as patches for the SMBIOS tables this
++  module installs as fallbacks, while entries of type ET_TABLE are parsed and
++  installed as verbatim SMBIOS tables.
++
++  Unknown entry types are silently skipped. Any error encountered during
++  traversal (for example, a recognized but malformed entry) aborts the
++  iteration, leaving the function with a possibly incomplete set of installed
++  tables.
++
++  @param[in]     Smbios          The EFI_SMBIOS_PROTOCOL instance used for
++                                 installing SMBIOS tables.
++  @param[in]     ProducerHandle  Passed on to Smbios->Add(), ProducerHandle
++                                 tracks the origin of installed SMBIOS tables.
++  @param[in,out] Context         The BUILD_CONTEXT object tracking installed
++                                 tables and saved patches.
++
++  @retval EFI_SUCCESS            The firmware configuration interface is
++                                 unavailable (no patches saved, no tables
++                                 installed).
++  @retval EFI_SUCCESS            Traversal complete. Tables provided by QEMU
++                                 have been installed. Patches have been saved
++                                 for any default tables that will be necessary.
++  @retval EFI_INVALID_PARAMETER  Encountered a corrupt entry in the SMBIOS
++                                 firmware configuration blob.
++  @retval EFI_OUT_OF_RESOURCES   Memory allocation failed.
++  @return                        Error codes returned by VisitSmbiosField() and
++                                 VisitSmbiosTable().
++**/
++STATIC
++EFI_STATUS
++EFIAPI
++ScanQemuSmbios (
++  IN     EFI_SMBIOS_PROTOCOL *Smbios,
++  IN     EFI_HANDLE          ProducerHandle,
++  IN OUT BUILD_CONTEXT       *Context
++  )
++{
++  EFI_STATUS Status;
++  UINT16     NumEntries;
++  UINT16     CurEntry;
++
++  Status = EFI_SUCCESS;
++
++  if (!QemuFwCfgIsAvailable ()) {
++    return Status;
++  }
++
++  QemuFwCfgSelectItem (QemuFwCfgItemX86SmbiosTables);
++
++  NumEntries = QemuFwCfgRead16 ();
++  for (CurEntry = 0; CurEntry < NumEntries && !EFI_ERROR (Status);
++       ++CurEntry) {
++    FW_CFG_SMBIOS_ENTRY_HDR Header;
++    UINT16                  PayloadSize;
++    UINT8                   *Payload;
++
++    QemuFwCfgReadBytes (sizeof Header, &Header);
++
++    if (Header.Size < (INT32) sizeof Header) {
++      DEBUG ((DEBUG_ERROR, "%a: invalid header size %d in entry %d\n",
++        __FUNCTION__, Header.Size, CurEntry));
++      return EFI_INVALID_PARAMETER;
++    }
++
++    PayloadSize = (UINT16) (Header.Size - sizeof Header);
++    Payload = AllocatePool (PayloadSize);
++
++    if (PayloadSize > 0 && Payload == NULL) {
++      DEBUG ((DEBUG_ERROR, "%a: failed to allocate %d bytes for entry %d\n",
++        __FUNCTION__, PayloadSize, CurEntry));
++      return EFI_OUT_OF_RESOURCES;
++    }
++
++    QemuFwCfgReadBytes (PayloadSize, Payload);
++
++    //
++    // dump the payload
++    //
++    DEBUG_CODE (
++      UINT16 Idx;
++
++      DEBUG ((DEBUG_VERBOSE,
++        "%a: entry %d, type %d, payload size %d, payload hex dump follows:",
++        __FUNCTION__, CurEntry, Header.Type, PayloadSize));
++      for (Idx = 0; Idx < PayloadSize; ++Idx) {
++        switch (Idx % 16) {
++          case 0:
++            DEBUG ((DEBUG_VERBOSE, "\n%04X:", Idx));
++            break;
++          case 8:
++            DEBUG ((DEBUG_VERBOSE, " "));
++            break;
++          default:
++            ;
++        }
++        DEBUG ((DEBUG_VERBOSE, " %02X", Payload[Idx]));
++      }
++      DEBUG ((DEBUG_VERBOSE, "\n"));
++    );
++
++    switch (Header.Type) {
++    case ET_FIELD:
++      Status = VisitSmbiosField (Context, Payload, PayloadSize);
++      break;
++    case ET_TABLE:
++      Status = VisitSmbiosTable (Smbios, ProducerHandle, Context, Payload,
++                 PayloadSize);
++      break;
++    default:
++      ;
++    }
++
++    FreePool (Payload);
++  }
++
++  return Status;
++}
++
++
++/**
++  Install some of the default SMBIOS tables for table types that QEMU hasn't
++  provided under QemuFwCfgItemX86SmbiosTables, but are required by the
++  SMBIOS-2.7.1 specification.
++
++  @param[in]     Smbios          The EFI_SMBIOS_PROTOCOL instance used for
++                                 installing SMBIOS tables.
++  @param[in]     ProducerHandle  Passed on to Smbios->Add(), ProducerHandle
++                                 tracks the origin of installed SMBIOS tables.
++  @param[in,out] Context         The BUILD_CONTEXT object tracking installed
++                                 tables and saved patches.
++
++  @return  Status codes returned by the InstallSmbiosTypeXX() functions,
++           including the final EFI_SUCCESS if all such calls succeed.
++**/
++STATIC
++EFI_STATUS
++EFIAPI
++InstallDefaultTables (
++  IN     EFI_SMBIOS_PROTOCOL *Smbios,
++  IN     EFI_HANDLE          ProducerHandle,
++  IN OUT BUILD_CONTEXT       *Context
++  )
++{
++  return EFI_SUCCESS;
++}
++
++
++/**
++  Fetch and install SMBIOS tables on the QEMU hypervisor.
++
++  First, tables provided by QEMU in entirety are installed verbatim.
++
++  Then the function prepares some of the remaining tables required by the
++  SMBIOS-2.7.1 specification. For each such table,
++  - if QEMU provides any fields for the table, they take effect verbatim,
++  - remaining fields are set by this function.
++
++  @param[in] Smbios       The EFI_SMBIOS_PROTOCOL instance used for installing
++                          the SMBIOS tables.
++  @param[in] ImageHandle  The image handle of the calling module, passed as
++                          ProducerHandle to the Smbios->Add() call.
++
++  @retval EFI_SUCCESS            All tables have been installed.
++  @retval EFI_UNSUPPORTED        The pair (Smbios->MajorVersion,
++                                 Smbios->MinorVersion) precedes (2, 3)
++                                 lexicographically.
++  @return                        Error codes returned by Smbios->Add() or
++                                 internal functions. Some tables may not have
++                                 been installed or fully patched.
++**/
++EFI_STATUS
++EFIAPI
++InstallQemuSmbiosTables (
++  IN EFI_SMBIOS_PROTOCOL *Smbios,
++  IN EFI_HANDLE          ImageHandle
++  )
++{
++  EFI_STATUS    Status;
++  BUILD_CONTEXT *Context;
++
++  if (Smbios->MajorVersion < 2 || Smbios->MinorVersion < 3) {
++    DEBUG ((DEBUG_ERROR, "%a: unsupported Smbios version %d.%d\n",
++      __FUNCTION__, Smbios->MajorVersion, Smbios->MinorVersion));
++    return EFI_UNSUPPORTED;
++  }
++
++  Status = InitSmbiosContext (&Context);
++  if (EFI_ERROR (Status)) {
++    return Status;
++  }
++
++  //
++  // <IndustryStandard/SmBios.h> and <Protocol/Smbios.h> must agree.
++  //
++  ASSERT (sizeof(SMBIOS_STRUCTURE) == sizeof(EFI_SMBIOS_TABLE_HEADER));
++
++  Status = ScanQemuSmbios (Smbios, ImageHandle, Context);
++  if (EFI_ERROR (Status)) {
++    goto Cleanup;
++  }
++
++  Status = InstallDefaultTables (Smbios, ImageHandle, Context);
++
++Cleanup:
++  UninitSmbiosContext (Context);
++  return Status;
++}
+diff --git a/OvmfPkg/SmbiosPlatformDxe/QemuLegacy.h b/OvmfPkg/SmbiosPlatformDxe/QemuLegacy.h
+new file mode 100644
+index 0000000..40d5ad3
+--- /dev/null
++++ b/OvmfPkg/SmbiosPlatformDxe/QemuLegacy.h
+@@ -0,0 +1,52 @@
++/** @file
++  This header file provides QEMU-specific public prototypes for the main driver
++  file, "SmbiosPlatformDxe.c".
++
++  Copyright (C) 2013, Red Hat, Inc.
++
++  This program and the accompanying materials are licensed and made available
++  under the terms and conditions of the BSD License which accompanies this
++  distribution.  The full text of the license may be found at
++  http://opensource.org/licenses/bsd-license.php
++
++  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
++  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
++**/
++
++#ifndef _QEMU_LEGACY_H_
++#define _QEMU_LEGACY_H_
++
++#include <Protocol/Smbios.h>
++
++
++/**
++  Fetch and install SMBIOS tables on the QEMU hypervisor.
++
++  First, tables provided by QEMU in entirety are installed verbatim.
++
++  Then the function prepares some of the remaining tables required by the
++  SMBIOS-2.7.1 specification. For each such table,
++  - if QEMU provides any fields for the table, they take effect verbatim,
++  - remaining fields are set by this function.
++
++  @param[in] Smbios       The EFI_SMBIOS_PROTOCOL instance used for installing
++                          the SMBIOS tables.
++  @param[in] ImageHandle  The image handle of the calling module, passed as
++                          ProducerHandle to the Smbios->Add() call.
++
++  @retval EFI_SUCCESS            All tables have been installed.
++  @retval EFI_UNSUPPORTED        The pair (Smbios->MajorVersion,
++                                 Smbios->MinorVersion) precedes (2, 3)
++                                 lexicographically.
++  @return                        Error codes returned by Smbios->Add() or
++                                 internal functions. Some tables may not have
++                                 been installed or fully patched.
++**/
++EFI_STATUS
++EFIAPI
++InstallQemuSmbiosTables (
++  IN EFI_SMBIOS_PROTOCOL *Smbios,
++  IN EFI_HANDLE          ImageHandle
++  );
++
++#endif
+diff --git a/OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h b/OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h
+new file mode 100644
+index 0000000..8613407
+--- /dev/null
++++ b/OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h
+@@ -0,0 +1,221 @@
++/** @file
++  This header provides common includes, and communicates internal types,
++  function prototypes and macros between "Qemu.c" and "QemuTypeXX.c", that
++  relate to the installation and patching of SMBIOS tables on the QEMU
++  platform.
++
++  Copyright (C) 2013, Red Hat, Inc.
++
++  This program and the accompanying materials are licensed and made available
++  under the terms and conditions of the BSD License which accompanies this
++  distribution.  The full text of the license may be found at
++  http://opensource.org/licenses/bsd-license.php
++
++  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
++  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
++**/
++
++#ifndef _QEMU_LEGACY_INTERNAL_H_
++#define _QEMU_LEGACY_INTERNAL_H_
++
++#include <IndustryStandard/SmBios.h>
++#include <Library/BaseLib.h>
++#include <Library/BaseMemoryLib.h>
++#include <Library/DebugLib.h>
++#include <Library/QemuFwCfgLib.h>
++#include <Protocol/Smbios.h>
++
++
++//
++// Type identifiers of all tables mandated by the SMBIOS-2.7.1 specification
++// fall strictly under this limit.
++//
++#define TABLE_TYPE_LIMIT (EFI_SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION + 1)
++
++
++//
++// Track a patch in dynamic memory, originating from a QEMU SMBIOS firmware
++// configuration entry with ET_FIELD type.
++//
++typedef struct {
++  UINT8  *Base;
++  UINT16 Size;
++} PATCH;
++
++
++#define FIELD_OFFSET_MINIMUM  ((INT32) sizeof(SMBIOS_STRUCTURE))
++#define PATCH_SUBSCRIPT_LIMIT (255 - FIELD_OFFSET_MINIMUM)
++
++//
++// The following structure tracks the installation of each SMBIOS table with a
++// type below TABLE_TYPE_LIMIT, and captures QEMU SMBIOS firmware configuration
++// entries with ET_FIELD type that target the default table for the same type.
++//
++typedef struct {
++  BOOLEAN Installed; // at least one instance of the type has been installed
++
++  PATCH Patch[PATCH_SUBSCRIPT_LIMIT]; // Patches indexed by the field offset
++                                      // that they target in this specific
++                                      // table type. Patching the SMBIOS table
++                                      // header is not allowed, hence we can
++                                      // shift down field offsets. An unused
++                                      // element has zeroed-out fields.
++} TABLE_CONTEXT;
++
++
++//
++// Track the installation of, and stored patches for, all table types below
++// TABLE_TYPE_LIMIT.
++//
++typedef struct {
++  TABLE_CONTEXT Table[TABLE_TYPE_LIMIT];
++} BUILD_CONTEXT;
++
++
++//
++// Convenience / safety macro for defining C structure types for default SMBIOS
++// tables.
++//
++// Rules of use:
++// - Use only within #pragma pack(1).
++// - This macro depends on the macro
++//   "OVMF_TYPE ## TableType ## _STRINGS" specifying the text strings
++//   (unformatted area) for TableType. Each "QemuTypeXX.c" file needs to
++//   provide said macro before using the one below.
++//
++#define OVMF_SMBIOS(TableType)                                                \
++          typedef struct {                                                    \
++            SMBIOS_TABLE_TYPE##TableType Base;                                \
++            UINT8             Strings[sizeof OVMF_TYPE##TableType##_STRINGS]; \
++          } OVMF_TYPE##TableType
++
++
++//
++// Convenience / safety macro for patching a field in the formatted area of
++// an SMBIOS table.
++//
++#define PATCH_FORMATTED(Context, TableType, OvmfTablePtr, FieldName)      \
++          PatchSmbiosFormatted (                                          \
++            Context,                                                      \
++            TableType,                                                    \
++            (UINT16) OFFSET_OF (SMBIOS_TABLE_TYPE##TableType, FieldName), \
++            (UINT16) sizeof (OvmfTablePtr)->Base.FieldName,               \
++            (UINT8 *) (OvmfTablePtr)                                      \
++            )
++
++
++/**
++  Apply a saved patch to a field located in the formatted are of a not yet
++  installed SMBIOS table.
++
++  The patch is looked up based on (Context, TableType, FieldOffset).
++
++  @param[in]  Context      The BUILD_CONTEXT object storing saved patches.
++  @param[in]  TableType    Selects the table type for which the patch has been
++                           saved. It is assumed that the caller has validated
++                           TableType against TABLE_TYPE_LIMIT (upper
++                           exclusive).
++  @param[in]  FieldOffset  Selects the SMBIOS field for which the patch has
++                           been saved. It is assumed that the caller has
++                           validated FieldOffset against FIELD_OFFSET_MINIMUM
++                           (lower inclusive) and 255 (upper exclusive).
++  @param[in]  FieldSize    The caller supplies the size of the field to patch
++                           in FieldSize. The patch saved for
++                           TableType:FieldOffset, if any, is only applied if
++                           its size equals FieldSize.
++  @param[out] TableBase    Base of the SMBIOS table of type TableType in which
++                           the field starting at FieldOffset needs to be
++                           patched.
++
++  @retval EFI_NOT_FOUND          No patch found for TableType:FieldOffset in
++                                 Context. This return value is considered
++                                 informative (ie. non-fatal).
++  @retval EFI_INVALID_PARAMETER  Patch found for TableType:FieldOffset, but its
++                                 size doesn't match FieldSize. This result is
++                                 considered a fatal error of the patch origin.
++  @retval EFI_SUCCESS            The SMBIOS table at TableBase has been patched
++                                 starting at FieldOffset for a length of
++                                 FieldSize.
++**/
++EFI_STATUS
++EFIAPI
++PatchSmbiosFormatted (
++  IN  BUILD_CONTEXT *Context,
++  IN  UINT8         TableType,
++  IN  UINT16        FieldOffset,
++  IN  UINT16        FieldSize,
++  OUT UINT8         *TableBase
++  );
++
++
++//
++// Convenience / safety macro for patching a string in the unformatted area of
++// an SMBIOS table.
++//
++#define PATCH_UNFORMATTED(Smbios, SmbiosHandle, Context, TableType,       \
++          OvmfTablePtr, FieldName)                                        \
++                                                                          \
++          PatchSmbiosUnformatted (                                        \
++            Smbios,                                                       \
++            SmbiosHandle,                                                 \
++            Context,                                                      \
++            TableType,                                                    \
++            (UINT16) OFFSET_OF (SMBIOS_TABLE_TYPE##TableType, FieldName), \
++            (UINT8 *) (OvmfTablePtr)                                      \
++            )
++
++
++/**
++  Apply a saved patch to a text string located in the unformatted area of an
++  already installed SMBIOS table.
++
++  The patch is looked up based on (Context, TableType, FieldOffset).
++
++  @param[in]  Smbios        The EFI_SMBIOS_PROTOCOL instance used previously
++                            for installing the SMBIOS table.
++  @param[in]  SmbiosHandle  The EFI_SMBIOS_HANDLE previously returned by
++                            Smbios->Add().
++  @param[in]  Context       The BUILD_CONTEXT object storing saved patches.
++  @param[in]  TableType     Selects the table type for which the patch has been
++                            saved. It is assumed that the caller has validated
++                            TableType against TABLE_TYPE_LIMIT (upper
++                            exclusive).
++  @param[in]  FieldOffset   Selects the SMBIOS field for which the patch has
++                            been saved. It is assumed that the caller has
++                            validated FieldOffset against FIELD_OFFSET_MINIMUM
++                            (lower inclusive) and 255 (upper exclusive).
++                            It is also assumed that TableBase[FieldOffset]
++                            accesses a field of type SMBIOS_TABLE_STRING, ie. a
++                            field in the formatted area that identifies an
++                            existent text string in the unformatted area. Text
++                            string identifiers are one-based.
++  @param[out] TableBase     Base of the SMBIOS table of type TableType in which
++                            the SMBIOS_TABLE_STRING field at FieldOffset
++                            identifies the existent text string to update.
++
++  @retval EFI_NOT_FOUND          No patch found for TableType:FieldOffset in
++                                 Context. This return value is considered
++                                 informative (ie. non-fatal).
++  @retval EFI_INVALID_PARAMETER  Patch found for TableType:FieldOffset, but it
++                                 doesn't end with a NUL character. This result
++                                 is considered a fatal error of the patch
++                                 origin.
++  @retval EFI_SUCCESS            The text string identified by
++                                 TableBase[FieldOffset] has been replaced in
++                                 the installed SMBIOS table under SmbiosHandle.
++  @return                        Error codes returned by
++                                 Smbios->UpdateString(). EFI_NOT_FOUND shall
++                                 not be returned.
++**/
++EFI_STATUS
++EFIAPI
++PatchSmbiosUnformatted (
++  IN  EFI_SMBIOS_PROTOCOL *Smbios,
++  IN  EFI_SMBIOS_HANDLE   SmbiosHandle,
++  IN  BUILD_CONTEXT       *Context,
++  IN  UINT8               TableType,
++  IN  UINT16              FieldOffset,
++  IN  UINT8               *TableBase
++  );
++
++#endif
+diff --git a/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c b/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c
+index 29948a4..b7c1d0d 100644
+--- a/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c
++++ b/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c
+@@ -1,6 +1,7 @@
+ /** @file
+   This driver installs SMBIOS information for OVMF
+ 
++  Copyright (C) 2013, Red Hat, Inc.
+   Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>
+   Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
+ 
+@@ -15,6 +16,9 @@
+ **/
+ 
+ #include "SmbiosPlatformDxe.h"
++#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
++#include "QemuLegacy.h"
++#endif
+ 
+ #define TYPE0_STRINGS \
+   "EFI Development Kit II / OVMF\0"     /* Vendor */ \
+@@ -27,10 +31,10 @@
+ typedef struct {
+   SMBIOS_TABLE_TYPE0 Base;
+   UINT8              Strings[sizeof(TYPE0_STRINGS)];
+-} OVMF_TYPE0;
++} OVMF_DEFAULT_TYPE0;
+ #pragma pack()
+ 
+-STATIC CONST OVMF_TYPE0 mOvmfDefaultType0 = {
++STATIC CONST OVMF_DEFAULT_TYPE0 mOvmfDefaultType0 = {
+   {
+     // SMBIOS_STRUCTURE Hdr
+     {
+@@ -202,7 +206,14 @@ SmbiosTablePublishEntry (
+     SmbiosTables = GetQemuSmbiosTables ();
+   }
+ 
+-  if (SmbiosTables != NULL) {
++  if (SmbiosTables == NULL) {
++#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
++    //
++    // Handle QEMU's legacy SMBIOS interface.
++    //
++    Status = InstallQemuSmbiosTables (Smbios, ImageHandle);
++#endif
++  } else {
+     Status = InstallAllStructures (Smbios, SmbiosTables);
+ 
+     //
+diff --git a/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf b/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+index 3b90aac..8c9f43c 100644
+--- a/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
++++ b/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+@@ -1,6 +1,7 @@
+ ## @file
+ #  This driver installs SMBIOS information for OVMF
+ #
++#  Copyright (C) 2013, Red Hat, Inc.
+ #  Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>
+ #  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+ #
+@@ -35,6 +36,7 @@
+ 
+ [Sources.IA32, Sources.X64]
+   X86Xen.c
++  QemuLegacy.c
+ 
+ [Sources.ARM, Sources.AARCH64]
+   ArmXen.c
+-- 
+1.8.3.1
+
diff --git a/0001-OvmfPkg-disable-multi-processor-support-for-boot-tim.patch b/0001-OvmfPkg-disable-multi-processor-support-for-boot-tim.patch
new file mode 100644
index 0000000..2592b07
--- /dev/null
+++ b/0001-OvmfPkg-disable-multi-processor-support-for-boot-tim.patch
@@ -0,0 +1,68 @@
+From dd48ac51d1df4f718b4401b188d2824aebcc341c Mon Sep 17 00:00:00 2001
+From: Laszlo Ersek <lersek@redhat.com>
+Date: Wed, 26 Nov 2014 16:32:06 +0100
+Subject: [PATCH] OvmfPkg: disable multi-processor support for boot time
+
+We have no useful workload for APs, so let's not start them up, because
+they would spin indefinitely until ExitBootServices().
+
+Setting gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber to 1
+causes InitializeMpSupport() in "UefiCpuPkg/CpuDxe/CpuMp.c" to return
+early.
+
+Contributed-under: TianoCore Contribution Agreement 1.0
+Signed-off-by: Laszlo Ersek <lersek@redhat.com>
+---
+ OvmfPkg/OvmfPkgIa32.dsc    | 4 ++++
+ OvmfPkg/OvmfPkgIa32X64.dsc | 4 ++++
+ OvmfPkg/OvmfPkgX64.dsc     | 4 ++++
+ 3 files changed, 12 insertions(+)
+
+diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
+index 6598102..1730812 100644
+--- a/OvmfPkg/OvmfPkgIa32.dsc
++++ b/OvmfPkg/OvmfPkgIa32.dsc
+@@ -329,6 +329,10 @@
+   # IRQs 5, 9, 10, 11 are level-triggered
+   gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel|0x0E20
+ 
++  # We have no useful workload for APs, so let's not start them up, because
++  # they would spin indefinitely until ExitBootServices().
++  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|1
++
+ ################################################################################
+ #
+ # Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
+diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
+index 4de961f..370ae50 100644
+--- a/OvmfPkg/OvmfPkgIa32X64.dsc
++++ b/OvmfPkg/OvmfPkgIa32X64.dsc
+@@ -335,6 +335,10 @@
+   # IRQs 5, 9, 10, 11 are level-triggered
+   gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel|0x0E20
+ 
++  # We have no useful workload for APs, so let's not start them up, because
++  # they would spin indefinitely until ExitBootServices().
++  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|1
++
+ ################################################################################
+ #
+ # Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
+diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
+index 6c38081..175d5f4 100644
+--- a/OvmfPkg/OvmfPkgX64.dsc
++++ b/OvmfPkg/OvmfPkgX64.dsc
+@@ -334,6 +334,10 @@
+   # IRQs 5, 9, 10, 11 are level-triggered
+   gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel|0x0E20
+ 
++  # We have no useful workload for APs, so let's not start them up, because
++  # they would spin indefinitely until ExitBootServices().
++  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|1
++
+ ################################################################################
+ #
+ # Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
+-- 
+1.8.3.1
+
diff --git a/0001-OvmfPkg-silence-EFI_D_VERBOSE-0x00400000-in-NvmExpre.patch b/0001-OvmfPkg-silence-EFI_D_VERBOSE-0x00400000-in-NvmExpre.patch
new file mode 100644
index 0000000..e3c5c99
--- /dev/null
+++ b/0001-OvmfPkg-silence-EFI_D_VERBOSE-0x00400000-in-NvmExpre.patch
@@ -0,0 +1,68 @@
+From 4475c02d63dda9e2da4c663593491a01ae8c6b5a Mon Sep 17 00:00:00 2001
+From: Laszlo Ersek <lersek@redhat.com>
+Date: Wed, 27 Jan 2016 03:05:18 +0100
+Subject: [PATCH 1/5] OvmfPkg: silence EFI_D_VERBOSE (0x00400000) in
+ NvmExpressDxe
+
+NvmExpressDxe logs all BlockIo read & write calls on the EFI_D_VERBOSE
+level.
+
+Contributed-under: TianoCore Contribution Agreement 1.0
+Signed-off-by: Laszlo Ersek <lersek@redhat.com>
+---
+ OvmfPkg/OvmfPkgIa32.dsc    | 5 ++++-
+ OvmfPkg/OvmfPkgIa32X64.dsc | 5 ++++-
+ OvmfPkg/OvmfPkgX64.dsc     | 5 ++++-
+ 3 files changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
+index 0206dda..36d3aaa 100644
+--- a/OvmfPkg/OvmfPkgIa32.dsc
++++ b/OvmfPkg/OvmfPkgIa32.dsc
+@@ -593,7 +593,10 @@
+   OvmfPkg/SataControllerDxe/SataControllerDxe.inf
+   MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+   MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+-  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
++  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf {
++    <PcdsFixedAtBuild>
++      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F
++  }
+   MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+   MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+   MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
+index 06fe141..c05a90a 100644
+--- a/OvmfPkg/OvmfPkgIa32X64.dsc
++++ b/OvmfPkg/OvmfPkgIa32X64.dsc
+@@ -602,7 +602,10 @@
+   OvmfPkg/SataControllerDxe/SataControllerDxe.inf
+   MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+   MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+-  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
++  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf {
++    <PcdsFixedAtBuild>
++      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F
++  }
+   MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+   MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+   MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
+index e88e70d..eb3ad3f 100644
+--- a/OvmfPkg/OvmfPkgX64.dsc
++++ b/OvmfPkg/OvmfPkgX64.dsc
+@@ -600,7 +600,10 @@
+   OvmfPkg/SataControllerDxe/SataControllerDxe.inf
+   MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+   MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+-  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
++  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf {
++    <PcdsFixedAtBuild>
++      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F
++  }
+   MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+   MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+   MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+-- 
+1.8.3.1
+
diff --git a/0001-pick-up-any-display-device-not-only-vga.patch b/0001-pick-up-any-display-device-not-only-vga.patch
new file mode 100644
index 0000000..de874d2
--- /dev/null
+++ b/0001-pick-up-any-display-device-not-only-vga.patch
@@ -0,0 +1,25 @@
+From 71de9d92e78ae0a7c351f9daf84109bbbaca400a Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Thu, 13 Mar 2014 08:08:41 +0100
+Subject: [PATCH] pick up any display device, not only vga
+
+---
+ OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
+index ab9c93e..d3f5908 100644
+--- a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
++++ b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
+@@ -593,7 +593,7 @@ DetectAndPreparePlatformPciDevicePath (
+   //
+   // Here we decide which VGA device to enable in PCI bus
+   //
+-  if (IS_PCI_VGA (Pci)) {
++  if (IS_PCI_DISPLAY (Pci)) {
+     //
+     // Add them to ConOut.
+     //
+-- 
+1.8.3.1
+
diff --git a/0002-OvmfPkg-SmbiosPlatformDxe-install-patch-default-lega.patch b/0002-OvmfPkg-SmbiosPlatformDxe-install-patch-default-lega.patch
new file mode 100644
index 0000000..8a4d751
--- /dev/null
+++ b/0002-OvmfPkg-SmbiosPlatformDxe-install-patch-default-lega.patch
@@ -0,0 +1,272 @@
+From 26146b77f6d54c44fbb984bacf8bf31683e8d477 Mon Sep 17 00:00:00 2001
+From: Laszlo Ersek <lersek@redhat.com>
+Date: Wed, 5 Jun 2013 10:25:13 +0200
+Subject: [PATCH 2/3] OvmfPkg/SmbiosPlatformDxe: install+patch default legacy
+ type0 table (X86)
+
+Contributed-under: TianoCore Contribution Agreement 1.0
+Signed-off-by: Laszlo Ersek <lersek@redhat.com>
+---
+ OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c          |   5 +-
+ OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h  |  30 ++++
+ OvmfPkg/SmbiosPlatformDxe/QemuType0.c           | 180 ++++++++++++++++++++++++
+ OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf |   1 +
+ 4 files changed, 215 insertions(+), 1 deletion(-)
+ create mode 100644 OvmfPkg/SmbiosPlatformDxe/QemuType0.c
+
+diff --git a/OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c b/OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c
+index 9c57558..ed75a01 100644
+--- a/OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c
++++ b/OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c
+@@ -628,7 +628,10 @@ InstallDefaultTables (
+   IN OUT BUILD_CONTEXT       *Context
+   )
+ {
+-  return EFI_SUCCESS;
++  EFI_STATUS Status;
++
++  Status = InstallSmbiosType0 (Smbios, ProducerHandle, Context);
++  return Status;
+ }
+ 
+ 
+diff --git a/OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h b/OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h
+index 8613407..ca776b5 100644
+--- a/OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h
++++ b/OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h
+@@ -218,4 +218,34 @@ PatchSmbiosUnformatted (
+   IN  UINT8               *TableBase
+   );
+ 
++
++/**
++  Install default (fallback) table for SMBIOS Type 0.
++
++  In case QEMU has provided no Type 0 SMBIOS table in whole, prepare one here,
++  patch it with any referring saved patches, and install it.
++
++  @param[in]     Smbios          The EFI_SMBIOS_PROTOCOL instance used for
++                                 installing SMBIOS tables.
++  @param[in]     ProducerHandle  Passed on to Smbios->Add(), ProducerHandle
++                                 tracks the origin of installed SMBIOS tables.
++  @param[in,out] Context         The BUILD_CONTEXT object tracking installed
++                                 tables and saved patches.
++
++  @retval EFI_SUCCESS  A Type 0 table has already been installed from the
++                       SMBIOS firmware configuration blob.
++  @retval EFI_SUCCESS  No Type 0 table was installed previously, and installing
++                       the default here has succeeded.
++  @return              Error codes from the PATCH_FORMATTED() and
++                       PATCH_UNFORMATTED() macros, except EFI_NOT_FOUND, which
++                       is only an informative result of theirs.
++**/
++EFI_STATUS
++EFIAPI
++InstallSmbiosType0 (
++  IN     EFI_SMBIOS_PROTOCOL *Smbios,
++  IN     EFI_HANDLE          ProducerHandle,
++  IN OUT BUILD_CONTEXT       *Context
++  );
++
+ #endif
+diff --git a/OvmfPkg/SmbiosPlatformDxe/QemuType0.c b/OvmfPkg/SmbiosPlatformDxe/QemuType0.c
+new file mode 100644
+index 0000000..9ec5d76
+--- /dev/null
++++ b/OvmfPkg/SmbiosPlatformDxe/QemuType0.c
+@@ -0,0 +1,180 @@
++/** @file
++  Install the default Type 0 SMBIOS table if QEMU doesn't provide one through
++  the firmware configuration interface.
++
++  Copyright (C) 2013, Red Hat, Inc.
++
++  This program and the accompanying materials are licensed and made available
++  under the terms and conditions of the BSD License which accompanies this
++  distribution.  The full text of the license may be found at
++  http://opensource.org/licenses/bsd-license.php
++
++  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
++  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
++**/
++
++#include "QemuLegacyInternal.h"
++
++
++//
++// Text strings (unformatted area) for the default Tpe 0 SMBIOS table.
++//
++// All possible strings must be provided because Smbios->UpdateString() can
++// only update existing strings, it can't introduce new ones.
++//
++#define OVMF_TYPE0_STRINGS                                        \
++          "EFI Development Kit II / OVMF\0" /* Vendor */          \
++          "0.1\0"                           /* BiosVersion */     \
++          "06/03/2013\0"                    /* BiosReleaseDate */
++
++
++//
++// Type definition and contents of the default Type 0 SMBIOS table.
++//
++#pragma pack(1)
++OVMF_SMBIOS (0);
++#pragma pack()
++
++STATIC CONST OVMF_TYPE0 mOvmfType0 = {
++  {
++    // SMBIOS_STRUCTURE Hdr
++    {
++      EFI_SMBIOS_TYPE_BIOS_INFORMATION, // UINT8 Type
++      sizeof (SMBIOS_TABLE_TYPE0)       // UINT8 Length
++    },
++    1,     // SMBIOS_TABLE_STRING       Vendor
++    2,     // SMBIOS_TABLE_STRING       BiosVersion
++    0xE800,// UINT16                    BiosSegment
++    3,     // SMBIOS_TABLE_STRING       BiosReleaseDate
++    0,     // UINT8                     BiosSize
++    { 0 }, // MISC_BIOS_CHARACTERISTICS BiosCharacteristics
++    { 0 }, // UINT8                     BIOSCharacteristicsExtensionBytes[2]
++    0,     // UINT8                     SystemBiosMajorRelease
++    1,     // UINT8                     SystemBiosMinorRelease
++    0xFF,  // UINT8                     EmbeddedControllerFirmwareMajorRelease
++    0xFF   // UINT8                     EmbeddedControllerFirmwareMinorRelease
++  },
++  OVMF_TYPE0_STRINGS
++};
++
++
++/**
++  Install default (fallback) table for SMBIOS Type 0.
++
++  In case QEMU has provided no Type 0 SMBIOS table in whole, prepare one here,
++  patch it with any referring saved patches, and install it.
++
++  @param[in]     Smbios          The EFI_SMBIOS_PROTOCOL instance used for
++                                 installing SMBIOS tables.
++  @param[in]     ProducerHandle  Passed on to Smbios->Add(), ProducerHandle
++                                 tracks the origin of installed SMBIOS tables.
++  @param[in,out] Context         The BUILD_CONTEXT object tracking installed
++                                 tables and saved patches.
++
++  @retval EFI_SUCCESS  A Type 0 table has already been installed from the
++                       SMBIOS firmware configuration blob.
++  @retval EFI_SUCCESS  No Type 0 table was installed previously, and installing
++                       the default here has succeeded.
++  @return              Error codes from the PATCH_FORMATTED() and
++                       PATCH_UNFORMATTED() macros, except EFI_NOT_FOUND, which
++                       is only an informative result of theirs.
++**/
++EFI_STATUS
++EFIAPI
++InstallSmbiosType0 (
++  IN     EFI_SMBIOS_PROTOCOL *Smbios,
++  IN     EFI_HANDLE          ProducerHandle,
++  IN OUT BUILD_CONTEXT       *Context
++  )
++{
++  TABLE_CONTEXT                       *Table;
++  OVMF_TYPE0                          OvmfType0;
++  MISC_BIOS_CHARACTERISTICS_EXTENSION *Ext;
++  EFI_STATUS                          Status;
++  EFI_SMBIOS_HANDLE                   SmbiosHandle;
++
++  Table = &Context->Table[0];
++  if (Table->Installed) {
++    return EFI_SUCCESS;
++  }
++
++  CopyMem (&OvmfType0, &mOvmfType0, sizeof OvmfType0);
++  Ext = (VOID *) &OvmfType0.Base.BIOSCharacteristicsExtensionBytes[0];
++
++  OvmfType0.Base.BiosCharacteristics.BiosCharacteristicsNotSupported = 1;
++  Ext->SystemReserved.UefiSpecificationSupported = 1;
++  Ext->SystemReserved.VirtualMachineSupported    = 1;
++
++  //
++  // Default contents ready. Formatted fields must be patched before installing
++  // the table, while strings in the unformatted area will be patched
++  // afterwards.
++  //
++  Status = PATCH_FORMATTED (Context, 0, &OvmfType0, BiosSegment);
++  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
++    return Status;
++  }
++  Status = PATCH_FORMATTED (Context, 0, &OvmfType0, BiosSize);
++  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
++    return Status;
++  }
++  Status = PATCH_FORMATTED (Context, 0, &OvmfType0, BiosCharacteristics);
++  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
++    return Status;
++  }
++  Status = PATCH_FORMATTED (Context, 0, &OvmfType0,
++             BIOSCharacteristicsExtensionBytes);
++  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
++    return Status;
++  }
++  Status = PATCH_FORMATTED (Context, 0, &OvmfType0, SystemBiosMajorRelease);
++  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
++    return Status;
++  }
++  Status = PATCH_FORMATTED (Context, 0, &OvmfType0, SystemBiosMinorRelease);
++  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
++    return Status;
++  }
++  Status = PATCH_FORMATTED (Context, 0, &OvmfType0,
++             EmbeddedControllerFirmwareMajorRelease);
++  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
++    return Status;
++  }
++  Status = PATCH_FORMATTED (Context, 0, &OvmfType0,
++             EmbeddedControllerFirmwareMinorRelease);
++  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
++    return Status;
++  }
++
++  //
++  // Install SMBIOS table with patched formatted area and default strings.
++  //
++  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
++  Status = Smbios->Add (Smbios, ProducerHandle, &SmbiosHandle,
++                     (EFI_SMBIOS_TABLE_HEADER *) &OvmfType0);
++  if (EFI_ERROR (Status)) {
++    DEBUG ((DEBUG_ERROR, "%a: Smbios->Add(): %r\n", __FUNCTION__, Status));
++    return Status;
++  }
++  Table->Installed = TRUE;
++
++  //
++  // Patch strings in the unformatted area of the installed table.
++  //
++  Status = PATCH_UNFORMATTED (Smbios, SmbiosHandle, Context, 0, &OvmfType0,
++             Vendor);
++  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
++    return Status;
++  }
++  Status = PATCH_UNFORMATTED (Smbios, SmbiosHandle, Context, 0, &OvmfType0,
++             BiosVersion);
++  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
++    return Status;
++  }
++  Status = PATCH_UNFORMATTED (Smbios, SmbiosHandle, Context, 0, &OvmfType0,
++             BiosReleaseDate);
++  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
++    return Status;
++  }
++  return EFI_SUCCESS;
++}
+diff --git a/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf b/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+index 8c9f43c..3483b9c 100644
+--- a/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
++++ b/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+@@ -37,6 +37,7 @@
+ [Sources.IA32, Sources.X64]
+   X86Xen.c
+   QemuLegacy.c
++  QemuType0.c
+ 
+ [Sources.ARM, Sources.AARCH64]
+   ArmXen.c
+-- 
+1.8.3.1
+
diff --git a/0002-OvmfPkg-silence-EFI_D_VERBOSE-0x00400000-in-the-DXE-.patch b/0002-OvmfPkg-silence-EFI_D_VERBOSE-0x00400000-in-the-DXE-.patch
new file mode 100644
index 0000000..cf4426c
--- /dev/null
+++ b/0002-OvmfPkg-silence-EFI_D_VERBOSE-0x00400000-in-the-DXE-.patch
@@ -0,0 +1,60 @@
+From c6e5bbe0378662620e736c82bcd0d08db42e5979 Mon Sep 17 00:00:00 2001
+From: Laszlo Ersek <lersek@redhat.com>
+Date: Wed, 27 Jan 2016 03:05:18 +0100
+Subject: [PATCH 2/5] OvmfPkg: silence EFI_D_VERBOSE (0x00400000) in the DXE
+ core
+
+The DXE core logs a bunch of Properties Table and Memory Attributes Table
+related information, on the EFI_D_VERBOSE level, that I am at the moment
+not interested in. Suppress said output.
+
+Contributed-under: TianoCore Contribution Agreement 1.0
+Signed-off-by: Laszlo Ersek <lersek@redhat.com>
+---
+ OvmfPkg/OvmfPkgIa32.dsc    | 2 ++
+ OvmfPkg/OvmfPkgIa32X64.dsc | 2 ++
+ OvmfPkg/OvmfPkgX64.dsc     | 2 ++
+ 3 files changed, 6 insertions(+)
+
+diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
+index 36d3aaa..bf64882 100644
+--- a/OvmfPkg/OvmfPkgIa32.dsc
++++ b/OvmfPkg/OvmfPkgIa32.dsc
+@@ -516,6 +516,8 @@
+     <LibraryClasses>
+       NULL|IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+       DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
++    <PcdsFixedAtBuild>
++      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F
+   }
+ 
+   IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCodeRuntimeDxe.inf
+diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
+index c05a90a..345c8ce 100644
+--- a/OvmfPkg/OvmfPkgIa32X64.dsc
++++ b/OvmfPkg/OvmfPkgIa32X64.dsc
+@@ -525,6 +525,8 @@
+     <LibraryClasses>
+       NULL|IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+       DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
++    <PcdsFixedAtBuild>
++      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F
+   }
+ 
+   IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCodeRuntimeDxe.inf
+diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
+index eb3ad3f..0e02ba8 100644
+--- a/OvmfPkg/OvmfPkgX64.dsc
++++ b/OvmfPkg/OvmfPkgX64.dsc
+@@ -523,6 +523,8 @@
+     <LibraryClasses>
+       NULL|IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+       DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
++    <PcdsFixedAtBuild>
++      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F
+   }
+ 
+   IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCodeRuntimeDxe.inf
+-- 
+1.8.3.1
+
diff --git a/0003-OvmfPkg-SmbiosPlatformDxe-install-patch-default-lega.patch b/0003-OvmfPkg-SmbiosPlatformDxe-install-patch-default-lega.patch
new file mode 100644
index 0000000..bf2254f
--- /dev/null
+++ b/0003-OvmfPkg-SmbiosPlatformDxe-install-patch-default-lega.patch
@@ -0,0 +1,270 @@
+From 1b10131728dd1cff48ef1ce46820d89f21708852 Mon Sep 17 00:00:00 2001
+From: Laszlo Ersek <lersek@redhat.com>
+Date: Wed, 5 Jun 2013 10:28:09 +0200
+Subject: [PATCH 3/3] OvmfPkg/SmbiosPlatformDxe: install+patch default legacy
+ type1 table (X86)
+
+Contributed-under: TianoCore Contribution Agreement 1.0
+Signed-off-by: Laszlo Ersek <lersek@redhat.com>
+---
+ OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c          |   5 +
+ OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h  |  30 ++++
+ OvmfPkg/SmbiosPlatformDxe/QemuType1.c           | 178 ++++++++++++++++++++++++
+ OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf |   1 +
+ 4 files changed, 214 insertions(+)
+ create mode 100644 OvmfPkg/SmbiosPlatformDxe/QemuType1.c
+
+diff --git a/OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c b/OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c
+index ed75a01..6507cc0 100644
+--- a/OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c
++++ b/OvmfPkg/SmbiosPlatformDxe/QemuLegacy.c
+@@ -631,6 +631,11 @@ InstallDefaultTables (
+   EFI_STATUS Status;
+ 
+   Status = InstallSmbiosType0 (Smbios, ProducerHandle, Context);
++  if (EFI_ERROR (Status)) {
++    return Status;
++  }
++
++  Status = InstallSmbiosType1 (Smbios, ProducerHandle, Context);
+   return Status;
+ }
+ 
+diff --git a/OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h b/OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h
+index ca776b5..4a2e824 100644
+--- a/OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h
++++ b/OvmfPkg/SmbiosPlatformDxe/QemuLegacyInternal.h
+@@ -248,4 +248,34 @@ InstallSmbiosType0 (
+   IN OUT BUILD_CONTEXT       *Context
+   );
+ 
++
++/**
++  Install default (fallback) table for SMBIOS Type 1.
++
++  In case QEMU has provided no Type 1 SMBIOS table in whole, prepare one here,
++  patch it with any referring saved patches, and install it.
++
++  @param[in]     Smbios          The EFI_SMBIOS_PROTOCOL instance used for
++                                 installing SMBIOS tables.
++  @param[in]     ProducerHandle  Passed on to Smbios->Add(), ProducerHandle
++                                 tracks the origin of installed SMBIOS tables.
++  @param[in,out] Context         The BUILD_CONTEXT object tracking installed
++                                 tables and saved patches.
++
++  @retval EFI_SUCCESS  A Type 1 table has already been installed from the
++                       SMBIOS firmware configuration blob.
++  @retval EFI_SUCCESS  No Type 1 table was installed previously, and installing
++                       the default here has succeeded.
++  @return              Error codes from the PATCH_FORMATTED() and
++                       PATCH_UNFORMATTED() macros, except EFI_NOT_FOUND, which
++                       is only an informative result of theirs.
++**/
++EFI_STATUS
++EFIAPI
++InstallSmbiosType1 (
++  IN     EFI_SMBIOS_PROTOCOL *Smbios,
++  IN     EFI_HANDLE          ProducerHandle,
++  IN OUT BUILD_CONTEXT       *Context
++  );
++
+ #endif
+diff --git a/OvmfPkg/SmbiosPlatformDxe/QemuType1.c b/OvmfPkg/SmbiosPlatformDxe/QemuType1.c
+new file mode 100644
+index 0000000..ff48164
+--- /dev/null
++++ b/OvmfPkg/SmbiosPlatformDxe/QemuType1.c
+@@ -0,0 +1,178 @@
++/** @file
++  Install the default Type 1 SMBIOS table if QEMU doesn't provide one through
++  the firmware configuration interface.
++
++  Copyright (C) 2013, Red Hat, Inc.
++
++  This program and the accompanying materials are licensed and made available
++  under the terms and conditions of the BSD License which accompanies this
++  distribution.  The full text of the license may be found at
++  http://opensource.org/licenses/bsd-license.php
++
++  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
++  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
++**/
++
++#include "QemuLegacyInternal.h"
++
++
++//
++// Text strings (unformatted area) for the default Tpe 1 SMBIOS table.
++//
++// All possible strings must be provided because Smbios->UpdateString() can
++// only update existing strings, it can't introduce new ones.
++//
++#define OVMF_TYPE1_STRINGS                            \
++          "QEMU\0"                 /* Manufacturer */ \
++          "QEMU Virtual Machine\0" /* ProductName */  \
++          "n/a\0"                  /* Version */      \
++          "n/a\0"                  /* SerialNumber */ \
++          "n/a\0"                  /* SKUNumber */    \
++          "n/a\0"                  /* Family */
++
++
++//
++// Type definition and contents of the default Type 1 SMBIOS table.
++//
++#pragma pack(1)
++OVMF_SMBIOS (1);
++#pragma pack()
++
++STATIC CONST OVMF_TYPE1 mOvmfType1 = {
++  {
++    // SMBIOS_STRUCTURE Hdr
++    {
++      EFI_SMBIOS_TYPE_SYSTEM_INFORMATION, // UINT8 Type
++      sizeof (SMBIOS_TABLE_TYPE1)         // UINT8 Length
++    },
++    1,                           // SMBIOS_TABLE_STRING Manufacturer
++    2,                           // SMBIOS_TABLE_STRING ProductName
++    3,                           // SMBIOS_TABLE_STRING Version
++    4,                           // SMBIOS_TABLE_STRING SerialNumber
++    { 0 },                       // GUID                Uuid
++    SystemWakeupTypePowerSwitch, // UINT8               WakeUpType
++    5,                           // SMBIOS_TABLE_STRING SKUNumber
++    6,                           // SMBIOS_TABLE_STRING Family
++  },
++  OVMF_TYPE1_STRINGS
++};
++
++
++/**
++  Install default (fallback) table for SMBIOS Type 1.
++
++  In case QEMU has provided no Type 1 SMBIOS table in whole, prepare one here,
++  patch it with any referring saved patches, and install it.
++
++  @param[in]     Smbios          The EFI_SMBIOS_PROTOCOL instance used for
++                                 installing SMBIOS tables.
++  @param[in]     ProducerHandle  Passed on to Smbios->Add(), ProducerHandle
++                                 tracks the origin of installed SMBIOS tables.
++  @param[in,out] Context         The BUILD_CONTEXT object tracking installed
++                                 tables and saved patches.
++
++  @retval EFI_SUCCESS  A Type 1 table has already been installed from the
++                       SMBIOS firmware configuration blob.
++  @retval EFI_SUCCESS  No Type 1 table was installed previously, and installing
++                       the default here has succeeded.
++  @return              Error codes from the PATCH_FORMATTED() and
++                       PATCH_UNFORMATTED() macros, except EFI_NOT_FOUND, which
++                       is only an informative result of theirs.
++**/
++EFI_STATUS
++EFIAPI
++InstallSmbiosType1 (
++  IN     EFI_SMBIOS_PROTOCOL *Smbios,
++  IN     EFI_HANDLE          ProducerHandle,
++  IN OUT BUILD_CONTEXT       *Context
++  )
++{
++  TABLE_CONTEXT     *Table;
++  OVMF_TYPE1        OvmfType1;
++  EFI_STATUS        Status;
++  EFI_SMBIOS_HANDLE SmbiosHandle;
++
++  Table = &Context->Table[1];
++  if (Table->Installed) {
++    return EFI_SUCCESS;
++  }
++
++  CopyMem (&OvmfType1, &mOvmfType1, sizeof OvmfType1);
++
++  QemuFwCfgSelectItem (QemuFwCfgItemSystemUuid);
++  OvmfType1.Base.Uuid.Data1 = SwapBytes32 (QemuFwCfgRead32 ());
++  OvmfType1.Base.Uuid.Data2 = SwapBytes16 (QemuFwCfgRead16 ());
++  OvmfType1.Base.Uuid.Data3 = SwapBytes16 (QemuFwCfgRead16 ());
++  QemuFwCfgReadBytes (sizeof OvmfType1.Base.Uuid.Data4,
++    &OvmfType1.Base.Uuid.Data4);
++
++  //
++  // Default contents ready. Formatted fields must be patched before installing
++  // the table, while strings in the unformatted area will be patched
++  // afterwards.
++  //
++  Status = PATCH_FORMATTED (Context, 1, &OvmfType1, Uuid);
++  switch (Status) {
++  case EFI_NOT_FOUND:
++    break;
++  case EFI_SUCCESS:
++    OvmfType1.Base.Uuid.Data1 = SwapBytes32 (OvmfType1.Base.Uuid.Data1);
++    OvmfType1.Base.Uuid.Data2 = SwapBytes16 (OvmfType1.Base.Uuid.Data2);
++    OvmfType1.Base.Uuid.Data3 = SwapBytes16 (OvmfType1.Base.Uuid.Data3);
++    break;
++  default:
++    return Status;
++  }
++
++  Status = PATCH_FORMATTED (Context, 1, &OvmfType1, WakeUpType);
++  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
++    return Status;
++  }
++
++  //
++  // Install SMBIOS table with patched formatted area and default strings.
++  //
++  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
++  Status = Smbios->Add (Smbios, ProducerHandle, &SmbiosHandle,
++                     (EFI_SMBIOS_TABLE_HEADER *) &OvmfType1);
++  if (EFI_ERROR (Status)) {
++    DEBUG ((DEBUG_ERROR, "%a: Smbios->Add(): %r\n", __FUNCTION__, Status));
++    return Status;
++  }
++  Table->Installed = TRUE;
++
++  //
++  // Patch strings in the unformatted area of the installed table.
++  //
++  Status = PATCH_UNFORMATTED (Smbios, SmbiosHandle, Context, 1, &OvmfType1,
++             Manufacturer);
++  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
++    return Status;
++  }
++  Status = PATCH_UNFORMATTED (Smbios, SmbiosHandle, Context, 1, &OvmfType1,
++             ProductName);
++  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
++    return Status;
++  }
++  Status = PATCH_UNFORMATTED (Smbios, SmbiosHandle, Context, 1, &OvmfType1,
++             Version);
++  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
++    return Status;
++  }
++  Status = PATCH_UNFORMATTED (Smbios, SmbiosHandle, Context, 1, &OvmfType1,
++             SerialNumber);
++  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
++    return Status;
++  }
++  Status = PATCH_UNFORMATTED (Smbios, SmbiosHandle, Context, 1, &OvmfType1,
++             SKUNumber);
++  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
++    return Status;
++  }
++  Status = PATCH_UNFORMATTED (Smbios, SmbiosHandle, Context, 1, &OvmfType1,
++             Family);
++  if (Status != EFI_NOT_FOUND && Status != EFI_SUCCESS) {
++    return Status;
++  }
++  return EFI_SUCCESS;
++}
+diff --git a/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf b/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+index 3483b9c..1f7dfca 100644
+--- a/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
++++ b/OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+@@ -38,6 +38,7 @@
+   X86Xen.c
+   QemuLegacy.c
+   QemuType0.c
++  QemuType1.c
+ 
+ [Sources.ARM, Sources.AARCH64]
+   ArmXen.c
+-- 
+1.8.3.1
+
diff --git a/0003-OvmfPkg-enable-DEBUG_VERBOSE.patch b/0003-OvmfPkg-enable-DEBUG_VERBOSE.patch
new file mode 100644
index 0000000..447fdfd
--- /dev/null
+++ b/0003-OvmfPkg-enable-DEBUG_VERBOSE.patch
@@ -0,0 +1,56 @@
+From 214090228fb08f03737ba90d29e23dc7b2235614 Mon Sep 17 00:00:00 2001
+From: Laszlo Ersek <lersek@redhat.com>
+Date: Sun, 8 Jul 2012 14:26:07 +0200
+Subject: [PATCH 3/5] OvmfPkg: enable DEBUG_VERBOSE
+
+Enable verbose debug logs.
+
+Signed-off-by: Laszlo Ersek <lersek@redhat.com>
+---
+ OvmfPkg/OvmfPkgIa32.dsc    | 2 +-
+ OvmfPkg/OvmfPkgIa32X64.dsc | 2 +-
+ OvmfPkg/OvmfPkgX64.dsc     | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
+index bf64882..aaaaaa8 100644
+--- a/OvmfPkg/OvmfPkgIa32.dsc
++++ b/OvmfPkg/OvmfPkgIa32.dsc
+@@ -392,7 +392,7 @@
+   # DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may
+   #                             // significantly impact boot performance
+   # DEBUG_ERROR     0x80000000  // Error
+-  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F
++  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8040004F
+ 
+ !ifdef $(SOURCE_DEBUG_ENABLE)
+   gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
+diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
+index 345c8ce..b4545b3 100644
+--- a/OvmfPkg/OvmfPkgIa32X64.dsc
++++ b/OvmfPkg/OvmfPkgIa32X64.dsc
+@@ -397,7 +397,7 @@
+   # DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may
+   #                             // significantly impact boot performance
+   # DEBUG_ERROR     0x80000000  // Error
+-  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F
++  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8040004F
+ 
+ !ifdef $(SOURCE_DEBUG_ENABLE)
+   gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
+diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
+index 0e02ba8..1836c25 100644
+--- a/OvmfPkg/OvmfPkgX64.dsc
++++ b/OvmfPkg/OvmfPkgX64.dsc
+@@ -397,7 +397,7 @@
+   # DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may
+   #                             // significantly impact boot performance
+   # DEBUG_ERROR     0x80000000  // Error
+-  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F
++  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8040004F
+ 
+ !ifdef $(SOURCE_DEBUG_ENABLE)
+   gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
+-- 
+1.8.3.1
+
diff --git a/0004-OvmfPkg-increase-max-debug-message-length-to-512.patch b/0004-OvmfPkg-increase-max-debug-message-length-to-512.patch
new file mode 100644
index 0000000..c59c207
--- /dev/null
+++ b/0004-OvmfPkg-increase-max-debug-message-length-to-512.patch
@@ -0,0 +1,26 @@
+From f468bab8fa61f7b7d0b0149f374945eb549af16e Mon Sep 17 00:00:00 2001
+From: Laszlo Ersek <lersek@redhat.com>
+Date: Thu, 20 Feb 2014 22:54:45 +0100
+Subject: [PATCH 4/5] OvmfPkg: increase max debug message length to 512
+
+Contributed-under: TianoCore Contribution Agreement 1.0
+---
+ OvmfPkg/Library/PlatformDebugLibIoPort/DebugLib.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/OvmfPkg/Library/PlatformDebugLibIoPort/DebugLib.c b/OvmfPkg/Library/PlatformDebugLibIoPort/DebugLib.c
+index 44850a9..b6927d0 100644
+--- a/OvmfPkg/Library/PlatformDebugLibIoPort/DebugLib.c
++++ b/OvmfPkg/Library/PlatformDebugLibIoPort/DebugLib.c
+@@ -27,7 +27,7 @@
+ //
+ // Define the maximum debug and assert message length that this library supports
+ //
+-#define MAX_DEBUG_MESSAGE_LENGTH  0x100
++#define MAX_DEBUG_MESSAGE_LENGTH  0x200
+ 
+ /**
+   This constructor function does not have to do anything.
+-- 
+1.8.3.1
+
diff --git a/0005-OvmfPkg-QemuVideoDxe-enable-debug-messages-in-VbeShi.patch b/0005-OvmfPkg-QemuVideoDxe-enable-debug-messages-in-VbeShi.patch
new file mode 100644
index 0000000..d8052ba
--- /dev/null
+++ b/0005-OvmfPkg-QemuVideoDxe-enable-debug-messages-in-VbeShi.patch
@@ -0,0 +1,524 @@
+From 82175ef201595d45a0959249a36f4ffd74047fdb Mon Sep 17 00:00:00 2001
+From: Laszlo Ersek <lersek@redhat.com>
+Date: Tue, 20 May 2014 23:41:56 +0200
+Subject: [PATCH 5/5] OvmfPkg: QemuVideoDxe: enable debug messages in VbeShim
+
+Contributed-under: TianoCore Contribution Agreement 1.0
+---
+ OvmfPkg/QemuVideoDxe/VbeShim.asm |   2 +-
+ OvmfPkg/QemuVideoDxe/VbeShim.h   | 481 +++++++++++++++++++++++++--------------
+ 2 files changed, 308 insertions(+), 175 deletions(-)
+
+diff --git a/OvmfPkg/QemuVideoDxe/VbeShim.asm b/OvmfPkg/QemuVideoDxe/VbeShim.asm
+index 18fa920..9a185f2 100644
+--- a/OvmfPkg/QemuVideoDxe/VbeShim.asm
++++ b/OvmfPkg/QemuVideoDxe/VbeShim.asm
+@@ -18,7 +18,7 @@
+ ;------------------------------------------------------------------------------
+ 
+ ; enable this macro for debug messages
+-;%define DEBUG
++%define DEBUG
+ 
+ %macro DebugLog 1
+ %ifdef DEBUG
+diff --git a/OvmfPkg/QemuVideoDxe/VbeShim.h b/OvmfPkg/QemuVideoDxe/VbeShim.h
+index cc9b6e1..db37f1d 100644
+--- a/OvmfPkg/QemuVideoDxe/VbeShim.h
++++ b/OvmfPkg/QemuVideoDxe/VbeShim.h
+@@ -517,185 +517,318 @@ STATIC CONST UINT8 mVbeShim[] = {
+   /* 000001FE nop                            */  0x90,
+   /* 000001FF nop                            */  0x90,
+   /* 00000200 cmp ax,0x4f00                  */  0x3D, 0x00, 0x4F,
+-  /* 00000203 jz 0x22d                       */  0x74, 0x28,
++  /* 00000203 jz 0x235                       */  0x74, 0x30,
+   /* 00000205 cmp ax,0x4f01                  */  0x3D, 0x01, 0x4F,
+-  /* 00000208 jz 0x245                       */  0x74, 0x3B,
++  /* 00000208 jz 0x255                       */  0x74, 0x4B,
+   /* 0000020A cmp ax,0x4f02                  */  0x3D, 0x02, 0x4F,
+-  /* 0000020D jz 0x269                       */  0x74, 0x5A,
++  /* 0000020D jz 0x289                       */  0x74, 0x7A,
+   /* 0000020F cmp ax,0x4f03                  */  0x3D, 0x03, 0x4F,
+-  /* 00000212 jz word 0x331                  */  0x0F, 0x84, 0x1B, 0x01,
++  /* 00000212 jz word 0x361                  */  0x0F, 0x84, 0x4B, 0x01,
+   /* 00000216 cmp ax,0x4f10                  */  0x3D, 0x10, 0x4F,
+-  /* 00000219 jz word 0x336                  */  0x0F, 0x84, 0x19, 0x01,
++  /* 00000219 jz word 0x36e                  */  0x0F, 0x84, 0x51, 0x01,
+   /* 0000021D cmp ax,0x4f15                  */  0x3D, 0x15, 0x4F,
+-  /* 00000220 jz word 0x338                  */  0x0F, 0x84, 0x14, 0x01,
++  /* 00000220 jz word 0x378                  */  0x0F, 0x84, 0x54, 0x01,
+   /* 00000224 cmp ah,0x0                     */  0x80, 0xFC, 0x00,
+-  /* 00000227 jz word 0x33a                  */  0x0F, 0x84, 0x0F, 0x01,
+-  /* 0000022B jmp short 0x22b                */  0xEB, 0xFE,
+-  /* 0000022D push es                        */  0x06,
+-  /* 0000022E push di                        */  0x57,
+-  /* 0000022F push ds                        */  0x1E,
+-  /* 00000230 push si                        */  0x56,
+-  /* 00000231 push cx                        */  0x51,
+-  /* 00000232 push cs                        */  0x0E,
+-  /* 00000233 pop ds                         */  0x1F,
+-  /* 00000234 mov si,0x0                     */  0xBE, 0x00, 0x00,
+-  /* 00000237 mov cx,0x100                   */  0xB9, 0x00, 0x01,
+-  /* 0000023A cld                            */  0xFC,
+-  /* 0000023B rep movsb                      */  0xF3, 0xA4,
+-  /* 0000023D pop cx                         */  0x59,
+-  /* 0000023E pop si                         */  0x5E,
+-  /* 0000023F pop ds                         */  0x1F,
+-  /* 00000240 pop di                         */  0x5F,
+-  /* 00000241 pop es                         */  0x07,
+-  /* 00000242 jmp word 0x34c                 */  0xE9, 0x07, 0x01,
+-  /* 00000245 push es                        */  0x06,
+-  /* 00000246 push di                        */  0x57,
+-  /* 00000247 push ds                        */  0x1E,
+-  /* 00000248 push si                        */  0x56,
+-  /* 00000249 push cx                        */  0x51,
+-  /* 0000024A and cx,0xbfff                  */  0x81, 0xE1, 0xFF, 0xBF,
+-  /* 0000024E cmp cx,0xf1                    */  0x81, 0xF9, 0xF1, 0x00,
+-  /* 00000252 jz 0x256                       */  0x74, 0x02,
+-  /* 00000254 jmp short 0x22b                */  0xEB, 0xD5,
+-  /* 00000256 push cs                        */  0x0E,
+-  /* 00000257 pop ds                         */  0x1F,
+-  /* 00000258 mov si,0x100                   */  0xBE, 0x00, 0x01,
+-  /* 0000025B mov cx,0x100                   */  0xB9, 0x00, 0x01,
+-  /* 0000025E cld                            */  0xFC,
+-  /* 0000025F rep movsb                      */  0xF3, 0xA4,
+-  /* 00000261 pop cx                         */  0x59,
+-  /* 00000262 pop si                         */  0x5E,
+-  /* 00000263 pop ds                         */  0x1F,
+-  /* 00000264 pop di                         */  0x5F,
+-  /* 00000265 pop es                         */  0x07,
+-  /* 00000266 jmp word 0x34c                 */  0xE9, 0xE3, 0x00,
+-  /* 00000269 push dx                        */  0x52,
+-  /* 0000026A push ax                        */  0x50,
+-  /* 0000026B cmp bx,0x40f1                  */  0x81, 0xFB, 0xF1, 0x40,
+-  /* 0000026F jz 0x273                       */  0x74, 0x02,
+-  /* 00000271 jmp short 0x22b                */  0xEB, 0xB8,
+-  /* 00000273 mov dx,0x3c0                   */  0xBA, 0xC0, 0x03,
+-  /* 00000276 mov al,0x20                    */  0xB0, 0x20,
+-  /* 00000278 out dx,al                      */  0xEE,
+-  /* 00000279 push dx                        */  0x52,
+-  /* 0000027A push ax                        */  0x50,
+-  /* 0000027B mov dx,0x1ce                   */  0xBA, 0xCE, 0x01,
+-  /* 0000027E mov ax,0x4                     */  0xB8, 0x04, 0x00,
+-  /* 00000281 out dx,ax                      */  0xEF,
+-  /* 00000282 mov dx,0x1d0                   */  0xBA, 0xD0, 0x01,
+-  /* 00000285 mov ax,0x0                     */  0xB8, 0x00, 0x00,
+-  /* 00000288 out dx,ax                      */  0xEF,
+-  /* 00000289 pop ax                         */  0x58,
+-  /* 0000028A pop dx                         */  0x5A,
+-  /* 0000028B push dx                        */  0x52,
+-  /* 0000028C push ax                        */  0x50,
+-  /* 0000028D mov dx,0x1ce                   */  0xBA, 0xCE, 0x01,
+-  /* 00000290 mov ax,0x5                     */  0xB8, 0x05, 0x00,
+-  /* 00000293 out dx,ax                      */  0xEF,
+-  /* 00000294 mov dx,0x1d0                   */  0xBA, 0xD0, 0x01,
+-  /* 00000297 mov ax,0x0                     */  0xB8, 0x00, 0x00,
+-  /* 0000029A out dx,ax                      */  0xEF,
+-  /* 0000029B pop ax                         */  0x58,
+-  /* 0000029C pop dx                         */  0x5A,
+-  /* 0000029D push dx                        */  0x52,
+-  /* 0000029E push ax                        */  0x50,
+-  /* 0000029F mov dx,0x1ce                   */  0xBA, 0xCE, 0x01,
+-  /* 000002A2 mov ax,0x8                     */  0xB8, 0x08, 0x00,
+-  /* 000002A5 out dx,ax                      */  0xEF,
+-  /* 000002A6 mov dx,0x1d0                   */  0xBA, 0xD0, 0x01,
+-  /* 000002A9 mov ax,0x0                     */  0xB8, 0x00, 0x00,
+-  /* 000002AC out dx,ax                      */  0xEF,
+-  /* 000002AD pop ax                         */  0x58,
+-  /* 000002AE pop dx                         */  0x5A,
+-  /* 000002AF push dx                        */  0x52,
+-  /* 000002B0 push ax                        */  0x50,
+-  /* 000002B1 mov dx,0x1ce                   */  0xBA, 0xCE, 0x01,
+-  /* 000002B4 mov ax,0x9                     */  0xB8, 0x09, 0x00,
+-  /* 000002B7 out dx,ax                      */  0xEF,
+-  /* 000002B8 mov dx,0x1d0                   */  0xBA, 0xD0, 0x01,
+-  /* 000002BB mov ax,0x0                     */  0xB8, 0x00, 0x00,
+-  /* 000002BE out dx,ax                      */  0xEF,
+-  /* 000002BF pop ax                         */  0x58,
+-  /* 000002C0 pop dx                         */  0x5A,
+-  /* 000002C1 push dx                        */  0x52,
+-  /* 000002C2 push ax                        */  0x50,
+-  /* 000002C3 mov dx,0x1ce                   */  0xBA, 0xCE, 0x01,
+-  /* 000002C6 mov ax,0x3                     */  0xB8, 0x03, 0x00,
+-  /* 000002C9 out dx,ax                      */  0xEF,
+-  /* 000002CA mov dx,0x1d0                   */  0xBA, 0xD0, 0x01,
+-  /* 000002CD mov ax,0x20                    */  0xB8, 0x20, 0x00,
+-  /* 000002D0 out dx,ax                      */  0xEF,
+-  /* 000002D1 pop ax                         */  0x58,
+-  /* 000002D2 pop dx                         */  0x5A,
+-  /* 000002D3 push dx                        */  0x52,
+-  /* 000002D4 push ax                        */  0x50,
+-  /* 000002D5 mov dx,0x1ce                   */  0xBA, 0xCE, 0x01,
+-  /* 000002D8 mov ax,0x1                     */  0xB8, 0x01, 0x00,
+-  /* 000002DB out dx,ax                      */  0xEF,
+-  /* 000002DC mov dx,0x1d0                   */  0xBA, 0xD0, 0x01,
+-  /* 000002DF mov ax,0x400                   */  0xB8, 0x00, 0x04,
+-  /* 000002E2 out dx,ax                      */  0xEF,
+-  /* 000002E3 pop ax                         */  0x58,
+-  /* 000002E4 pop dx                         */  0x5A,
+-  /* 000002E5 push dx                        */  0x52,
+-  /* 000002E6 push ax                        */  0x50,
+-  /* 000002E7 mov dx,0x1ce                   */  0xBA, 0xCE, 0x01,
+-  /* 000002EA mov ax,0x6                     */  0xB8, 0x06, 0x00,
+-  /* 000002ED out dx,ax                      */  0xEF,
+-  /* 000002EE mov dx,0x1d0                   */  0xBA, 0xD0, 0x01,
+-  /* 000002F1 mov ax,0x400                   */  0xB8, 0x00, 0x04,
+-  /* 000002F4 out dx,ax                      */  0xEF,
+-  /* 000002F5 pop ax                         */  0x58,
+-  /* 000002F6 pop dx                         */  0x5A,
+-  /* 000002F7 push dx                        */  0x52,
+-  /* 000002F8 push ax                        */  0x50,
+-  /* 000002F9 mov dx,0x1ce                   */  0xBA, 0xCE, 0x01,
+-  /* 000002FC mov ax,0x2                     */  0xB8, 0x02, 0x00,
+-  /* 000002FF out dx,ax                      */  0xEF,
+-  /* 00000300 mov dx,0x1d0                   */  0xBA, 0xD0, 0x01,
+-  /* 00000303 mov ax,0x300                   */  0xB8, 0x00, 0x03,
+-  /* 00000306 out dx,ax                      */  0xEF,
+-  /* 00000307 pop ax                         */  0x58,
+-  /* 00000308 pop dx                         */  0x5A,
+-  /* 00000309 push dx                        */  0x52,
+-  /* 0000030A push ax                        */  0x50,
+-  /* 0000030B mov dx,0x1ce                   */  0xBA, 0xCE, 0x01,
+-  /* 0000030E mov ax,0x7                     */  0xB8, 0x07, 0x00,
+-  /* 00000311 out dx,ax                      */  0xEF,
+-  /* 00000312 mov dx,0x1d0                   */  0xBA, 0xD0, 0x01,
+-  /* 00000315 mov ax,0x300                   */  0xB8, 0x00, 0x03,
+-  /* 00000318 out dx,ax                      */  0xEF,
+-  /* 00000319 pop ax                         */  0x58,
+-  /* 0000031A pop dx                         */  0x5A,
+-  /* 0000031B push dx                        */  0x52,
+-  /* 0000031C push ax                        */  0x50,
+-  /* 0000031D mov dx,0x1ce                   */  0xBA, 0xCE, 0x01,
+-  /* 00000320 mov ax,0x4                     */  0xB8, 0x04, 0x00,
+-  /* 00000323 out dx,ax                      */  0xEF,
+-  /* 00000324 mov dx,0x1d0                   */  0xBA, 0xD0, 0x01,
+-  /* 00000327 mov ax,0x41                    */  0xB8, 0x41, 0x00,
+-  /* 0000032A out dx,ax                      */  0xEF,
+-  /* 0000032B pop ax                         */  0x58,
+-  /* 0000032C pop dx                         */  0x5A,
+-  /* 0000032D pop ax                         */  0x58,
+-  /* 0000032E pop dx                         */  0x5A,
+-  /* 0000032F jmp short 0x34c                */  0xEB, 0x1B,
+-  /* 00000331 mov bx,0x40f1                  */  0xBB, 0xF1, 0x40,
+-  /* 00000334 jmp short 0x34c                */  0xEB, 0x16,
+-  /* 00000336 jmp short 0x350                */  0xEB, 0x18,
+-  /* 00000338 jmp short 0x350                */  0xEB, 0x16,
+-  /* 0000033A cmp al,0x3                     */  0x3C, 0x03,
+-  /* 0000033C jz 0x345                       */  0x74, 0x07,
+-  /* 0000033E cmp al,0x12                    */  0x3C, 0x12,
+-  /* 00000340 jz 0x349                       */  0x74, 0x07,
+-  /* 00000342 jmp word 0x22b                 */  0xE9, 0xE6, 0xFE,
+-  /* 00000345 mov al,0x30                    */  0xB0, 0x30,
+-  /* 00000347 jmp short 0x34b                */  0xEB, 0x02,
+-  /* 00000349 mov al,0x20                    */  0xB0, 0x20,
+-  /* 0000034B iretw                          */  0xCF,
+-  /* 0000034C mov ax,0x4f                    */  0xB8, 0x4F, 0x00,
+-  /* 0000034F iretw                          */  0xCF,
+-  /* 00000350 mov ax,0x14f                   */  0xB8, 0x4F, 0x01,
+-  /* 00000353 iretw                          */  0xCF,
++  /* 00000227 jz word 0x382                  */  0x0F, 0x84, 0x57, 0x01,
++  /* 0000022B push si                        */  0x56,
++  /* 0000022C mov si,0x3e9                   */  0xBE, 0xE9, 0x03,
++  /* 0000022F call word 0x3c4                */  0xE8, 0x92, 0x01,
++  /* 00000232 pop si                         */  0x5E,
++  /* 00000233 jmp short 0x233                */  0xEB, 0xFE,
++  /* 00000235 push es                        */  0x06,
++  /* 00000236 push di                        */  0x57,
++  /* 00000237 push ds                        */  0x1E,
++  /* 00000238 push si                        */  0x56,
++  /* 00000239 push cx                        */  0x51,
++  /* 0000023A push si                        */  0x56,
++  /* 0000023B mov si,0x3fb                   */  0xBE, 0xFB, 0x03,
++  /* 0000023E call word 0x3c4                */  0xE8, 0x83, 0x01,
++  /* 00000241 pop si                         */  0x5E,
++  /* 00000242 push cs                        */  0x0E,
++  /* 00000243 pop ds                         */  0x1F,
++  /* 00000244 mov si,0x0                     */  0xBE, 0x00, 0x00,
++  /* 00000247 mov cx,0x100                   */  0xB9, 0x00, 0x01,
++  /* 0000024A cld                            */  0xFC,
++  /* 0000024B rep movsb                      */  0xF3, 0xA4,
++  /* 0000024D pop cx                         */  0x59,
++  /* 0000024E pop si                         */  0x5E,
++  /* 0000024F pop ds                         */  0x1F,
++  /* 00000250 pop di                         */  0x5F,
++  /* 00000251 pop es                         */  0x07,
++  /* 00000252 jmp word 0x3ac                 */  0xE9, 0x57, 0x01,
++  /* 00000255 push es                        */  0x06,
++  /* 00000256 push di                        */  0x57,
++  /* 00000257 push ds                        */  0x1E,
++  /* 00000258 push si                        */  0x56,
++  /* 00000259 push cx                        */  0x51,
++  /* 0000025A push si                        */  0x56,
++  /* 0000025B mov si,0x404                   */  0xBE, 0x04, 0x04,
++  /* 0000025E call word 0x3c4                */  0xE8, 0x63, 0x01,
++  /* 00000261 pop si                         */  0x5E,
++  /* 00000262 and cx,0xbfff                  */  0x81, 0xE1, 0xFF, 0xBF,
++  /* 00000266 cmp cx,0xf1                    */  0x81, 0xF9, 0xF1, 0x00,
++  /* 0000026A jz 0x276                       */  0x74, 0x0A,
++  /* 0000026C push si                        */  0x56,
++  /* 0000026D mov si,0x432                   */  0xBE, 0x32, 0x04,
++  /* 00000270 call word 0x3c4                */  0xE8, 0x51, 0x01,
++  /* 00000273 pop si                         */  0x5E,
++  /* 00000274 jmp short 0x233                */  0xEB, 0xBD,
++  /* 00000276 push cs                        */  0x0E,
++  /* 00000277 pop ds                         */  0x1F,
++  /* 00000278 mov si,0x100                   */  0xBE, 0x00, 0x01,
++  /* 0000027B mov cx,0x100                   */  0xB9, 0x00, 0x01,
++  /* 0000027E cld                            */  0xFC,
++  /* 0000027F rep movsb                      */  0xF3, 0xA4,
++  /* 00000281 pop cx                         */  0x59,
++  /* 00000282 pop si                         */  0x5E,
++  /* 00000283 pop ds                         */  0x1F,
++  /* 00000284 pop di                         */  0x5F,
++  /* 00000285 pop es                         */  0x07,
++  /* 00000286 jmp word 0x3ac                 */  0xE9, 0x23, 0x01,
++  /* 00000289 push dx                        */  0x52,
++  /* 0000028A push ax                        */  0x50,
++  /* 0000028B push si                        */  0x56,
++  /* 0000028C mov si,0x41a                   */  0xBE, 0x1A, 0x04,
++  /* 0000028F call word 0x3c4                */  0xE8, 0x32, 0x01,
++  /* 00000292 pop si                         */  0x5E,
++  /* 00000293 cmp bx,0x40f1                  */  0x81, 0xFB, 0xF1, 0x40,
++  /* 00000297 jz 0x2a3                       */  0x74, 0x0A,
++  /* 00000299 push si                        */  0x56,
++  /* 0000029A mov si,0x432                   */  0xBE, 0x32, 0x04,
++  /* 0000029D call word 0x3c4                */  0xE8, 0x24, 0x01,
++  /* 000002A0 pop si                         */  0x5E,
++  /* 000002A1 jmp short 0x233                */  0xEB, 0x90,
++  /* 000002A3 mov dx,0x3c0                   */  0xBA, 0xC0, 0x03,
++  /* 000002A6 mov al,0x20                    */  0xB0, 0x20,
++  /* 000002A8 out dx,al                      */  0xEE,
++  /* 000002A9 push dx                        */  0x52,
++  /* 000002AA push ax                        */  0x50,
++  /* 000002AB mov dx,0x1ce                   */  0xBA, 0xCE, 0x01,
++  /* 000002AE mov ax,0x4                     */  0xB8, 0x04, 0x00,
++  /* 000002B1 out dx,ax                      */  0xEF,
++  /* 000002B2 mov dx,0x1d0                   */  0xBA, 0xD0, 0x01,
++  /* 000002B5 mov ax,0x0                     */  0xB8, 0x00, 0x00,
++  /* 000002B8 out dx,ax                      */  0xEF,
++  /* 000002B9 pop ax                         */  0x58,
++  /* 000002BA pop dx                         */  0x5A,
++  /* 000002BB push dx                        */  0x52,
++  /* 000002BC push ax                        */  0x50,
++  /* 000002BD mov dx,0x1ce                   */  0xBA, 0xCE, 0x01,
++  /* 000002C0 mov ax,0x5                     */  0xB8, 0x05, 0x00,
++  /* 000002C3 out dx,ax                      */  0xEF,
++  /* 000002C4 mov dx,0x1d0                   */  0xBA, 0xD0, 0x01,
++  /* 000002C7 mov ax,0x0                     */  0xB8, 0x00, 0x00,
++  /* 000002CA out dx,ax                      */  0xEF,
++  /* 000002CB pop ax                         */  0x58,
++  /* 000002CC pop dx                         */  0x5A,
++  /* 000002CD push dx                        */  0x52,
++  /* 000002CE push ax                        */  0x50,
++  /* 000002CF mov dx,0x1ce                   */  0xBA, 0xCE, 0x01,
++  /* 000002D2 mov ax,0x8                     */  0xB8, 0x08, 0x00,
++  /* 000002D5 out dx,ax                      */  0xEF,
++  /* 000002D6 mov dx,0x1d0                   */  0xBA, 0xD0, 0x01,
++  /* 000002D9 mov ax,0x0                     */  0xB8, 0x00, 0x00,
++  /* 000002DC out dx,ax                      */  0xEF,
++  /* 000002DD pop ax                         */  0x58,
++  /* 000002DE pop dx                         */  0x5A,
++  /* 000002DF push dx                        */  0x52,
++  /* 000002E0 push ax                        */  0x50,
++  /* 000002E1 mov dx,0x1ce                   */  0xBA, 0xCE, 0x01,
++  /* 000002E4 mov ax,0x9                     */  0xB8, 0x09, 0x00,
++  /* 000002E7 out dx,ax                      */  0xEF,
++  /* 000002E8 mov dx,0x1d0                   */  0xBA, 0xD0, 0x01,
++  /* 000002EB mov ax,0x0                     */  0xB8, 0x00, 0x00,
++  /* 000002EE out dx,ax                      */  0xEF,
++  /* 000002EF pop ax                         */  0x58,
++  /* 000002F0 pop dx                         */  0x5A,
++  /* 000002F1 push dx                        */  0x52,
++  /* 000002F2 push ax                        */  0x50,
++  /* 000002F3 mov dx,0x1ce                   */  0xBA, 0xCE, 0x01,
++  /* 000002F6 mov ax,0x3                     */  0xB8, 0x03, 0x00,
++  /* 000002F9 out dx,ax                      */  0xEF,
++  /* 000002FA mov dx,0x1d0                   */  0xBA, 0xD0, 0x01,
++  /* 000002FD mov ax,0x20                    */  0xB8, 0x20, 0x00,
++  /* 00000300 out dx,ax                      */  0xEF,
++  /* 00000301 pop ax                         */  0x58,
++  /* 00000302 pop dx                         */  0x5A,
++  /* 00000303 push dx                        */  0x52,
++  /* 00000304 push ax                        */  0x50,
++  /* 00000305 mov dx,0x1ce                   */  0xBA, 0xCE, 0x01,
++  /* 00000308 mov ax,0x1                     */  0xB8, 0x01, 0x00,
++  /* 0000030B out dx,ax                      */  0xEF,
++  /* 0000030C mov dx,0x1d0                   */  0xBA, 0xD0, 0x01,
++  /* 0000030F mov ax,0x400                   */  0xB8, 0x00, 0x04,
++  /* 00000312 out dx,ax                      */  0xEF,
++  /* 00000313 pop ax                         */  0x58,
++  /* 00000314 pop dx                         */  0x5A,
++  /* 00000315 push dx                        */  0x52,
++  /* 00000316 push ax                        */  0x50,
++  /* 00000317 mov dx,0x1ce                   */  0xBA, 0xCE, 0x01,
++  /* 0000031A mov ax,0x6                     */  0xB8, 0x06, 0x00,
++  /* 0000031D out dx,ax                      */  0xEF,
++  /* 0000031E mov dx,0x1d0                   */  0xBA, 0xD0, 0x01,
++  /* 00000321 mov ax,0x400                   */  0xB8, 0x00, 0x04,
++  /* 00000324 out dx,ax                      */  0xEF,
++  /* 00000325 pop ax                         */  0x58,
++  /* 00000326 pop dx                         */  0x5A,
++  /* 00000327 push dx                        */  0x52,
++  /* 00000328 push ax                        */  0x50,
++  /* 00000329 mov dx,0x1ce                   */  0xBA, 0xCE, 0x01,
++  /* 0000032C mov ax,0x2                     */  0xB8, 0x02, 0x00,
++  /* 0000032F out dx,ax                      */  0xEF,
++  /* 00000330 mov dx,0x1d0                   */  0xBA, 0xD0, 0x01,
++  /* 00000333 mov ax,0x300                   */  0xB8, 0x00, 0x03,
++  /* 00000336 out dx,ax                      */  0xEF,
++  /* 00000337 pop ax                         */  0x58,
++  /* 00000338 pop dx                         */  0x5A,
++  /* 00000339 push dx                        */  0x52,
++  /* 0000033A push ax                        */  0x50,
++  /* 0000033B mov dx,0x1ce                   */  0xBA, 0xCE, 0x01,
++  /* 0000033E mov ax,0x7                     */  0xB8, 0x07, 0x00,
++  /* 00000341 out dx,ax                      */  0xEF,
++  /* 00000342 mov dx,0x1d0                   */  0xBA, 0xD0, 0x01,
++  /* 00000345 mov ax,0x300                   */  0xB8, 0x00, 0x03,
++  /* 00000348 out dx,ax                      */  0xEF,
++  /* 00000349 pop ax                         */  0x58,
++  /* 0000034A pop dx                         */  0x5A,
++  /* 0000034B push dx                        */  0x52,
++  /* 0000034C push ax                        */  0x50,
++  /* 0000034D mov dx,0x1ce                   */  0xBA, 0xCE, 0x01,
++  /* 00000350 mov ax,0x4                     */  0xB8, 0x04, 0x00,
++  /* 00000353 out dx,ax                      */  0xEF,
++  /* 00000354 mov dx,0x1d0                   */  0xBA, 0xD0, 0x01,
++  /* 00000357 mov ax,0x41                    */  0xB8, 0x41, 0x00,
++  /* 0000035A out dx,ax                      */  0xEF,
++  /* 0000035B pop ax                         */  0x58,
++  /* 0000035C pop dx                         */  0x5A,
++  /* 0000035D pop ax                         */  0x58,
++  /* 0000035E pop dx                         */  0x5A,
++  /* 0000035F jmp short 0x3ac                */  0xEB, 0x4B,
++  /* 00000361 push si                        */  0x56,
++  /* 00000362 mov si,0x411                   */  0xBE, 0x11, 0x04,
++  /* 00000365 call word 0x3c4                */  0xE8, 0x5C, 0x00,
++  /* 00000368 pop si                         */  0x5E,
++  /* 00000369 mov bx,0x40f1                  */  0xBB, 0xF1, 0x40,
++  /* 0000036C jmp short 0x3ac                */  0xEB, 0x3E,
++  /* 0000036E push si                        */  0x56,
++  /* 0000036F mov si,0x43f                   */  0xBE, 0x3F, 0x04,
++  /* 00000372 call word 0x3c4                */  0xE8, 0x4F, 0x00,
++  /* 00000375 pop si                         */  0x5E,
++  /* 00000376 jmp short 0x3b8                */  0xEB, 0x40,
++  /* 00000378 push si                        */  0x56,
++  /* 00000379 mov si,0x452                   */  0xBE, 0x52, 0x04,
++  /* 0000037C call word 0x3c4                */  0xE8, 0x45, 0x00,
++  /* 0000037F pop si                         */  0x5E,
++  /* 00000380 jmp short 0x3b8                */  0xEB, 0x36,
++  /* 00000382 push si                        */  0x56,
++  /* 00000383 mov si,0x423                   */  0xBE, 0x23, 0x04,
++  /* 00000386 call word 0x3c4                */  0xE8, 0x3B, 0x00,
++  /* 00000389 pop si                         */  0x5E,
++  /* 0000038A cmp al,0x3                     */  0x3C, 0x03,
++  /* 0000038C jz 0x39d                       */  0x74, 0x0F,
++  /* 0000038E cmp al,0x12                    */  0x3C, 0x12,
++  /* 00000390 jz 0x3a1                       */  0x74, 0x0F,
++  /* 00000392 push si                        */  0x56,
++  /* 00000393 mov si,0x432                   */  0xBE, 0x32, 0x04,
++  /* 00000396 call word 0x3c4                */  0xE8, 0x2B, 0x00,
++  /* 00000399 pop si                         */  0x5E,
++  /* 0000039A jmp word 0x233                 */  0xE9, 0x96, 0xFE,
++  /* 0000039D mov al,0x30                    */  0xB0, 0x30,
++  /* 0000039F jmp short 0x3a3                */  0xEB, 0x02,
++  /* 000003A1 mov al,0x20                    */  0xB0, 0x20,
++  /* 000003A3 push si                        */  0x56,
++  /* 000003A4 mov si,0x3d6                   */  0xBE, 0xD6, 0x03,
++  /* 000003A7 call word 0x3c4                */  0xE8, 0x1A, 0x00,
++  /* 000003AA pop si                         */  0x5E,
++  /* 000003AB iretw                          */  0xCF,
++  /* 000003AC push si                        */  0x56,
++  /* 000003AD mov si,0x3d6                   */  0xBE, 0xD6, 0x03,
++  /* 000003B0 call word 0x3c4                */  0xE8, 0x11, 0x00,
++  /* 000003B3 pop si                         */  0x5E,
++  /* 000003B4 mov ax,0x4f                    */  0xB8, 0x4F, 0x00,
++  /* 000003B7 iretw                          */  0xCF,
++  /* 000003B8 push si                        */  0x56,
++  /* 000003B9 mov si,0x3dc                   */  0xBE, 0xDC, 0x03,
++  /* 000003BC call word 0x3c4                */  0xE8, 0x05, 0x00,
++  /* 000003BF pop si                         */  0x5E,
++  /* 000003C0 mov ax,0x14f                   */  0xB8, 0x4F, 0x01,
++  /* 000003C3 iretw                          */  0xCF,
++  /* 000003C4 pushaw                         */  0x60,
++  /* 000003C5 push ds                        */  0x1E,
++  /* 000003C6 push cs                        */  0x0E,
++  /* 000003C7 pop ds                         */  0x1F,
++  /* 000003C8 mov dx,0x402                   */  0xBA, 0x02, 0x04,
++  /* 000003CB lodsb                          */  0xAC,
++  /* 000003CC cmp al,0x0                     */  0x3C, 0x00,
++  /* 000003CE jz 0x3d3                       */  0x74, 0x03,
++  /* 000003D0 out dx,al                      */  0xEE,
++  /* 000003D1 jmp short 0x3cb                */  0xEB, 0xF8,
++  /* 000003D3 pop ds                         */  0x1F,
++  /* 000003D4 popaw                          */  0x61,
++  /* 000003D5 ret                            */  0xC3,
++  /* 000003D6 inc bp                         */  0x45,
++  /* 000003D7 js 0x442                       */  0x78, 0x69,
++  /* 000003D9 jz 0x3e5                       */  0x74, 0x0A,
++  /* 000003DB add [di+0x6e],dl               */  0x00, 0x55, 0x6E,
++  /* 000003DE jnc 0x455                      */  0x73, 0x75,
++  /* 000003E0 jo 0x452                       */  0x70, 0x70,
++  /* 000003E2 outsw                          */  0x6F,
++  /* 000003E3 jc 0x459                       */  0x72, 0x74,
++  /* 000003E5 or al,[fs:bx+si]               */  0x65, 0x64, 0x0A, 0x00,
++  /* 000003E9 push bp                        */  0x55,
++  /* 000003EA outsb                          */  0x6E,
++  /* 000003EB imul bp,[bp+0x6f],byte +0x77   */  0x6B, 0x6E, 0x6F, 0x77,
++  /* 000003EF outsb                          */  0x6E,
++  /* 000003F0 and [bp+0x75],al               */  0x20, 0x46, 0x75,
++  /* 000003F3 outsb                          */  0x6E,
++  /* 000003F4 arpl [si+0x69],si              */  0x63, 0x74, 0x69,
++  /* 000003F7 outsw                          */  0x6F,
++  /* 000003F8 outsb                          */  0x6E,
++  /* 000003F9 or al,[bx+si]                  */  0x0A, 0x00,
++  /* 000003FB inc di                         */  0x47,
++  /* 000003FC gs jz 0x448                    */  0x65, 0x74, 0x49,
++  /* 000003FF outsb                          */  0x6E,
++  /* 00000400 outsd                          */  0x66, 0x6F,
++  /* 00000402 or al,[bx+si]                  */  0x0A, 0x00,
++  /* 00000404 inc di                         */  0x47,
++  /* 00000405 gs jz 0x455                    */  0x65, 0x74, 0x4D,
++  /* 00000408 outsw                          */  0x6F,
++  /* 00000409 gs dec cx                      */  0x64, 0x65, 0x49,
++  /* 0000040C outsb                          */  0x6E,
++  /* 0000040D outsd                          */  0x66, 0x6F,
++  /* 0000040F or al,[bx+si]                  */  0x0A, 0x00,
++  /* 00000411 inc di                         */  0x47,
++  /* 00000412 gs jz 0x462                    */  0x65, 0x74, 0x4D,
++  /* 00000415 outsw                          */  0x6F,
++  /* 00000416 or al,[gs:bx+si]               */  0x64, 0x65, 0x0A, 0x00,
++  /* 0000041A push bx                        */  0x53,
++  /* 0000041B gs jz 0x46b                    */  0x65, 0x74, 0x4D,
++  /* 0000041E outsw                          */  0x6F,
++  /* 0000041F or al,[gs:bx+si]               */  0x64, 0x65, 0x0A, 0x00,
++  /* 00000423 push bx                        */  0x53,
++  /* 00000424 gs jz 0x474                    */  0x65, 0x74, 0x4D,
++  /* 00000427 outsw                          */  0x6F,
++  /* 00000428 gs dec sp                      */  0x64, 0x65, 0x4C,
++  /* 0000042B gs a32 popaw                   */  0x65, 0x67, 0x61,
++  /* 0000042E arpl [bx+di+0xa],di            */  0x63, 0x79, 0x0A,
++  /* 00000431 add [di+0x6e],dl               */  0x00, 0x55, 0x6E,
++  /* 00000434 imul bp,[bx+0x77],byte +0x6e   */  0x6B, 0x6F, 0x77, 0x6E,
++  /* 00000438 and [di+0x6f],cl               */  0x20, 0x4D, 0x6F,
++  /* 0000043B or al,[gs:bx+si]               */  0x64, 0x65, 0x0A, 0x00,
++  /* 0000043F inc di                         */  0x47,
++  /* 00000440 gs jz 0x493                    */  0x65, 0x74, 0x50,
++  /* 00000443 insw                           */  0x6D,
++  /* 00000444 inc bx                         */  0x43,
++  /* 00000445 popaw                          */  0x61,
++  /* 00000446 jo 0x4a9                       */  0x70, 0x61,
++  /* 00000448 bound bp,[bx+di+0x6c]          */  0x62, 0x69, 0x6C,
++  /* 0000044B imul si,[si+0x69],word 0x7365  */  0x69, 0x74, 0x69, 0x65, 0x73,
++  /* 00000450 or al,[bx+si]                  */  0x0A, 0x00,
++  /* 00000452 push dx                        */  0x52,
++  /* 00000453 gs popaw                       */  0x65, 0x61,
++  /* 00000455 fs inc bp                      */  0x64, 0x45,
++  /* 00000457 fs                             */  0x64,
++  /* 00000458 db 0x69                        */  0x69,
++  /* 00000459 or al,[fs:bx+si]               */  0x64, 0x0A, 0x00,
+ };
+ #endif
+-- 
+1.8.3.1
+
diff --git a/basetools-arm.patch b/basetools-arm.patch
deleted file mode 100644
index 85f2613..0000000
--- a/basetools-arm.patch
+++ /dev/null
@@ -1,14 +0,0 @@
-diff --git a/Source/C/GNUmakefile b/Source/C/GNUmakefile
-index e0dde3e..bee0059 100644
---- a/Source/C/GNUmakefile
-+++ b/Source/C/GNUmakefile
-@@ -22,6 +22,9 @@ ifndef ARCH
-   ifneq (,$(strip $(filter $(uname_m), x86_64 amd64)))
-     ARCH=X64
-   endif
-+  ifeq ($(patsubst arm%,ARM,$(uname_m)),ARM)
-+    ARCH=ARM
-+  endif
-   ifeq ($(patsubst i%86,IA32,$(uname_m)),IA32)
-     ARCH=IA32
-   endif
diff --git a/edk2.spec b/edk2.spec
index 321c4e7..4989f12 100644
--- a/edk2.spec
+++ b/edk2.spec
@@ -1,35 +1,52 @@
-%global SVNDATE   20151127
-%global SVNREV    18975
+%global edk2_date        20160418
+%global edk2_githash     a8c39ba
+%global openssl_version  1.0.2g
 
 Name:           edk2
-Version:        %{SVNDATE}svn%{SVNREV}
-Release:        3%{?dist}
+Version:        %{edk2_date}git%{edk2_githash}
+Release:        0%{dist}
 Summary:        EFI Development Kit II
 
-# There are no formal releases from upstream.
-# Tarballs are created with:
-
-# svn export -r ${SVNREV} \
-#     https://svn.code.sf.net/p/edk2/code/trunk/edk2/BaseTools edk2-buildtools-r${SVNREV}
-# rm -rf edk2-buildtools-r${SVNREV}/Bin
-# tar -cv edk2-buildtools-r${SVNREV} | xz -6 > edk2-buildtools-r${SVNREV}.tar.xz
-Source0:        edk2-buildtools-r%{SVNREV}.tar.xz
-Patch1:         basetools-arm.patch
-Patch2:         0001-BaseTools-LzmaCompress-eliminate-_maxMode-and-bogus-.patch
-
-License:        BSD
 Group:          Applications/Emulators
-URL:            http://sourceforge.net/apps/mediawiki/tianocore/index.php?title=EDK2
-
-# We need to build tools everywhere, but how is still an open question
-# https://bugzilla.redhat.com/show_bug.cgi?id=992180
-ExclusiveArch:  %{ix86} x86_64 %{arm}
-
-BuildRequires:  python2-devel
+License:        BSD
+URL:            http://www.tianocore.org/edk2/
+Source0:        edk2-%{edk2_date}-%{edk2_githash}.tar.gz
+Source1:        https://www.openssl.org/source/openssl-%{openssl_version}.tar.gz
+Source3:        build-iso.sh
+Source9:        update-tarball.sh
+
+Patch1:         0001-pick-up-any-display-device-not-only-vga.patch
+Patch2:         0001-MdeModulePkg-TerminalDxe-add-other-text-resolutions.patch
+Patch3:         0001-EXCLUDE_SHELL_FROM_FD.patch
+
+Patch10:        0001-OvmfPkg-silence-EFI_D_VERBOSE-0x00400000-in-NvmExpre.patch
+Patch11:        0002-OvmfPkg-silence-EFI_D_VERBOSE-0x00400000-in-the-DXE-.patch
+Patch12:        0003-OvmfPkg-enable-DEBUG_VERBOSE.patch
+Patch13:        0004-OvmfPkg-increase-max-debug-message-length-to-512.patch
+Patch14:        0005-OvmfPkg-QemuVideoDxe-enable-debug-messages-in-VbeShi.patch
+
+Patch20:        0001-OvmfPkg-EnrollDefaultKeys-application-for-enrolling-.patch
+
+#
+# actual firmware builds are done on x86_64 and aarch64,
+# see all the %ifarch blocks below.
+#
+# edk2-tools builds are done on all x86 and arm.
+# in theory they should build everywhere without much trouble, but
+# in practice the edk2 build system barfs on archs it doesn't know
+# (such as ppc), so lets limit things to the known-good ones.
+#
+ExclusiveArch:  %{ix86} x86_64 %{arm} aarch64
+
+BuildRequires:  python
 BuildRequires:  libuuid-devel
-
-Requires:       edk2-tools%{?_isa} = %{version}-%{release}
-Requires:       edk2-tools-doc%{?_isa} = %{version}-%{release}
+%ifarch x86_64
+BuildRequires:  iasl
+BuildRequires:  nasm
+BuildRequires:  dosfstools
+BuildRequires:  mtools
+BuildRequires:  genisoimage
+%endif
 
 %description
 EDK II is a development code base for creating UEFI drivers, applications
@@ -38,8 +55,6 @@ and firmware images.
 %package tools
 Summary:        EFI Development Kit II Tools
 Group:          Development/Tools
-Requires:       edk2-tools-python = %{version}-%{release}
-
 %description tools
 This package provides tools that are needed to
 build EFI executables and ROMs using the GNU tools.
@@ -58,83 +73,149 @@ you probably want to install edk2-tools only.
 %package tools-doc
 Summary:        Documentation for EFI Development Kit II Tools
 Group:          Development/Tools
-
+BuildArch:      noarch
 %description tools-doc
 This package documents the tools that are needed to
 build EFI executables and ROMs using the GNU tools.
 
+%ifarch x86_64
+%package ovmf
+Summary:        Open Virtual Machine Firmware
+License:        BSD and OpenSSL
+Provides:       OVMF
+BuildArch:      noarch
+%description ovmf
+EFI Development Kit II
+Open Virtual Machine Firmware (x64)
+%endif
+
+%ifarch aarch64
+%package aarch64
+Summary:        AARCH64 Virtual Machine Firmware
+Provides:       AAVMF
+BuildArch:      noarch
+%description aarch64
+EFI Development Kit II
+AARCH64 UEFI Firmware
+%endif
+
 %prep
-%setup -q -n edk2-buildtools-r%{SVNREV}
+%setup -q -n tianocore-%{name}-%{edk2_githash}
 %patch1 -p1
-%patch2 -p2
+%patch2 -p1
+%patch3 -p1
 
+%patch10 -p1
+%patch11 -p1
+%patch12 -p1
+%patch13 -p1
+%patch14 -p1
 
-%build
-export WORKSPACE=`pwd`
+%patch20 -p1
+
+# add openssl
+tar -C CryptoPkg/Library/OpensslLib -xf %{SOURCE1}
+(cd CryptoPkg/Library/OpensslLib/openssl-%{openssl_version};
+ patch -p1 < ../EDKII_openssl-%{openssl_version}.patch)
+(cd CryptoPkg/Library/OpensslLib; ./Install.sh)
+cp CryptoPkg/Library/OpensslLib/openssl-*/LICENSE LICENSE.openssl
 
-# Build is broken if MAKEFLAGS contains -j option.
-unset MAKEFLAGS
-make
+%build
+source ./edksetup.sh
+
+# conpiler
+CC_FLAGS="-t GCC49"
+
+# parallel builds
+JOBS="%{?_smp_mflags}"
+JOBS="${JOBS#-j}"
+if test "$JOBS" != ""; then
+        CC_FLAGS="${CC_FLAGS} -n $JOBS"
+fi
+
+# common features
+CC_FLAGS="${CC_FLAGS} -b DEBUG"
+CC_FLAGS="${CC_FLAGS} --cmd-len=65536"
+
+# ovmf features
+OVMF_FLAGS="${CC_FLAGS}"
+OVMF_FLAGS="${OVMF_FLAGS} -D HTTP_BOOT_ENABLE"
+OVMF_FLAGS="${OVMF_FLAGS} -D NETWORK_IP6_ENABLE"
+
+# ovmf + secure boot features
+OVMF_SB_FLAGS="${OVMF_FLAGS}"
+OVMF_SB_FLAGS="${OVMF_SB_FLAGS} -D SECURE_BOOT_ENABLE"
+OVMF_SB_FLAGS="${OVMF_SB_FLAGS} -D SMM_REQUIRE"
+OVMF_SB_FLAGS="${OVMF_SB_FLAGS} -D EXCLUDE_SHELL_FROM_FD"
+
+# arm firmware features
+ARM_FLAGS="${CC_FLAGS}"
+ARM_FLAGS="${ARM_FLAGS} -D DEBUG_PRINT_ERROR_LEVEL=0x8040004F"
+
+make -C BaseTools #%{?_smp_mflags}
+
+%ifarch x86_64
+# build ovmf
+mkdir -p ovmf
+build ${OVMF_FLAGS} -a X64 -p OvmfPkg/OvmfPkgX64.dsc
+cp Build/OvmfX64/*/FV/OVMF_*.fd ovmf
+rm -rf Build/OvmfX64
+
+# build ovmf with secure boot
+build ${OVMF_SB_FLAGS} -a IA32 -a X64 -p OvmfPkg/OvmfPkgIa32X64.dsc
+cp Build/Ovmf3264/*/FV/OVMF_CODE.fd ovmf/OVMF_CODE.secboot.fd
+
+# build shell iso with EnrollDefaultKeys
+cp Build/Ovmf3264/*/X64/Shell.efi ovmf
+cp Build/Ovmf3264/*/X64/EnrollDefaultKeys.efi ovmf
+sh %{SOURCE3} ovmf
+%endif
+
+%ifarch aarch64
+# build arm/aarch64 firmware
+mkdir -p aarch64
+build $ARM_FLAGS -a AARCH64 -p ArmVirtPkg/ArmVirtQemu.dsc
+cp Build/ArmVirtQemu-AARCH64/DEBUG_*/FV/*.fd aarch64
+dd of="aarch64/QEMU_EFI-pflash.raw" if="/dev/zero" bs=1M count=64
+dd of="aarch64/QEMU_EFI-pflash.raw" if="aarch64/QEMU_EFI.fd" conv=notrunc
+dd of="aarch64/vars-template-pflash.raw" if="/dev/zero" bs=1M count=64
+%endif
 
 %install
-mkdir -p %{buildroot}%{_bindir}
-install \
-        Source/C/bin/BootSectImage \
-        Source/C/bin/EfiLdrImage \
-        Source/C/bin/EfiRom \
-        Source/C/bin/GenCrc32 \
-        Source/C/bin/GenFfs \
-        Source/C/bin/GenFv \
-        Source/C/bin/GenFw \
-        Source/C/bin/GenPage \
-        Source/C/bin/GenSec \
-        Source/C/bin/GenVtf \
-        Source/C/bin/GnuGenBootSector \
-        Source/C/bin/LzmaCompress \
-        BinWrappers/PosixLike/LzmaF86Compress \
-        Source/C/bin/Split \
-        Source/C/bin/TianoCompress \
-        Source/C/bin/VfrCompile \
-        Source/C/bin/VolInfo \
+mkdir -p %{buildroot}%{_bindir} \
+         %{buildroot}%{_datadir}/%{name}/Conf \
+         %{buildroot}%{_datadir}/%{name}/Scripts
+install BaseTools/Source/C/bin/* \
         %{buildroot}%{_bindir}
-
-ln -f %{buildroot}%{_bindir}/GnuGenBootSector \
-        %{buildroot}%{_bindir}/GenBootSector
-
-mkdir -p %{buildroot}%{_datadir}/%{name}
-install \
-        BuildEnv \
+install BaseTools/BinWrappers/PosixLike/LzmaF86Compress \
+        %{buildroot}%{_bindir}
+install BaseTools/BuildEnv \
         %{buildroot}%{_datadir}/%{name}
-
-mkdir -p %{buildroot}%{_datadir}/%{name}/Conf
-install \
-        Conf/build_rule.template \
-        Conf/tools_def.template \
-        Conf/target.template \
+install BaseTools/Conf/*.template \
         %{buildroot}%{_datadir}/%{name}/Conf
-
-mkdir -p %{buildroot}%{_datadir}/%{name}/Scripts
-install \
-        Scripts/GccBase.lds \
+install BaseTools/Scripts/GccBase.lds \
         %{buildroot}%{_datadir}/%{name}/Scripts
 
-cp -R Source/Python %{buildroot}%{_datadir}/%{name}/Python
-
-find %{buildroot}%{_datadir}/%{name}/Python -name "*.pyd" | xargs rm
-
+cp -R BaseTools/Source/Python %{buildroot}%{_datadir}/%{name}/Python
 for i in build BPDG Ecc GenDepex GenFds GenPatchPcdTable PatchPcdValue TargetTool Trim UPT; do
-  echo '#!/bin/sh
-PYTHONPATH=%{_datadir}/%{name}/Python
-export PYTHONPATH
+echo '#!/bin/sh
+export PYTHONPATH=%{_datadir}/%{name}/Python
 exec python '%{_datadir}/%{name}/Python/$i/$i.py' "$@"' > %{buildroot}%{_bindir}/$i
   chmod +x %{buildroot}%{_bindir}/$i
 done
 
+mkdir -p %{buildroot}/usr/share/%{name}
+%ifarch x86_64
+cp -a ovmf %{buildroot}/usr/share/%{name}
+%endif
+%ifarch aarch64
+cp -a aarch64 %{buildroot}/usr/share/%{name}
+%endif
+
 %files tools
 %{_bindir}/BootSectImage
 %{_bindir}/EfiLdrImage
 %{_bindir}/EfiRom
-%{_bindir}/GenBootSector
 %{_bindir}/GenCrc32
 %{_bindir}/GenFfs
 %{_bindir}/GenFv
@@ -149,9 +230,10 @@ done
 %{_bindir}/TianoCompress
 %{_bindir}/VfrCompile
 %{_bindir}/VolInfo
+%dir %{_datadir}/%{name}
 %{_datadir}/%{name}/BuildEnv
-%{_datadir}/%{name}/Conf/
-%{_datadir}/%{name}/Scripts/
+%{_datadir}/%{name}/Conf
+%{_datadir}/%{name}/Scripts
 
 %files tools-python
 %{_bindir}/build
@@ -164,34 +246,38 @@ done
 %{_bindir}/TargetTool
 %{_bindir}/Trim
 %{_bindir}/UPT
-%{_datadir}/%{name}/Python/
+%dir %{_datadir}/%{name}
+%{_datadir}/%{name}/Python
 
 %files tools-doc
-%doc UserManuals/BootSectImage_Utility_Man_Page.rtf
-%doc UserManuals/Build_Utility_Man_Page.rtf
-%doc UserManuals/EfiLdrImage_Utility_Man_Page.rtf
-%doc UserManuals/EfiRom_Utility_Man_Page.rtf
-%doc UserManuals/GenBootSector_Utility_Man_Page.rtf
-%doc UserManuals/GenCrc32_Utility_Man_Page.rtf
-%doc UserManuals/GenDepex_Utility_Man_Page.rtf
-%doc UserManuals/GenFds_Utility_Man_Page.rtf
-%doc UserManuals/GenFfs_Utility_Man_Page.rtf
-%doc UserManuals/GenFv_Utility_Man_Page.rtf
-%doc UserManuals/GenFw_Utility_Man_Page.rtf
-%doc UserManuals/GenPage_Utility_Man_Page.rtf
-%doc UserManuals/GenPatchPcdTable_Utility_Man_Page.rtf
-%doc UserManuals/GenSec_Utility_Man_Page.rtf
-%doc UserManuals/GenVtf_Utility_Man_Page.rtf
-%doc UserManuals/LzmaCompress_Utility_Man_Page.rtf
-%doc UserManuals/PatchPcdValue_Utility_Man_Page.rtf
-%doc UserManuals/SplitFile_Utility_Man_Page.rtf
-%doc UserManuals/TargetTool_Utility_Man_Page.rtf
-%doc UserManuals/TianoCompress_Utility_Man_Page.rtf
-%doc UserManuals/Trim_Utility_Man_Page.rtf
-%doc UserManuals/VfrCompiler_Utility_Man_Page.rtf
-%doc UserManuals/VolInfo_Utility_Man_Page.rtf
+%doc BaseTools/UserManuals/*.rtf
+
+%ifarch x86_64
+%files ovmf
+%license OvmfPkg/License.txt
+%license LICENSE.openssl
+%doc OvmfPkg/README
+%dir /usr/share/%{name}
+%dir /usr/share/%{name}/ovmf
+/usr/share/%{name}/ovmf/OVMF*.fd
+/usr/share/%{name}/ovmf/*.efi
+/usr/share/%{name}/ovmf/*.iso
+%endif
+
+%ifarch aarch64
+%files aarch64
+%license ArmVirtPkg/License.txt
+%dir /usr/share/%{name}
+%dir /usr/share/%{name}/aarch64
+/usr/share/%{name}/aarch64/QEMU*.fd
+/usr/share/%{name}/aarch64/*.raw
+%endif
 
 %changelog
+* Mon Apr 18 2016 Gerd Hoffmann <kraxel@redhat.com> 20160418gita8c39ba-0
+- Update to latest git.
+- Add firmware builds (FatPkg is free now).
+
 * Mon Feb 15 2016 Cole Robinson <crobinso@redhat.com> 20151127svn18975-3
 - Fix FTBFS gcc warning (bz 1307439)
 
diff --git a/sources b/sources
index b04bb1e..f488ba2 100644
--- a/sources
+++ b/sources
@@ -1 +1,2 @@
-b54c3b57cd661dc4e232489919315a6f  edk2-buildtools-r18975.tar.xz
+2ba075ea9168725aede3d43486cb4c62  edk2-20160418-a8c39ba.tar.gz
+f3c710c045cdee5fd114feb69feba7aa  openssl-1.0.2g.tar.gz
diff --git a/update-tarball.sh b/update-tarball.sh
new file mode 100644
index 0000000..b61d758
--- /dev/null
+++ b/update-tarball.sh
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+user="tianocore"
+repo="edk2"
+branch="master"
+
+uri="https://github.com/${user}/${repo}"
+api="${uri/github.com/api.github.com/repos}"
+tar="${uri/github.com/codeload.github.com}/legacy.tar.gz"
+
+hash=$(curl -s "${api}/git/refs/heads/${branch}" | grep '"sha"' | cut -d'"' -f4)
+if test "$hash" = ""; then
+	echo "# failed to fetch $branch hash"
+	exit 1
+fi
+short=$(echo $hash | sed -e 's/^\(.......\).*/\1/')
+
+date=$(curl -s "${api}/git/commits/$hash" | awk '
+	/"committer"/	{ c=1 }
+	/"date"/	{ if (c) { print } }
+' | cut -d'"' -f4)
+date="${date%T*}"
+date="${date//-/}"
+
+name="${repo}-${date}-${short}.tar.gz"
+
+if test -f "$name"; then
+	echo "# exists: $name"
+	exit 1
+fi
+
+echo
+echo "# specfile update: version $date, release $short"
+sed -i.old \
+        -e "s/\(%global edk2_date[ \t]\+\)\(.*\)/\1$date/" \
+        -e "s/\(%global edk2_githash[ \t]\+\)\(.*\)/\1$short/" \
+        edk2.spec
+diff -u edk2.spec.old edk2.spec
+
+echo
+echo "# cleanup ..."
+rm -vf ${repo}-*.tar*
+echo "# fetching $name ..."
+curl "$tar/$hash" > "$name"
+exit 0